我有下面这段代码,如果我输入 "Hi" 按下回车,则会在内存中存储 'H'、'i'、'\n'、'\0'
如果我输入 "Hello" 按下回车,则会在内存中存储 'H'、'e'、'l'、'l'、'\0',然后 'o'、'\n' 会在缓冲区中
最后,如果我输入 "Hell" 按下回车,则会在内存中存储 'H'、'e'、'l'、'l'、'\0',然后 '\n' 会在缓冲区中
char str [5];
fgets(str, 5, stdin);
printf("%s", str);
fgets(buf,n,stream)
读取输入并将其保存到buf
中,直到以下4种情况之一发生。
缓冲区快满了。 一旦读取并保存了n-1个字符,“\0”将被附加到buf
。函数返回buf
。可能还有剩余的字符需要从stream
读取。1
从stream
读取了“\n”。 “\n”被附加到buf
中。“\0”被附加到buf
。函数返回buf
。该行已完全读取。
出现文件结尾。如果之前已经读取了一些字符,则将“\0”附加到buf
中。函数返回buf
。否则返回NULL
。
输入错误(罕见)。返回NULL
。buf
状态不确定。
读取'\n'
与读取其他字符唯一的不同之处在于它通知fgets()
停止读取。
1如果读取一个满的缓冲区而没有'\n'
,则读取和忽略其余的行:
int ch;
while ((ch = fgetc(stream)) != '\n' && c != EOF) {
;
}
'\n'
-这也是一个字符。'\n'
是你问题中的“n-1个字符”之一吗? - chux - Reinstate Monicafgets(buf, 5, stdin)
读取了前4个字符 H,e,l,l 和 \n。\n
仍留在 stdin
中。第二个 fgets(buf, 5, stdin)
读取了 \n
并停止。 - chux - Reinstate Monica'\n'
仍然留在 stdin
中。也许可以这样解释:fgets 函数从指向流的指针 stream 指向的流中最多读取 n-1 个字符到指向数组 s 的指针中。在新行字符(保留)或文件结束后,不会再读取任何其他字符。空字符将立即写入到最后一个读取的字符之后的数组中。C17 § 7.21.7.2 2 - chux - Reinstate Monica给定fgets()
的定义:
char *fgets( char *str, int count, FILE *stream );
(直到 C99)
char *fgets( char *restrict str, int count, FILE *restrict stream );
(自 C99 起)从给定的文件流中最多读取
count - 1
个字符,并将它们存储在由str
指向的字符数组中。如果找到一个newline
字符,则解析停止,此时str
将包含该newline
字符;或者如果发生了end-of-file
,则解析停止。如果读取了字节并且没有发生错误,则在写入到str
的最后一个字符的位置立即写入一个null character
。如果
count
小于 1,则行为未定义。也未指定是否在count==1
时写入null
字符。
fgets
会将输入行中的最大长度(大小)置为5,并将其与 null 终止符一起存储在 str
变量中。
由于您提供的大小是5,如果您输入了 "Hello"
,它将存储为 H e l l \0
,替换掉了 'o'
,'o'
不被存储,而且通常情况下,'o'
和 '\n'
将继续留在 stdin
缓冲区中,尽管这不是标准规定的。
如果您输入了 "Hell"
,则 stdin
缓冲区将有 H e l l \n
,因此当其被存储时,'\n'
将被替换为 '\0'
,而'\n'
将留在缓冲区中。
同样,如果行比 5 - 1
小,则不替换任何内容,char 数组
将被空终止,即 "Hel"
将被存储为 H e l \n \0
,而stdin
缓冲区将被清空。
char array
时要比实际预期的最大大小多一个字符,并且将其大小传递给fgets
函数的原因。fgets(str, sizeof(str), stdin);
从我的机器上的 man fgets
中得知:
char * fgets(char * restrict str, int size, FILE * restrict stream);
fgets() 函数从给定的
stream
中最多读取size
个字符减一,并将它们存储在字符串str
中。当发现换行符、文件末尾或错误时,读取就会停止。如果有任何换行符,则保留该换行符。如果读取了任何字符且没有错误,则会附加一个 `\0' 字符来结束字符串。
这意味着你关于将存储在 str
缓冲区中的内容是正确的。未读取的字符可能可以通过后续从标准输入流读取来读取,但这将取决于操作系统和你正在读取的位置。 C 标准并不强制要求。
fflush
是未定义行为。一些实现将其作为非可移植扩展添加。 - Some programmer dudefflush(stdin)
部分。是谁或什么文本建议使用fflush(stdin)
? - chux - Reinstate Monica