我对C中的fgets和fscanf有疑问。这两者之间究竟有什么区别?例如:
char str[10];
while(fgets(str,10,ptr))
{
counter++;
...
和第二个例子:
char str[10];
while(fscanf(ptr,"%s",str))
{
counter++;
...
当文本文件包含由空格分隔的字符串时,例如:AB1234 AC5423 AS1433。在第一个示例中,while循环中的“counter”将不会提供与第二个示例中相同的输出。当更改fgets函数中的“10”时,计数器将始终给出不同的结果。这是什么原因? 有人可以解释一下fscanf究竟做了什么,每个while循环中的字符串有多长?
答案 0 :(得分:7)
函数fgets
读取直到换行符(并且还存储它)。带有fscanf
说明符的%s
读取直到任何空格并且不存储它...
作为旁注,您没有在scanf中指定缓冲区的大小,而且它不安全。尝试:
fscanf(ptr, "%9s", str)
答案 1 :(得分:3)
fgets
读取换行符。 fscanf
只读取空格。
答案 2 :(得分:2)
在您的示例中,fgets
将从输入流中读取最多9个字符,并将其保存到str
,以及0终止符。它不会跳过前导空格。如果在最大字符数之前看到换行符(将保存到str
)或EOF,它将停止。
fscanf
转换说明符的 %s
将跳过任何前导空格,然后读取所有非空白字符,将它们保存到str
,后跟0终止符。它会在下一个空格字符或EOF处停止读取。如果没有明确的字段宽度,它将读取与流中的非空白字符一样多的非空白字符,可能会超出目标缓冲区。
因此,假设输入流如下所示:"\t abcdef\n<EOF>"
。如果您使用fgets
进行阅读,str
将包含"\t abcdef\n\0"
。如果您使用fscanf
,则str
可能包含"abcdef\0"
(其中\0
表示0终结符)。
答案 3 :(得分:1)
fgets
阅读整行。 fscanf
%s
读取字符串,按空格分隔(或\ n,\ t等等)。
无论如何,你不应该使用它们,除非你确定你读到的数组大到足以包含输入。
您写了When changing the "10" in the fgets function the counter will always give different results.
请注意,fgets和scanf不知道要读取多少字节。你应该告诉他们。更改“10”只是放大这些函数写入的缓冲区。