【问题标题】:fgets inside the while loopfgets 在 while 循环中
【发布时间】:2016-01-14 13:51:08
【问题描述】:

我遇到了fgets 的问题,因为它在k 输入之后第一次进入while 循环时返回\n。 由于我已经在 while 循环中,并且我的 #1 try 已经写入,我该如何处理?

int main() {
    char r;

    printf("How to input?\n");
    printf("Keyboard ([K])\n File ([F])\n Leave ([E])\n");
    scanf("%c", &r);

    if (r == 'k' || r == 'K') {
        printf("\nKeyboard\n");
        opcaoTeclado();
    } else {
       // stuff
    }
}

void opcaoTeclado() {
    int try = 0;
    char inputline[161];

    while (try <= 10) {
        printf("\n#%d try\n ", try);
        fgets(inputline, 160, stdin);
        try++;
    }
}

【问题讨论】:

    标签: c fgets


    【解决方案1】:

    在调用scanf() 之后,输入中有一个换行符,第一次调用fgets() 会读取该换行符。 fgets() 在遇到换行符 \n 时停止读取输入。因此,它不会读取任何输入。

    scanf() 之后添加对getchar(); 的调用以使用换行符。

    如果输入中有多个字符,也可以使用循环来消费。

    int c;
    
    while((c= getchar()) != '\n' && c != EOF); 
    

    一般来说,最好避免将scanf()fgets() 混合使用。您可以使用fgets() 代替scanf() 并使用不太容易出现的sscanf() 解析行。

    【讨论】:

      【解决方案2】:

      你应该清理标准输入的缓冲区。您可以在循环之前使用fflush(stdin); 来执行此操作。但这是一种糟糕的风格。也可以考虑fseek(stdin,0,SEEK_END);

      【讨论】:

      • fflush(stdin); 是标准 C 中的未定义行为。虽然它适用于某些平台,但应避免使用。
      • 两者都是不好的解决方案。 OP 可以将 if (r != '\n') { int c; while ((c = getchar()) != EOF &amp;&amp; c != '\n') continue; } 写入 flush 当前行。
      【解决方案3】:

      您可以简单地在格式后添加空格来使用\n

      scanf("%c ", &r);
      

      【讨论】:

      • 不,这是个坏主意,因为它会一直等待非空格输入。
      • @chqrlie 我同意,但对于 OP 案例来说还可以。
      • 恐怕不是。 'k' 的测试可以继续之前,需要用户进一步的非空格输入。我不认为这是预期的行为。 if (r != '\n') { int c; while ((c = getchar()) != EOF &amp;&amp; c != '\n') continue; } 解决方案要好得多。
      【解决方案4】:
      1. 我遇到了 fgets 的问题,因为它在“k”输入之后第一次进入 while 循环时返回 \n。

        这是因为对于scanf("%c", &amp;r);,当您输入k[ENTER_KEY] 时,字符k 将存储在变量r 中,而\n(按下ENTER 键)则留在stdin 流中。

        所以对于fgets(inputline, 160, stdin);,它会在stdin 中找到\n 换行符,将其放入inputline 并从man -s3 fgets 退出:

        fgets() 从流中最多读入一个小于 size 的字符并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止读取。如果读取了换行符,则将其存储到缓冲区中。


      1. 既然我已经在 while 循环中并且我的“#1 try”已经写好了,我该如何处理呢?

        您可以使用getchar()stdin 中使用该\n

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-06
        • 2021-12-31
        • 1970-01-01
        • 2015-06-19
        相关资源
        最近更新 更多