c语言 - fscanf 是否向后移动文件指针?



这些是我的文件"未排序.txt的内容:

3罗伯特·

贾斯汀·特朗普

这是我的代码:

#include <stdio.h>
int main(void) {
FILE *f = fopen("unsorted.txt", "r");
char n;
printf("%dn", ftell(f));
fscanf(f, "%s", &n);
int l = n - '0';
printf("%d %dn", l, ftell(f));
return 0;
}

在执行时,它给出以下输出:

0
3 -1

为什么在第二种情况下它返回-1?它应该从0转移到1,对吧?

注意:文件可以打开,因为这样它如何在第一次调用中打印 0 和文件中的第一个字符而无法打开?

fscanf(f,"%s",&n);

是非常错误的,因为你声明了char n;(只有一个字节)。你有未定义的行为。非常害怕(下次,感到羞耻)。

我建议:

测试fopen不会失败:

FILE *f = fopen("unsorted.txt","r");
if (!f)  { perror("fopen unsorted.txt"); exit(EXIT_FAILURE); };

声明一个合理大小的缓冲区(80 是 1970 年代穿孔卡的大小)。

char buf[80];

清除它(你想要防御性编程):

memset(buf, 0, sizeof(buf));

然后仔细阅读有关 fscanf 的信息。多次阅读该文档。以固定大小使用它并测试其结果:

if (fscanf(f, "%72s", buf) > 0) {

(72是穿孔卡PL/1程序中的可用大小;小于80)

不要忘记阅读其他函数的文档,包括 ftell。

重要提示:

使用所有警告和调试信息进行编译(使用 GCCgcc -Wall -Wextra -g),改进代码以获得无警告,使用调试器gdb逐步运行它。

附言。作为练习,找到使初始程序正常运行的unsorted.txt的可能内容。在这种情况下,你能预测它的输出吗?如果没有,为什么??

代码中存在多个问题:

  • 您不测试fopen()的返回值。使用NULL指针调用ftell()具有未定义的行为。 您无法从观察到的行为中得出结论。

  • printf("%dn", ftell(f));不正确,因为ftell()的返回值是一个long。 您应该使用格式%ld

  • fscanf(f, "%s", &n);不正确,因为您传递了单个char的地址,以便fscanf()存储以 null 结尾的字符串。fscanf()将访问超出char大小的内存,而具有未定义的行为。定义一个char数组(如char buf[80];),并将要存储的最大字符数传递为:fscanf(f, "%79s", buf);并检查返回值,或使用%c读取单个字节。

  • int l = n - '0';并非严格不正确,但它容易出错:避免将变量命名l因为它看起来与1相似。

  • printf("%d %dn", l, ftell(f));不正确,因为前面对printf的调用:对返回值ftell()使用转换说明符%ld

另请注意,文本流上ftell()的返回值不一定是文件中的字节偏移量。

这是更正后的版本:

#include <stdio.h>
int main(void) {
FILE *f = fopen("unsorted.txt", "r");
char c;
if (f != NULL) {
printf("%ldn", ftell(f));
if (fscanf(f, "%c", &c) == 1) {
int diff = c - '0';
printf("%d %ldn", diff, ftell(f));
}
}
return 0;
}

输出:

0
3 1

相关内容

  • 没有找到相关文章

最新更新