我有以下C程序。
#include <stdio.h>
int main()
{
FILE *fp;
long n;
char c;
fp=fopen("RANDOM","W");
while((c=getchar()) != EOF)
{
putc(c,fp);
}
printf("No. of character entered = %1d\n",ftell(fp));
fclose(fp);
n=0L;
while(feof(fp) == 0)
{
fseek(fp, n, 0);
printf("Position of %c is %1d\n", getc(fp), ftell(fp));
n=n+5L;
}
printf("\n");
fseek(fp,-1L,2);
do
{
putchar(getc(fp));
}
while(!fseek(fp,-2L,1));
fclose(fp);
return 0;
}
此代码未显示任何错误。但是当我在输入 ABCD ... Z 之后运行代码时,它表示段错误,核心转储。问题在哪里?
答案 0 :(得分:3)
确认seg错误来自于feof()
之后调用fclose()
。 fp
在此时关闭,不应作为另一个IO函数的扩充传递。
问题数量
1)不要使用大写"W"
,而应使用小写"w"
。其他未定义的行为(UB)。
2)使用fopen("RANDOM","w")
将文件截断为零长度并写入,但不更新。建议使用fopen("RANDOM","r+")
&#34;打开文本文件进行更新(读写)&#34;或fopen("RANDOM","w+")
打开以进行读写,并且&#34;截断为零长度或创建文本文件以进行更新&#34; @BLUEPIXY
3)char c; ... while((c=getchar()) != EOF)
错误,因为文件结束条件会在某些合法char
上被标记。而是使用int c
。
4)fclose(fp);
之后无需printf("No. of...
。
5)while(feof(fp) == 0)
开始无限循环。如果有的话使用if (feof(fp) == 0)
。虽然出于学习目的,但可以放弃测试
5R)这可以。建议检查fseek(fp, n, 0);
6)printf("Position of %c is %1d\n", getc(fp), ftell(fp));
应该使用"%ld"
而不是"%d"
。
7)请勿使用fseek(fp, n, 0);
和fseek(fp,-1L,2);
,而应使用fseek(fp, -1L, SEEK_SET);
或SEEK_CUR SEEK_END
之类的内容。
8)如果不使用上述标准宏,则不清楚代码的目标是fseek(fp,-1L,2);
9)建议测试fseek(fp,-1L,2);
的结果。
10)printf("Position of %c is %1d\n", getc(fp), ftell(fp));
是一个问题。 (由@BLUEPIXY确定)。调用getc(fp)
和ftell(fp)
的 order 由编译器选择。最好像printf("Position of %c is ", getc(fp)); printf("%ld\n", ftell(fp));
一样明确。
如果代码是在写入之前截断现有文件,则使用"w"
打开是好的。不要删除中间fclose()
,而应考虑freopen(..., "r")
。
答案 1 :(得分:0)
首先,在第一个fp=fopen("RANDOM","R")
之后添加fclose(fp)
。
关闭文件后,您无法从文件中读取文件(只有在文字打开时才能读取文件)。