为什么多个 fgets 需要的不仅仅是 sizeof(type)

Why do multiple fgets require more than sizeof(type)

我希望有人能帮助我解释使用多个 fgets 时的以下行为。

以下代码有效,用户需要为每个 fgets 输入一些内容:

char input[1]; // to store a character
fgets(input,3,stdin); // read a character from the keyboard

char test[5];// for second fgets
fgets(test,3,stdin); // to test if this asks for user input too

printf("The character input is %c",input[0]);

==========OUTPUT============
Enter a character please: 
e
f
The character input is e
=============================

但是下面的代码只会让用户输入第一个 fgets:

char input[1]; 
fgets(input,2,stdin); // THIS IS THE DIFFERENCE, USING 2 INSTEAD OF 3

char test[5];
fgets(test,3,stdin);

printf("The character input is %c",input[0]);
=====OUTPUT=============
Enter a character please: 
e
The character input is e
=========================

区别在于这一行:

fgets(input,2,stdin);

使用小于 3 的地方意味着后面的 fgets 不要求用户输入。 我认为这可能是因为大小为 3 时,当用户在输入字符后按 Enter 时,\n 在大小为 3 或更大时被第一个 fgets 消耗。 但是,如果大小小于 3,则 \n 不会被第一个 fgets 使用,将其留在标准输入上,因此它会被第二个 fgets 使用,这就是为什么第二个 fgets 不等待用户输入就终止的原因。

如果我使用 sizeof(char) 作为那个值,那么我得到输出:

=============OUTPUT============
Enter a character please: 
e
The character input is 
===============================

这很奇怪,因为我看到有人建议对该参数使用 sizeof(type)。

我希望有人能解释为什么需要 3 来消耗 \n,我原以为 2 就足够了,例如char 占用 1 个字节,\n 占用 1 个字节,如果是这种情况,那么推荐的 sizeof(type) 选择是错误的,因为您需要 sizeof(type)+1,但看起来您确实需要sizeof(type) + 2 允许使用 \n 并将其从标准输入中删除。请帮助我理解这一点,谢谢。

您有两个不同的问题:

首先是您写出数组的边界 input,这会导致 未定义的行为

对于第二个问题,当你告诉fgets缓冲区的大小是3时,它将读取字符换行符并添加都添加到您提供的缓冲区并添加字符串空终止符。当您说大小是 2 时,它将读取字符但 而不是 换行符,因为大小包括字符串空终止符。这意味着下一个 fgets 调用将读取换行符并认为它是一个空行。

您通过使用足够大的缓冲区来容纳所有字符以及换行符和字符串空终止符来解决问题。对于单个字符,这意味着您的数组必须包含三个元素:

char input[3];
fgets(input, sizeof input, stdin);

作为可选解决方案,您可以读取单个字符(例如 getchar or getc or fgetc)。

然后您需要循环读取(但不存储)字符,直到您读取换行符。

也许是这样的:

int input = getchar();

// Discard the rest of the line
for (int temp = getchar(); temp != '\n' && temp != EOF; temp = getchar())
{
    // Empty
}
char input[1]; // to store a character
fgets(input,3,stdin);  // read a character from the keyboard

输入变量, 如果用户输入像"new"这样的字符串,会导致segmentation fault, 当值超过 fgets(input,3,stdin) 的字符时 标准输入将忽略它们, 我实际上无法说明与 char 数组具有相同值的 fgets() 背后的设计。