scanf()和fgets()的区别

41

我想知道fgets()scanf()的区别。我使用C语言平台。

6个回答

29

有多个不同之处。其中两个至关重要:

  • fgets() 可以从任何打开的文件中读取,但 scanf() 仅读取标准输入。
  • fgets() 从文件中读取“一行文本”,scanf() 可以用于此目的,同时还可处理从字符串转换为内置数字类型的转换。

许多人会使用 fgets() 读取一行数据,然后使用 sscanf() 进行分析。


8
int scanf(const char * restrict format, ...);

scanf(3) 函数在输入流(stdin)中搜索由您定义的 格式参数 所定义的某些 模式。根据其变体(scanf、fscanf、sscanf、vscanf、vsscanf、vfscanf),scanf(3) 函数接收的输入可以是字符串或文件。

char *fgets(char * restrict str, int size, FILE * restrict stream);

fgets(3)函数从输入文件流中读取一行,将其以空字符结尾的字符串形式复制到缓冲区str中,并将输出限制为给定字节数size


7

Scanf函数不会执行边界检查。fgets函数很可能是更好的选择。然后您可以使用sscanf()函数对其进行评估。

有关此主题的良好讨论请参见此处

如何允许使用scanf输入空格?(那是我的邪恶的孪生被训斥忘记了这一点,不是我)


1
对于数值类型,scanf() 不需要进行边界检查。对于字符串类型,您可以告诉 scanf() 进行边界检查。 - Jonathan Leffler

2
需要翻译的内容:

需要注意的是,scanf 模式规范确实允许字段宽度限制:

scanf( " %80s", mybuffer );

然而,printf()允许使用变量(使用“*”)作为宽度参数:

printf( "My name is %*s.\n", 20, name );

scanf()不会解释星号(*)。(它将星号视为一个标志,用于完全禁止/忽略该字段。)这意味着您最终会做出如下的事情:

#define NAMEWIDTH 40
char buffer[ NAMEWIDTH + 4 ];
...
scanf( " %40x", buffer );

scanf()中没有连接字段宽度40和缓冲区声明中宽度为40的缓冲区的方法。


1

scanf解析您读取(或创建)的字符串,而fgets从打开的FILE*中读取一行。或者您是指fscanf?


1
主要区别在于,scanf 没有限制可以读取的字符数(在默认情况下),而 fgets 有一个最大可读取字符数的限制。
看一下这两个函数的原型:

char * fgets (char * dest, int size, FILE * stream);

int scanf (const char * format, ...);

你可以看到,fgets 的第二个参数规定了最多只能读取 size 个字符。
另一个明显的区别是返回值:fgets 在成功时返回指向 dest 的指针;scanf 返回成功匹配和赋值的输入项数。 然后,scanf 函数根据 format 扫描输入,并从标准输入流 stdin 读取输入,而 fgets 默认从 FILE * stream 读取输入。
总之,使用scanf从文件中读取数据并将它们插入到固定大小的数组中(例如)没有太多意义。 scanf的一个优点是输出数据的格式化:如果函数读取12345\n,则输出为12345,而fgets读取并返回直到\n(包括),在末尾添加\0作为字符串终止符。

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