c - fgets inside while循环用于登录验证

标签 c

我在 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/

相关文章:

c - 指针访问和数组访问之间的值差异

c - 为何存在 Unresolved 包容性?

c - 如何将 2 uint 的结构转换为 double

c - 简单的堆栈,弹出

c - 将 strcat() 与字符串中的字符一起使用?

c - 为什么字符串终止不会发生在空字符处

c++ - 使用函数优化代码-数组中的最大元素

c - 我的数据会在这个 mutex/pthread_cond_wait 结构中丢失在哪里?

php - 从 PHP 打包 C 结构

c++ - 我如何强制cmake在Linux中使用/usr/include中的C++头文件?