用gets函数获得输入时,对输入的数据大小内容没有做出限制,但它实际上只取自身实际储存大小进行保存,而多余的输入被保存在缓冲区中,覆盖后面的存储区。
这是一段检验输入密码的代码
#include<stdio.h>
int main(){
char password[8] = "secret", Get[8];
while(1) {
printf("Enter your password:");
gets(Get);
if(strcmp(password,Get) == 0){
printf("Welcome!");
break;
}
else{printf("Wrong!");}
}
return 0;
}
在这代码中,如果输入数据超过Get[]所能存储的范围,溢出的数据将会覆盖原本password的内容;导致程序不能按原本的运行;
将其换成scanf("%s",Get);也会有一定的风险;保险的方式是使用scanf("%7s",Get);限制其获得数据的长度,就不会将多余的数据保存到缓冲区;
改进:使用fgets()函数
但同时,使用fgets()函数也面临一个问题,字符数组最后以空字符结束,而通过fgets()函数获得的数据'\n'换行符将直接被读入,不会被转换成空字符,也会导致程序不能正常运行。
解决方案:
1.改变原密码,赋值时 password = "secret\n";
2.改变获得的输入,读走换行符,改为空字符:
int i;
for(i = 0; Get[i] != '\n'; i++){
;
}
Get(i) = '\0';
最终代码展示:
#include<stdio.h>
int main(){
int i;
char password[8] = "secret", Get[8];
while(1) {
printf("Enter your password:");
fgets(Get, sizeof(Get), stdin);
for(i = 0; Get[i] != '\n'; i++){
;
}
Get[i] = '\0';
if(strcmp(password,Get) == 0){
printf("Welcome!");
break;
}
else{printf("Wrong!");}
}
return 0;
}