【问题标题】:C - fgets and length of stdinC - fgets 和标准输入的长度
【发布时间】:2012-10-04 14:58:32
【问题描述】:

我用 C 语言编写了一个程序,它允许用户输入密码以允许他进入系统。我正在使用方法 fgets。正确的密码是“letmein”。这是代码:

现在我想验证用户通过stdin输入的密码不超过8个字符。由于程序是(没有空 if 语句),即使用户输入“letmein0000000”,用户也被授予访问权限,因为 fgets 只获取前七个字符。现在我只想在用户输入“letmein”时授予用户访问权限。请问这个怎么做?

附:我必须使用 fgets,因为它是我项目中的要求。

【问题讨论】:

    标签: c string fgets


    【解决方案1】:

    来自fgets() 的文档:

    从给定的文件流中最多读取 count - 1 个字符并将它们存储在 str 中。生成的字符串始终以 NULL 结尾。如果出现文件结尾或找到换行符,解析将停止,在这种情况下 str 将包含该换行符。

    请求读取最多8 个字符(这意味着将9 作为第二个参数传递)。如果用户输入超过7 个字符,则可以被捕获。通知用户失败并跳过stdin 中剩余的任何内容。如果用户正确输入7并点击返回fgets()将在换行符处停止。

    检查fgets() 的返回值以确保代码不会尝试处理未初始化的缓冲区。

    例如:

    char password[9];
    
    if (fgets(password, 9, stdin))
    {
        /* Strip new-line if present. */
        char* nl = strchr(password, '\n');
        if (nl) *nl = 0;
    
        if (strlen(password) > 7)
        {
            /* Password too long. 
               Skip remaining input if necessary. */
            int c;
            while ((c = fgetc(stdin)) != EOF && c != '\n');
        }
        else if (0 == strcmp("letmein", password))
        {
            /* Good password. */
        }
        else
        {
            /* Incorrect password. */
        }
    }
    

    【讨论】:

    • 感谢您的回复。我想说的是,如何确定用户提供的输入不超过 8 个字符(包括空终止符号?)。如果用户输入“letmein1234”,程序仍然会接受它作为一个好的密码,因为 1234 被 fgets 截断。请问这个问题怎么解决?
    • @Matthew,也许我不清楚。我的回答是建议指示fgets() 阅读更多内容而不是7。这意味着如果用户输入"letmein1234",那么fgets() 将读取"letmein1",则输入的其余部分无关紧要。如果用户输入"letmein"fgets() 将在换行处停止。
    • @Matthew:使缓冲区足够大以容纳您可以合理设想的用户键入的最长行(例如 1024 字节),然后阅读它。然后检查读取的长度(减去换行符后)是否过长;然后才检查字符串是否相等。或者,哈希用户输入的内容减去换行符,并将其与保存的哈希值进行比较;如果字符串太长,它不会散列到正确的值,但用户不会对你的代码进行计时攻击。
    • 获取用户输入的所有行直到换行符。
    • @JonathanLeffler,缓冲区只需要 1 个字节太长。 1 字节过多后的任何输入都是无意义的,并且已检测到过长。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    相关资源
    最近更新 更多