【问题标题】:Simple Loops and String Length in CC中的简单循环和字符串长度
【发布时间】:2016-02-01 16:56:52
【问题描述】:

我是 C 的新手。在 Visual Studio 2015 中编写时,我正在尝试使用 fgets 安全地提示用户输入字符串。我想使用 fgets 来获取字符串,检查字符串是否太长,如果是,则重新提示用户,直到他们输入一个好的字符串。这是我的代码

/*
* Nick Gilbert
* COS317 Lab 2 Task 2
*/
#include "stdafx.h"
int main()
{
    char str[10];
    int isValid = 0;
    while (isValid == 0) {
        printf("Please enter a password: ");
        fgets(str, 10, stdin);
        if (strlen(str) == 9 && str[8] != '\n') { //http://stackoverflow.com/questions/21691843/how-to-correctly-input-a-string-in-c
            printf("Error! String is too long\n\n");
            memset(&str[0], 0, sizeof(str));
        }
        else {
            printf(str);
            isValid = 1;
        }
    }
    printf("Press 'Enter' to continue...");
    getchar();
}

但是,当我运行它并输入一个错误的字符串时,多余的字符会自动输入下一个 fget!

我怎样才能解决这个问题来做我想做的事?

【问题讨论】:

  • printf(str); --> printf("%s\n", str);
  • 最佳建议 - 退出 Visual Studio 学习 C!从 Windows 上的 CodeBlocks 之类的东西开始。
  • this answer 可能有用。
  • 检查过长的输入是个好主意。这里的问题是,实际上,fgets 已经在为您执行此操作,并且它对过长输入的作用是,它会将其留在输入流中以供其他人阅读。当您调用 fgets(str, 10, stdin) 时,您是在说“将字符从 stdin 读取到 str,直到您看到换行符或读取 10 个字符,以先到者为准”。
  • 失败的原因是你的 str[8] != \n。您坚持认为第 7 个字符是换行符。

标签: c input while-loop fgets


【解决方案1】:

如果fgets读入的字符串不以换行符结尾,则循环调用fgets直到它结束,然后再次提示用户。

    if (strlen(str) > 0 && str[strlen(str)-1] != '\n') {
        printf("Error! String is too long\n\n");
        do {
            fgets(str, 10, stdin);
        } while (strlen(str) > 0 && str[strlen(str)-1] != '\n') {
    }

此外,切勿将第一个参数的变量传递给printf,尤其是当该变量的内容来自用户输入的数据时。这样做会导致format string vulnerability

【讨论】:

  • 格式字符串漏洞其实是本实验第三部分解决的问题哈哈
【解决方案2】:

试试这个:

#include "stdafx.h"
int main()
{
    char str[10];
    int isValid = 0;
    while (isValid == 0) {
        printf("Please enter a password: ");
        fgets(str, str, stdin);
        if (strlen(str) == 9 && str[8] != '\n') { //http://stackoverflow.com/questions/21691843/how-to-correctly-input-a-string-in-c
            printf("Error! String is too long\n\n");
            memset(str, 0, sizeof(str));
        }
        else {
            printf("%s",str);
            isValid = 1;
        }
    }
    printf("Press 'Enter' to continue...");
    getchar();
}

另外:

使用memset() 时,您可以直接使用array_name 而不是&array_name[0]

【讨论】:

  • 而不是10,9,8 in fgets(str, 10, stdin); if (strlen(str) == 9 && str[8] ...,考虑fgets(str, sizeof str, stdin); if (strlen(str) + 1 == sizeof str && str[sizeof str - 2]。就像在memset(str, 0, sizeof(str)); 中使用的代码一样。
猜你喜欢
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
相关资源
最近更新 更多