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
相关产品推荐
相关产品推荐

