在C中同时读取和写入文件

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”。

同样,我不想使用其他文件来完成此操作,我只需要弄清楚屏幕后面到底出了什么问题

任何线索将不胜感激。谢谢。

chq*_*lie 4

您的代码中存在多个问题:

\n\n

C 标准对以更新模式打开的文件指定了此限制:

\n
\n

7.21.5.3fopen函数

\n

fflush[...] 在没有对函数或文件定位函数(fseekfsetpos或)的中间调用的情况下rewind,输出后面不得直接跟有输入,并且在没有对文件定位函数的中间调用的情况下,输入后面不得直接跟有输出,除非输入操作遇到文件结尾。

\n
\n

这解释了为什么在以相反顺序写入行后仅读取文件位置会导致问题。打电话fflush()应该可以解决这个问题。

\n

这是一个更正的版本:

\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}\n
Run Code Online (Sandbox Code Playgroud)\n