fgets() 不会连续第二次要求输入

时间:2021-05-25 16:44:03

标签: c fgets

我正在编写调用 fgets() 两个不同函数的代码,但我注意到第二个 fgets() 被跳过了。我尝试制作一个测试文件来解决这个问题,但我注意到即使在编写愚蠢的简单代码时,它仍然不会等待我第二次输入。编辑:将 [3] 更改为 [4],但仍然不起作用。

#include <stdio.h>

main()
{
    char I[4];
    
    fgets(I,3,stdin);
    
    printf("%s",I);
    
    fgets(I,3,stdin);
    
    printf("%s",I);
}

3 个答案:

答案 0 :(得分:1)

fgets() 的原型将其定义为 char *fgets(char *str, int n, FILE *stream),其中 n - 1 是要读取的最大字符数,对于如下输入:

A1\n,您有三个字符和 NULL 字节,所以 A1\n\0

通过将 n 设置为 3,您告诉 fgets() 它将最多读取 2 个字符加上 \0 以终止字符串。因此,换行符 (\n) 留在缓冲区中,稍后会被下一次 fgets() 调用使用。

因此将 fgets(I, 3, stdin) 更改为 fgets(I, 4, stdin) 应该可以解决您的问题。您可能还需要考虑检查 fgets() 的返回值,以防它返回 NULL 指针。

答案 1 :(得分:1)

出现问题是因为没有清除键盘缓冲区。基本上在第一个 fgets 中,如果键盘输入达到输入缓冲区大小的限制,其余的将由下一个 fgets 读取。

此示例根据您遇到的问题而工作:

#include <stdio.h>
#include <string.h>

void flushBuffer() {
    int ch;
    while (((ch = getchar()) != EOF) && (ch != '\n'));
}

int main()
{
    char I[3];

    fgets(I, sizeof(I), stdin);
    printf("\n%s",I);

    if ( strchr( I, '\n' ) == NULL )
    {
        flushBuffer();
    }

    fgets(I, sizeof(I), stdin);
    printf("\n%s",I);

    return 0;
}

还有一点是使用sizeof运算符来表示向量的大小。 至于向量的大小,确实很小,如果可能的话,根据你的需要放一个更大的值。

答案 2 :(得分:1)

<块引用>

我认为它需要 just 3

要在 "A1\n" 中完整阅读,fgets() 至少需要 4. 3 个用于1 和 1 个用于附加的空字符形成一个字符串

<块引用>

fgets 函数从 stream 指向的流中读取至多比 n 指定的字符数少 1 到 s 指向的数组中。在换行符(保留)后或文件结束后不会读取其他字符。在读入数组的最后一个字符后立即写入空字符。 C2x 博士 § 7.21.7.2 2

对于输入 "A1\n"fgets(I,3,stdin);fgets() 读取 "A1",将 '"\n" 留给下一个 fgets()。第二个 fgets() 在读取 '\n' 时立即返回。


相反

  • 使用充足的缓冲。无论您认为最大的理智输入是什么,我都推荐 2 倍。

  • 传入 fgets() 缓冲区的大小。

  • 支票退货

  • 为了清晰起见,使用标记打印

.

// char I[4];
// fgets(I,3,stdin);
// printf("%s",I);

char I[100];
if (fgets(I, sizeof I, stdin)) {
  printf("<%s>\n", I);
}

1 在 C 中,“每行由零个或多个字符加上终止的换行符组成。”

相关问题