【问题标题】:Fseek rolls back 8 byte,but I want it to be 4 bytesFseek 回滚 8 个字节,但我希望它是 4 个字节
【发布时间】:2021-09-04 19:06:12
【问题描述】:
for (int i = 0; i < num - 1 - ct; i++) {
    int tmp = k;
    fread(&k, sizeof(int), 1, fp);
    fflush(stdin);
    fseek(fp, -(sizeof(int)), SEEK_CUR);
    fwrite(&tmp, sizeof(int), 1, fp);
}

问题部分在上面。 我希望fseek 每次回滚 4 个字节。但它会回滚 8 个字节,或者可能会回滚到文件的开头。我无法让它正常工作。一个新生。提前致谢。

【问题讨论】:

  • 隐藏stdin 的 fflush 的无意义和未定义行为性质,您是否真的通过检查结果代码验证了 任何 IO 调用?它们不仅仅是为了方便。他们可以帮助您找出潜在问题。
  • 您没有显示k 的定义位置或循环前的初始化方式。您如何确定fseek() 反转了 8 个字节而不是 4 个字节?您是否检查过fp 是否有效?它是如何打开的?你用"rb+"模式了吗?但是,主要问题可能是循环一次迭代结束时的fwrite() 和下一次循环开始时的fread() 之间缺少fseek()。当从阅读切换到写作(你会这样做)以及从写作切换到阅读(你不这样做)时,你必须做一个fseek()。这会导致不确定的行为,UB。
  • 你fflush(stdin) 和读/寻求/写fp。是你想要的吗?
  • 表达式:sizeof( int ) 如果底层硬件是 64 位将返回 8,如果底层硬件是 32 位则返回 4

标签: c file fseek


【解决方案1】:

问题是当从同一个流从写入切换到读取时,您没有使用fseek() 来同步流的内部数据。

试试这个:

fseek(fp, 0, SEEK_CUR);
for (int i = 0; i < num - 1 - ct; i++) {
    int tmp = k;
    fread(&k, sizeof(int), 1, fp);
    //fflush(stdin);  // this has undefined behavior
    fseek(fp, -(sizeof(int)), SEEK_CUR);
    fwrite(&tmp, sizeof(int), 1, fp);
    fseek(fp, 0, SEEK_CUR);
}

【讨论】:

    【解决方案2】:

    尝试在读取之前保存当前位置并使用该位置移动文件指针。一定要以“r+b”模式打开文件。

    fp = fopen("Your file name", "r+b");
    ....
    for (int i = 0; i < num - 1 - ct; i++){
        int tmp = k;
        long pos = ftell(fp);
        fread(&k, sizeof(int), 1, fp);
        fflush(stdin);   // What has stdin to do here while your read/seek/write fp
        fseek(fp, pos - sizeof(int), SEEK_SET);
        fwrite(&tmp, sizeof(int), 1, fp);
    }
    

    并且不要忘记添加检查所用函数的任何的返回值。

    【讨论】:

    猜你喜欢
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 2018-05-22
    相关资源
    最近更新 更多