ps_*_*ps_ 5 c fgetpos fgets file-handling
假定交换文件中的每两行,直到仅剩一行或所有行都用完为止。我不想使用其他文件。
这是我的代码:
#include <stdio.h>
int main() {
FILE *fp = fopen("this.txt", "r+");
int i = 0;
char line1[100], line2[100];
fpos_t pos;
fgetpos(fp, &pos);
//to get the total line count
while (!feof(fp)) {
fgets(line1, 100, fp);
i++;
}
i /= 2; //no. of times to run the loop
rewind(fp);
while (i-- > 0) { //trying to use !feof(fp) condition to break the loop results in an infinite loop
fgets(line1, 100, fp);
fgets(line2, 100, fp);
fsetpos(fp, &pos);
fputs(line2, fp);
fputs(line1, fp);
fgetpos(fp, &pos);
}
fclose(fp);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
this.txt中的内容:
aaa
b
cc
ddd
ee
ffff
gg
hhhh
i
jj
Run Code Online (Sandbox Code Playgroud)
运行程序后的内容
b
aaa
ddd
cc
ddd
c
c
c
i
jj
Run Code Online (Sandbox Code Playgroud)
我什至尝试使用fseek来代替fgetpos以获得相同的错误结果。
根据我的计算,第二个while循环运行两次(即已处理了前四行)之后,光标正确地位于了应该位于的第17个字节(由调用返回ftell(fp)),甚至是文件第四行之后的内容保持不变,并且由于某种原因(当fgets第三次运行循环时调用该内容),读入数组line1和line2的内容分别为“ c \ n”和“ ddd \ n”。
同样,我不想使用其他文件来完成此操作,我只需要弄清楚屏幕后面到底出了什么问题
任何线索将不胜感激。谢谢。
您的代码中存在多个问题:
\n您不检查是否fopen()成功,从而冒着未定义行为的风险。
确定总行数的循环不正确。
了解原因:为什么 \xe2\x80\x9cwhile ( !feof (file) )\xe2\x80\x9d 总是错误?
您实际上不需要计算总行数。
\n在从写回更改为读取之前,您应该调用fflush()将内容写回文件。
C 标准对以更新模式打开的文件指定了此限制:
\n\n\n7.21.5.3
\nfopen函数\n
fflush[...] 在没有对函数或文件定位函数(fseek、fsetpos或)的中间调用的情况下rewind,输出后面不得直接跟有输入,并且在没有对文件定位函数的中间调用的情况下,输入后面不得直接跟有输出,除非输入操作遇到文件结尾。
这解释了为什么在以相反顺序写入行后仅读取文件位置会导致问题。打电话fflush()应该可以解决这个问题。
这是一个更正的版本:
\n#include <stdio.h>\n\nint main(void) {\n FILE *fp;\n char line1[100], line2[100];\n fpos_t pos;\n\n fp = fopen("this.txt", "r+");\n if (fp == NULL) {\n fprintf(stderr, "cannot open this.txt\\n");\n return 1;\n }\n\n while (fgetpos(fp, &pos) == 0 &&\n fgets(line1, sizeof line1, fp) != NULL &&\n fgets(line2, sizeof line2, fp) != NULL) {\n\n fsetpos(fp, &pos);\n fputs(line2, fp);\n fputs(line1, fp);\n fflush(fp); \n }\n\n fclose(fp);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n