如果输入的大小和格式特定,为什么fgets调用会被忽略?

问题描述 投票:2回答:2

我有以下用C语言编写的代码

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int main(void)
{
    char buf1[8];
    char buf2[1024];
    int n;

    fgets(buf1, 6, stdin);
    n = atoi(buf1);

    fgets(buf2, 16, stdin);

    return 0;
}

每当将长度超过3个字符的输入赋给第一个fget时,第二个fget就会存在而无需等待输入。

如果第一个输入= 100,则第二个fget挂起并等待输入。但是,如果输入有4个字符(例如1000),则第二个fget存在并且程序结束。

此行为的解释是什么?

c string
2个回答
1
投票

[输入4个字符后,(至少在Windows中)输入以下6个字符:

1 2 3 4 '\r' '\n'

您的缓冲区只有6个字节,并且尾随的0个字节也必须适合。因此,对fgets()的第一次调用放置了

"1234\r\0"

进入缓冲区,然后第二个调用仍然获得\n,它终止该行并导致第二个fgets()放入

"\n\0"

进入第二个缓冲区并立即返回。因此,计数时必须考虑到行尾(对于Windows,“ \ r \ n”,对于Linux,“ \ n”)和零字节。


1
投票

例如,如果在fgets调用中输入超出指定大小减去1,则>]

char buf1[8];

fgets(buf1, 8, stdin);

输入为

1234567

然后,不会从输入缓冲区中读取与按下的Enter键相对应的换行符'\ n'。

字符数组f1将包含以下内容

{ '1', '2', '3', '4', '5', '6', '7', '\0' }

因此,输入缓冲区保持为非空,并且第二次调用fgets读取输入缓冲区的尾部,而无需等待其他用户输入。

当输入小于指定大小减去1时,新行字符'\ n'被读入字符数组,输入缓冲区将为空。

例如,如果用于此呼叫

fgets(buf1, 8, stdin);

用户输入

123456

然后字符数组将包含

{ '1', '2', '3', '4', '5', '6', '\n', '\0' }
© www.soinside.com 2019 - 2024. All rights reserved.