我在c中有这个登录程序,它为用户提供最多3次登录尝试。 我使用fgets来避免缓冲区溢出,但是当我输入超过16个字符时会发生这种情况:
Enterlogin:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 输入密码:输入登录名:输入密码:输入登录名:输入 密码:无效的登录名和/或密码
而不是仅读取前16'a'。 这是我的代码:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int checkpasswd();
int main() {
int result;
result = checkpasswd();
if (result == 1)
printf("Password correct - Login approved\n");
else
printf("Invalid login and/or password\n");
return 0;
}
int checkpasswd(void) {
char name[16], passwd[16];
int correct = 0, attempts = 0;
while ((attempts != 3)&&(correct == 0)) {
printf("Enter login:");
fgets(name, sizeof(name), stdin);
printf("Enter password:");
fgets(passwd, sizeof(passwd), stdin);
if ((strncmp(name, "admin", strlen(name) - 1) == 0) && (strncmp(passwd, "secret", strlen(passwd) - 1) == 0))
correct = 1;
else
attempts++;
}
if (correct)
return 1;
else return 0;
}
答案 0 :(得分:3)
首先,您应该检查fgets
返回的内容。如果失败,它将返回NULL
。
至于你的问题,fgets
函数不一定会读整行。如果您告诉fgets
最多读取16
个字符(包括终结符),那么fgets
将从输入中读取最多15个字符,然后将其余字符留在缓冲区中。它将不在换行前读取并丢弃不适合缓冲区的内容。
要验证您获得fgets
的整行,请检查字符串中的最后一个字符是换行符。
为了帮助您,您需要执行类似
的操作if (fgets(name, sizeof name, stdin) == NULL)
{
// Error or end-of-file, either way no use in continuing
break;
}
if (strcspn(name, "\n") == strlen(name))
{
// No newline in string, there might be more to read in the input buffer
// Lets read and discard all remaining input in the input buffer until a newline
int c;
while ((c = fgetc(stdin)) != EOF && c != '\n')
{
}
// TODO: Should probably tell the user about this event
// Continue with next attempt
++attempts;
continue;
}
我建议您将其分解为一个单独的函数,您也可以重复使用它来读取密码。