fgets内部如何工作?

5

这是一个基本问题,但我似乎还是很困惑。

这个问题涉及到IT技术。请注意,不要删除HTML标签。
#include<stdio.h>
int main()
{
char a[100];
printf("Enter a string\n");
scanf("%s",a);
}

基本上,我想要实现上述内容。如果我输入一个字符串

James Bond

我希望将其存储在数组a中。问题是,由于单词之间有空格,只有James一词被存储。那么我该如何解决这个问题。

更新:
根据下面给出的回复,我了解到fgets()会是一个更好的选择。我想知道fgets的内部工作原理,为什么它能够存储带有空格的字符串,而scanf无法做到相同的效果。


3
几乎总是使用 fgets 而不是 scanf - Chris Lutz
@Chris Lutz 我想知道 fgets 如何工作,为什么 fgets 能够接受空格但 scanf 不能? - Registered User
5个回答


1

scanf函数会读取到第一个空格字符为止。解决方法是使用fgets函数,如果我没记错的话,在您的情况下应该是:

fgets(a, 100, STDIN);

它将从标准输入中读取最多100个字符(或第一个\n),并将其存储在a中。

永远不要使用gets函数,即使它看起来更容易。


@Lainlwakura 我想知道fgets如何工作,为什么fgets能够接受空格但scanf不能,并且为什么不应该使用gets()? - Registered User
1
我不了解fgets()的内部工作原理,但你不应该使用gets(),因为它只接受一个指向数组的指针。它完全不知道数组的大小,实际上你很容易溢出。一些编译器,如gcc,实际上会警告你不要使用gets()函数。 - LainIwakura

1
通常情况下,scanf 函数会根据空格(空格、制表符、换行等)来分割输入。

例如,通过 scanf("%d%d%d") 可以接受输入 "5 42 -100",因为每个 %d 都会忽略前导空格。在使用 %s 时也会有同样的行为。
唯一不忽略前导空格的转换说明符是 %%%[%c(而对于不同的原因,还有一个是 %n)。
char input[] = " hello world";
char buf[100];
sscanf(input, "%8c", buf); /* buf contains " hello w" */
sscanf(input, "%8[^o]", buf); /* buf contains " hell" */

fgets 函数读取尽可能多的字符,直到下一个换行符。


我使用开放组基础规范第7版进行在线文档查阅。


0
尝试使用fgets()
char a[100];
printf("Enter a string\n");
fgets(a, sizeof(a), STDIN);

关于STDIN的更多信息,请查看此处


我想知道fgets如何工作,即fgets如何能够存储包含空格在内的完整字符串。 - Registered User
@注册用户:请检查链接。 - Donotalo
我读了你的链接,它讲述了标准输入文件描述符为0,但我不明白fgets是如何实现的。 - Registered User
@注册用户,您可以检查scanf()和fgets()函数的编译器实现。 - Donotalo
@注册用户,我从未研究过实现细节,所以对它们一无所知。 :) - Donotalo

0

你应该使用 gets(a)/fgets(a, sizeof(a), stdin) 而不是 sscanf()。


我想了解fgets的内部工作原理,为什么它能够存储带有空格的字符串,而scanf却不能做到相同的效果。 - Registered User
@registered-user 请查看 http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/。%s 用于 sscanf 处理单词(直到找到空格为止)。 - mattn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接