我在 c 中有这个登录程序,它允许用户最多尝试登录 3 次。 我正在使用 fgets 来避免缓冲区溢出,但是当我键入超过 16 个字符时,会发生这种情况:
Enterlogin:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Enter password:Enter login:Enter password:Enter login:Enter password:Invalid login and/or password
而不是只读取前 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;
}
最佳答案
首先你应该检查什么 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;
}
我确实建议您将其分解为一个单独的函数,您也可以重复使用该函数来读取密码。
关于c - fgets inside while循环用于登录验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50816579/