You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言fopen以r+模式打开文件后fwrite写入无结果问题求助

问题原因及解决方案

核心问题分析

  • 读写操作未做同步:以r+更新模式打开的文件,C语言标准明确要求读操作和写操作之间必须调用定位函数(fseek/fsetpos/rewind)或fflush刷新流,否则写入行为是未定义的,这是你文件没有输出内容的最主要原因。
  • 文件指针位置错误:执行fread读取首个字符后,文件指针已经偏移到第二个字节的位置,此时写入内容会从第二个字节开始写,无法覆盖首字符,也不符合你生成字符串后写入的预期逻辑。
  • 空文件兼容问题:如果database.txt是空文件,fread会读取失败,bufr会取栈上的随机值,导致生成的字符串首字符异常。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void scriviDatabase(struct tm giorno,int temp) {
    char bufr;
    char buf[256];
    FILE *lgPos  = fopen("database.txt", "r+");
    if (lgPos == NULL) {   
        printf("Errore! Non ho potuto trovare il database!\n"); 
        exit(-1);
    }
    // 处理空文件情况,读取失败则默认bufr为'0'
    if(fread(&bufr, 1, sizeof(bufr), lgPos) != 1) {
        bufr = '0';
    }
    if (bufr == 10) { // 10为换行符ASCII值
        bufr = '0';
    }
    sprintf(buf,"%c Giorno: %s %d/%d/%d Temp: %dC\n", (char)(bufr+1), "ciao", giorno.tm_mday, giorno.tm_mon, giorno.tm_year, temp);
    printf("scritta prima linea %s", buf);
    // 关键修复:将文件指针移回文件开头,同步读写状态
    rewind(lgPos);
    fwrite(buf, 1, strlen(buf), lgPos);
    // 可选:如果需要截断后续残留的旧内容,可添加以下代码(需包含unistd.h)
    // ftruncate(fileno(lgPos), ftell(lgPos));
    fclose(lgPos);
}

int main(void) {
    struct tm giorno;
    int temp = 32;
    giorno.tm_mday = 12;
    giorno.tm_mon = 10;
    giorno.tm_year = 2021;
    scriviDatabase(giorno, temp);
    return 0;
}

补充说明

  • 标准tm结构体的tm_year成员实际是「当前年份减去1900」的值,如果你后续要使用系统时间函数生成tm结构体,需要注意对年份做减1900的处理,手动赋值的场景不受影响。
  • 如果你不需要保留旧文件中超出新写入内容长度的部分,可以取消代码中ftruncate相关行的注释,记得引入unistd.h头文件。

内容的提问来源于stack exchange,提问作者Narrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:27:03