賬號登錄系統(tǒng)在很多系統(tǒng)設(shè)計時都時必不可少的,今天這個登錄系統(tǒng)功能較全,可以注冊,登錄,找回密碼,修改密碼,以及在輸入密碼時會有*將密碼掩蓋,還有完善地登錄選擇界面,廢話不多,上代碼!
目錄
1.頭文件&結(jié)構(gòu)體&大概函數(shù)實現(xiàn)
2.主函數(shù)&登錄界面
3.注冊系統(tǒng)
4.登錄系統(tǒng)
5.找回密碼(更改密碼)
6.密碼輸入獲取&密碼掩蓋
7.完整代碼?。。。?!
?。。?!首先需要在和.c文件同個目錄下新建一個文件儲存數(shù)據(jù),命名users.dat ?如圖!!
img
?。。。。。。。。。。。。。。。。。。。?/p>
也可以命名別的,后綴dat是我自己隨便取的,喜歡就行!但是記得在代碼中將文件名改過來!
1.頭文件&結(jié)構(gòu)體&大概函數(shù)實現(xiàn)
?
//引頭文件 #include?#include? #include? #include? //用于反應(yīng)意外情況的,下面會講到 #include? //定義宏常量 #define?MAX_ID?11//ID的最大長度 #define?MAX_PWD?20//密碼的最大長度 #define?MAX_NAME?15//名字的最大長度 #define?MAX_SEX?5//性別的最大長度 #define?MAX_PHONE?12//電話的最大長度 //創(chuàng)建用戶的結(jié)構(gòu)體 typedef?struct?Users { ?char?id[MAX_ID];//id?即登錄的賬號 ?char?pwd[MAX_PWD];//密碼 ?char?name[MAX_NAME];//姓名 ?char?sex[MAX_SEX];//性別 ?char?phone[MAX_PHONE];//電話 }Users; //聲明函數(shù) //打印菜單 void?menu(); //用戶注冊 void?Register(); //登錄 void?Login(); //找回密碼 void?Reback(); ? //定位光標(biāo) void?gotoxy(); //獲取x的位置 int?posx(); //獲取y的位置 int?posy(); //密碼輸入(含掩蓋功能) void?Getpwd(char*?pwd);
?
這里定義了很多宏常量,可以看情況修改合適的數(shù)值,比較快捷方便,不用到代碼里一個個改
2.主函數(shù)&登錄界面
?
void?menu()
{
?printf("************************************
");
?printf("************************************
");
?printf("*****1.Register?????????2.Login*****
");
?printf("*****3.Reback???????????0.exit?*****
");
?printf("************************************
");
?printf("************************************
");
}
int?main()
{
?char?input;
?do
?{
??menu();
??setbuf(stdin,?NULL);//清空輸入緩沖區(qū),避免下面getchar讀到上一次輸入緩沖區(qū)剩下的東西
??input?=?getchar();
??switch?(input)
??{
??case?'1':
???Register();
???break;
??case?'2':
???Login();
???break;
??case?'3':
???Reback();
???break;
??case?'0':
???printf("退出成功!
");
???break;
??default:
???printf("選擇錯誤,請重新選擇!
");
???break;
??}
?}?while?(input!='0');//如果輸入了0,就exit退出咯
}
?
這里用到字符去當(dāng)作switch的判斷依據(jù),是因為如果用整形去做判斷依據(jù)的話,若向input中輸入的東西不是整形而是字符或者字符串,switch在循環(huán)中就會陷入死循環(huán),具體情況大家去試試就知道,這里不多講解,用單個字符判斷到現(xiàn)在是沒試出什么bug。
3.注冊系統(tǒng)
?
void?Register() { ?Users?a,?b;//創(chuàng)建用戶結(jié)構(gòu)體臨時變量,a是用來接收用戶輸入的,b是用來從文件中讀取的,來和a作比較 ?char?tmp[20]="";//用著下面判斷的 ?? ?printf("歡迎來到注冊界面! "); ?FILE*?pf?=?fopen("users.dat",?"rb");//"rb"是以二進制只讀方式打開文件的意思 ?fread(&b,?sizeof(Users),?1,?pf);//將數(shù)據(jù)讀入b中 ?if?(!pf)//如果打開失敗 ?{ ??printf("%s",?strerror(errno));//errno可以理解是報的錯誤對應(yīng)的編號,strerror可以把這個編號翻譯出來,輸出在屏幕上 ??return; ?} ?Sleep(800); ?? ?printf("請輸入您的賬號>>"); ?scanf("%s",?a.id); ?while?(1) ?{ ??if?(strcmp(a.id,?b.id))//兩個用戶名不相等 ??{ ???if?(!feof(pf))//沒讀到文件末尾 ???{ ????fread(&b,?sizeof(Users),?1,?pf);//繼續(xù)讀取文件中的用戶到b中 ???} ???else//讀到文件末尾了,確認(rèn)沒有重復(fù)的id ???{ ????break; ???} ??} ??else//有兩個用戶名相等 ??{ ???printf("此用戶名已存在在,請重新輸入! "); ???Sleep(1000); ???fclose(pf);//關(guān)閉文件 ???pf?=?NULL;//pf置空,避免野指針 ???return; ??} ?} ?printf("請輸入您的姓名>>"); ?scanf("%s",?a.name); ?printf("請輸入您的性別>>"); ?scanf("%s",?a.sex); ?printf("請輸入您的電話號碼>>"); ?scanf("%s",?a.phone); ?printf("請輸入您的密碼>>"); ?Getpwd(a.pwd);//輸入密碼的函數(shù),有掩蓋功能,下面會介紹 ?printf(" 請再次確認(rèn)您的密碼>>"); ?Getpwd(tmp); ?do ?{ ??if?(!strcmp(a.pwd,?tmp))//兩次密碼相等 ??{ ???pf?=?fopen("users.dat",?"ab"); ???fwrite(&a,?sizeof(Users),?1,?pf); ???printf(" 賬號注冊成功,請登錄! "); ???Sleep(500); ???fclose(pf); ???pf?=?NULL; ???return; ??} ??else ??{ ???printf(" 兩次密碼不匹配!請重新輸入>>"); ???Getpwd(a.pwd); ???printf(" 請再次確認(rèn)>>"); ???Getpwd(tmp); ??} ?}?while?(1); }
?
文件都是以二進制打開以二進制寫入的,沒別的原因,就是覺得帥!
關(guān)注公眾號:C語言中文社區(qū),免費領(lǐng)取300G編程資料
4.登錄系統(tǒng)
?
void?Login()
{
?Users?a,?b;//同理,a是用來給用戶輸入的,b是用來是水的(從文件中讀取到b中,用b和a匹配比較)
?FILE*?pf?=?fopen("users.dat",?"rb");//以只讀的方式打開文件
?if?(!pf)//如果讀取失敗
?{
??printf("%s
",?strerror(errno));//上面有講過~
??return;
?}
?printf("歡迎來到登錄界面!
");
?Sleep(1000);
??
?fread(&b,?sizeof(Users),?1,?pf);//先從文件中讀取一個用戶試試水
??
?printf("請輸入賬號>>");
?scanf("%s",?a.id);
??
?while?(1)
?{
??if?(!strcmp(a.id,?b.id))//在文件中找到了與用戶輸入相同的id
??{
???break;
??}
??else
??{
???if?(!feof(pf))//沒讀到文件末尾,繼續(xù)讀取文件中的id到b中
???{
????fread(&b,?sizeof(Users),?1,?pf);//繼續(xù)從文件中讀取用戶信息進b,直到在文件中找到一個和a的信息相同的
???}
???else//讀到文件末尾了,沒有找到與用戶輸入相同的賬號
???{
????printf("此賬號不存在!請重新輸入!
");
????Sleep(500);
????fclose(pf);
????pf?=?NULL;
????return;
???}
??}
?}
?do
?{
??printf("請輸入密碼>>");
??Getpwd(a.pwd);//獲取密碼,在下面會講
??if?(!strcmp(a.pwd,?b.pwd))//輸入的密碼與文件中的相同
??{
???printf("
登錄成功!歡迎使用!
");
???Sleep(500);
???fclose(pf);//用完當(dāng)然要把文件關(guān)啦
???pf?=?NULL;//置空,避免野指針
???return;
??}
??else
??{
???printf("
密碼輸入錯誤,請重新輸入
");
??}
?}?while?(strcmp(a.pwd,?b.pwd));
}
?
大概思路就是用戶先輸入賬號(id),接著b從文件中讀取用戶,直到找到與用戶輸入id相同的,然后就是輸入密碼判斷密碼對不對咯。? 里面用到了一個庫函數(shù)strcmp,判斷字符串是不是一樣的,如果一樣則返回0,不一樣則返回一個非0值。
5.找回密碼(更改密碼)
?
void?Reback()
{
?char?tmp[20]?=?"";//密碼匹配用的
?Users?a,?b;
?FILE*?pf?=?fopen("users.dat",?"rb+");//"rb+"是為了讀和寫以二進制打開文件的意思
??
?if?(!pf)//老樣子,先判斷能不能順利打開
?{
??printf("%s",?strerror(errno));
??return;
?}
??
?fread(&b,?sizeof(Users),?1,?pf);//照樣,讀一個試試水
??
?printf("請輸入您的賬號>>");
?Sleep(800);
??
?scanf("%s",?a.id);
??
?while?(1)//在文件中找到與用戶輸入相同的id
?{
??if?(!strcmp(a.id,?b.id))//如果讀取到了相同的id(在文件中找到了和用戶輸入一樣的)
??{
???break;
??}
??else
??{
???if?(!feof(pf))//沒讀到文件尾,繼續(xù)讀
???{
????fread(&b,?sizeof(Users),?1,?pf);
???}
???else
???{
????printf("您輸入的賬號不存在!請重新輸入!
");
????Sleep(500);
????fclose(pf);
????pf?=?NULL;
????break;
???}
??}
?}
??
?//下面是信息匹配驗證
?do//匹配姓名
?{
??printf("請輸入您的姓名>>");
??scanf("%s",?a.name);
??if?(!strcmp(a.name,?b.name))
??{
???break;
??}
??else
??{
???printf("輸入錯誤,請重新輸入!
");
??}
?}?while?(strcmp(a.name,?b.name));
??
?do//匹配性別
?{
??printf("請輸入您的性別>>");
??scanf("%s",?a.sex);
??if?(!strcmp(a.sex,?b.sex))
??{
???break;
??}
??else
??{
???printf("輸入錯誤,請重新輸入!
");
??}
?}?while?(strcmp(a.sex,?b.sex));
?do//匹配電話號碼
?{
??printf("請輸入您的電話號碼>>");
??scanf("%s",?a.phone);
??if?(!strcmp(a.phone,?b.phone))
??{
???break;
??}
??else
??{
???printf("輸入錯誤,請重新輸入!
");
??}
?}?while?(strcmp(a.phone,?b.phone));
??
?//更改密碼
?printf("驗證成功!請修改您的密碼!
");
?printf("請輸入您的密碼>>");
?Getpwd(a.id);
?printf("請再次確認(rèn)您的密碼>>");
?Getpwd(tmp);
?if?(!pf)
?{
??printf("%s",?strerror(errno));
??return;
?}
?//將原來的密碼覆蓋掉
?do
?{
??if?(!strcmp(a.pwd,?tmp))//兩次密碼相等
??{
???fseek(pf,-((int)(sizeof(Users)-MAX_ID)),?SEEK_CUR);//將文件流調(diào)回到要修改的密碼的位置
???fprintf(pf,?"%s",?a.pwd);//覆蓋原來的密碼
???printf("密碼修改成功,請登錄!
");
???Sleep(500);
???fclose(pf);
???pf?=?NULL;
???return;
??}
??else
??{
???printf("兩次密碼不匹配!請重新輸入>>");
???scanf("%s",?a.pwd);
???printf("請再次確認(rèn)>>");
???scanf("%s",?tmp);
??}
?}?while?(1);
}
?
大概思路是輸入賬號->匹配信息->修改密碼,修改密碼時要將文件流調(diào)回要修改的密碼的前面,這里用到了fseek,-((int)(sizeof(Users)-MAX_ID))是要調(diào)回的范圍。
6.密碼輸入獲取&密碼掩蓋
?
void?gotoxy(int?x,?int?y)
{
?//更新光標(biāo)位置
?COORD?pos;
?HANDLE?hOutput?=?GetStdHandle(STD_OUTPUT_HANDLE);//GetStdHandle是一個Windows API函數(shù)。
?pos.X?=?x;
?pos.Y?=?y;
?SetConsoleCursorPosition(hOutput,?pos);
}
int?posx()
{
?CONSOLE_SCREEN_BUFFER_INFO?ptr;
?GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),?&ptr);
?return?(ptr.dwCursorPosition.X);
}
int?posy()
{
?CONSOLE_SCREEN_BUFFER_INFO?ptr;
?GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),?&ptr);
?return?(ptr.dwCursorPosition.Y);
}
void?Getpwd(char*?pwd)
{
?int?i?=?0;
?int?x,?y;
?while?(1)
?{
??pwd[i]?=?getch();//獲取單個密碼(字符)
??if?(pwd[i]?==?VK_BACK?&&?i?>=?0)//如果輸入的是回退鍵,VK_BACK是鍵盤的鍵值,ASCII碼值為8
??{
???if?(i?>?0)//i>0說明有輸入東西了,則回退前一格
???{
????i--;
????x?=?posx()?-?1;//定位x并回退一格
????y?=?posy();//定位y
????gotoxy(x,?y);//定位光標(biāo)
????printf("?");//將*用空格掩蓋
????x?=?posx()?-?1;//再次回退,下次輸入時光標(biāo)才會顯示在正確的位置
????y?=?posy();//定位y
????gotoxy(x,?y);
????continue;//然后跳過此次循環(huán)
???}
???else?if?(i?==?0)//i==0說明沒輸入東西,直接跳過此次循環(huán)即可
???{
????continue;
???}
??}
??if?(i?>=?0?&&?pwd[i]?!=?VK_RETURN?&&?pwd[i]?!=?VK_BACK)//輸入東西了
??{
???x?=?posx();
???y?=?posy();
???gotoxy(x,?y);
???printf("*");
??}
??if?(i?==?0?&&?pwd[i]?==?VK_RETURN)//如果沒輸入東西直接按回車,直接跳過此次循環(huán),避免程序把回車當(dāng)密碼了
??{
???continue;
??}
??if?(pwd[i]?==?VK_RETURN||i==MAX_PWD-2)//輸入回車了或者到上限了
??{
???i++;
???pwd[i]?=?'';//結(jié)尾放''
???break;
??}
??i++;
?}
}
?
那幾個長長的都是windows控制臺的API函數(shù),這里不多講解
7.完整代碼?。。。?!
?
//引頭文件 #include?#include? #include? #include? #include? //定義宏常量 #define?MAX_ID?11 #define?MAX_PWD?20 #define?MAX_NAME?15 #define?MAX_SEX?5 #define?MAX_PHONE?12 //創(chuàng)建用戶的結(jié)構(gòu)體 typedef?struct?Users { ?char?id[MAX_ID]; ?char?pwd[MAX_PWD]; ?char?name[MAX_NAME]; ?char?sex[MAX_SEX]; ?char?phone[MAX_PHONE]; }Users; ? //聲明函數(shù) //打印菜單 void?menu(); //用戶注冊 void?Register(); //登錄 void?Login(); //找回密碼 void?Reback(); //定位光標(biāo) void?gotoxy(); //獲取x的位置 int?posx(); //獲取y的位置 int?posy(); //密碼輸入(含掩蓋功能) void?Getpwd(char*?pwd); int?main()//主函數(shù) 關(guān)注公眾號:C語言中文社區(qū),免費領(lǐng)取300G編程資料 { ?char?input; ?do ?{ ??menu(); ??setbuf(stdin,?NULL); ??input?=?getchar(); ??switch?(input) ??{ ??case?'1': ???Register(); ???break; ??case?'2': ???Login(); ???break; ??case?'3': ???Reback(); ???break; ??case?'0': ???printf("退出成功! "); ???break; ??default: ???printf("選擇錯誤,請重新選擇! "); ???break; ??} ?}?while?(input!='0'); } //打印菜單 void?menu() { ?printf("************************************ "); ?printf("************************************ "); ?printf("*****1.Register?????????2.Login***** "); ?printf("*****3.Reback???????????0.exit?***** "); ?printf("************************************ "); ?printf("************************************ "); } //注冊系統(tǒng) void?Register() { ?Users?a,?b;//創(chuàng)建用戶結(jié)構(gòu)體臨時變量,a是用來接收用戶輸入的,b是用來從文件中讀取的,來和a作比較 ?char?tmp[20]="";//用著下面判斷的 ?? ?printf("歡迎來到注冊界面! "); ?FILE*?pf?=?fopen("users.dat",?"rb");//"rb"是以二進制只讀方式打開文件的意思 ?fread(&b,?sizeof(Users),?1,?pf);//將數(shù)據(jù)讀入b中 ?if?(!pf)//如果打開失敗 ?{ ??printf("%s",?strerror(errno));//errno可以理解是報的錯誤對應(yīng)的編號,strerror可以把這個編號翻譯出來,輸出在屏幕上 ??return; ?} ?Sleep(800); ?? ?printf("請輸入您的賬號>>"); ?scanf("%s",?a.id); ?while?(1) ?{ ??if?(strcmp(a.id,?b.id))//兩個用戶名不相等 ??{ ???if?(!feof(pf))//沒讀到文件末尾 ???{ ????fread(&b,?sizeof(Users),?1,?pf);//繼續(xù)讀取文件中的用戶到b中 ???} ???else//讀到文件末尾了,確認(rèn)沒有重復(fù)的id ???{ ????break; ???} ??} ??else//有兩個用戶名相等 ??{ ???printf("此用戶名已存在在,請重新輸入! "); ???Sleep(1000); ???fclose(pf);//關(guān)閉文件 ???pf?=?NULL;//pf置空,避免野指針 ???return; ??} ?} ?printf("請輸入您的姓名>>"); ?scanf("%s",?a.name); ?printf("請輸入您的性別>>"); ?scanf("%s",?a.sex); ?printf("請輸入您的電話號碼>>"); ?scanf("%s",?a.phone); ?printf("請輸入您的密碼>>"); ?Getpwd(a.pwd);//輸入密碼的函數(shù),有掩蓋功能,下面會介紹 ?printf(" 請再次確認(rèn)您的密碼>>"); ?Getpwd(tmp); ?do ?{ ??if?(!strcmp(a.pwd,?tmp))//兩次密碼相等 ??{ ???pf?=?fopen("users.dat",?"ab"); ???fwrite(&a,?sizeof(Users),?1,?pf); ???printf(" 賬號注冊成功,請登錄! "); ???Sleep(500); ???fclose(pf); ???pf?=?NULL; ???return; ??} ??else ??{ ???printf(" 兩次密碼不匹配!請重新輸入>>"); ???Getpwd(a.pwd); ???printf(" 請再次確認(rèn)>>"); ???Getpwd(tmp); ??} ?}?while?(1); } //登錄系統(tǒng) void?Login() { ?Users?a,?b;//同理,a是用來給用戶輸入的,b是用來是水的(從文件中讀取到b中,用b和a匹配比較) ?FILE*?pf?=?fopen("users.dat",?"rb");//以只讀的方式打開文件 ?if?(!pf)//如果讀取失敗 ?{ ??printf("%s ",?strerror(errno));//上面有講過~ ??return; ?} ?printf("歡迎來到登錄界面! "); ?Sleep(1000); ?? ?fread(&b,?sizeof(Users),?1,?pf);//先從文件中讀取一個用戶試試水 ?? ?printf("請輸入賬號>>"); ?scanf("%s",?a.id); ?? ?while?(1) ?{ ??if?(!strcmp(a.id,?b.id))//在文件中找到了與用戶輸入相同的id ??{ ???break; ??} ??else ??{ ???if?(!feof(pf))//沒讀到文件末尾,繼續(xù)讀取文件中的id到b中 ???{ ????fread(&b,?sizeof(Users),?1,?pf);//繼續(xù)從文件中讀取用戶信息進b,直到在文件中找到一個和a的信息相同的 ???} ???else//讀到文件末尾了,沒有找到與用戶輸入相同的賬號 ???{ ????printf("此賬號不存在!請重新輸入! "); ????Sleep(500); ????fclose(pf); ????pf?=?NULL; ????return; ???} ??} ?} ?do ?{ ??printf("請輸入密碼>>"); ??Getpwd(a.pwd);//獲取密碼,在下面會講 ??if?(!strcmp(a.pwd,?b.pwd))//輸入的密碼與文件中的相同 ??{ ???printf(" 登錄成功!歡迎使用! "); ???Sleep(500); ???fclose(pf);//用完當(dāng)然要把文件關(guān)啦 ???pf?=?NULL;//置空,避免野指針 ???return; ??} ??else ??{ ???printf(" 密碼輸入錯誤,請重新輸入 "); ??} ?}?while?(strcmp(a.pwd,?b.pwd)); } //找回密碼 void?Reback() { ?char?tmp[20]?=?"";//密碼匹配用的 ?Users?a,?b; ?FILE*?pf?=?fopen("users.dat",?"rb+");//"rb+"是為了讀和寫以二進制打開文件的意思 ?? ?if?(!pf)//老樣子,先判斷能不能順利打開 ?{ ??printf("%s",?strerror(errno)); ??return; ?} ?? ?fread(&b,?sizeof(Users),?1,?pf);//照樣,讀一個試試水 ?? ?printf("請輸入您的賬號>>"); ?Sleep(800); ?? ?scanf("%s",?a.id); ?? ?while?(1)//在文件中找到與用戶輸入相同的id ?{ ??if?(!strcmp(a.id,?b.id))//如果讀取到了相同的id(在文件中找到了和用戶輸入一樣的) ??{ ???break; ??} ??else ??{ ???if?(!feof(pf))//沒讀到文件尾,繼續(xù)讀 ???{ ????fread(&b,?sizeof(Users),?1,?pf); ???} ???else ???{ ????printf("您輸入的賬號不存在!請重新輸入! "); ????Sleep(500); ????fclose(pf); ????pf?=?NULL; ????break; ???} ??} ?} ?? ?//下面是信息匹配驗證 ?do//匹配姓名 ?{ ??printf("請輸入您的姓名>>"); ??scanf("%s",?a.name); ??if?(!strcmp(a.name,?b.name)) ??{ ???break; ??} ??else ??{ ???printf("輸入錯誤,請重新輸入! "); ??} ?}?while?(strcmp(a.name,?b.name)); ?? ?do//匹配性別 ?{ ??printf("請輸入您的性別>>"); ??scanf("%s",?a.sex); ??if?(!strcmp(a.sex,?b.sex)) ??{ ???break; ??} ??else ??{ ???printf("輸入錯誤,請重新輸入! "); ??} ?}?while?(strcmp(a.sex,?b.sex)); ?do//匹配電話號碼 ?{ ??printf("請輸入您的電話號碼>>"); ??scanf("%s",?a.phone); ??if?(!strcmp(a.phone,?b.phone)) ??{ ???break; ??} ??else ??{ ???printf("輸入錯誤,請重新輸入! "); ??} ?}?while?(strcmp(a.phone,?b.phone)); ?? ?//更改密碼 ?printf("驗證成功!請修改您的密碼! "); ?printf("請輸入您的密碼>>"); ?Getpwd(a.id); ?printf("請再次確認(rèn)您的密碼>>"); ?Getpwd(tmp); ?if?(!pf) ?{ ??printf("%s",?strerror(errno)); ??return; ?} ?//將原來的密碼覆蓋掉 ?do ?{ ??if?(!strcmp(a.pwd,?tmp))//兩次密碼相等 ??{ ???fseek(pf,-((int)(sizeof(Users)-MAX_ID)),?SEEK_CUR);//將文件流調(diào)回到要修改的密碼的位置 ???fprintf(pf,?"%s",?a.pwd);//覆蓋原來的密碼 ???printf("密碼修改成功,請登錄! "); ???Sleep(500); ???fclose(pf); ???pf?=?NULL; ???return; ??} ??else ??{ ???printf("兩次密碼不匹配!請重新輸入>>"); ???scanf("%s",?a.pwd); ???printf("請再次確認(rèn)>>"); ???scanf("%s",?tmp); ??} ?}?while?(1); } //定位光標(biāo) void?gotoxy(int?x,?int?y) { ?//更新光標(biāo)位置 ?COORD?pos; ?HANDLE?hOutput?=?GetStdHandle(STD_OUTPUT_HANDLE);//GetStdHandle是一個Windows API函數(shù)。 ?pos.X?=?x; ?pos.Y?=?y; ?SetConsoleCursorPosition(hOutput,?pos); } //獲取光標(biāo)x坐標(biāo) int?posx() { ?CONSOLE_SCREEN_BUFFER_INFO?ptr; ?GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),?&ptr); ?return?(ptr.dwCursorPosition.X); } //獲取光標(biāo)y坐標(biāo) int?posy() { ?CONSOLE_SCREEN_BUFFER_INFO?ptr; ?GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),?&ptr); ?return?(ptr.dwCursorPosition.Y); } //輸入密碼 void?Getpwd(char*?pwd) { ?int?i?=?0; ?int?x,?y; ?while?(1) ?{ ??pwd[i]?=?getch();//獲取單個密碼(字符) ??if?(pwd[i]?==?VK_BACK?&&?i?>=?0)//如果輸入的是回退鍵,VK_BACK是鍵盤的鍵值,ASCII碼值為8 ??{ ???if?(i?>?0)//i>0說明有輸入東西了,則回退前一格 ???{ ????i--; ????x?=?posx()?-?1;//定位x并回退一格 ????y?=?posy();//定位y ????gotoxy(x,?y);//定位光標(biāo) ????printf("?");//將*用空格掩蓋 ????x?=?posx()?-?1;//再次回退,下次輸入時光標(biāo)才會顯示在正確的位置 ????y?=?posy();//定位y ????gotoxy(x,?y); ????continue;//然后跳過此次循環(huán) ???} ???else?if?(i?==?0)//i==0說明沒輸入東西,直接跳過此次循環(huán)即可 ???{ ????continue; ???} ??} ??if?(i?>=?0?&&?pwd[i]?!=?VK_RETURN?&&?pwd[i]?!=?VK_BACK)//輸入東西了 ??{ ???x?=?posx(); ???y?=?posy(); ???gotoxy(x,?y); ???printf("*"); ??} ??if?(i?==?0?&&?pwd[i]?==?VK_RETURN)//如果沒輸入東西直接按回車,直接跳過此次循環(huán),避免程序把回車當(dāng)密碼了 ??{ ???continue; ??} ??if?(pwd[i]?==?VK_RETURN||i==MAX_PWD-2)//輸入回車了或者到上限了 ??{ ???i++; ???pwd[i]?=?'';//結(jié)尾放'' ???break; ??} ??i++; ?} }
?
審核編輯:湯梓紅
電子發(fā)燒友App





評論