r+模式下文件写入出现多余空格及内容覆盖异常问题求助
问题分析与解决方案
先帮你定位问题根源,你的代码出现多余空格和写入异常的情况,主要是以下几个原因导致的:
1. 更新模式下读写切换的未定义行为
你用r+模式打开文件(支持读写的更新模式),在执行第二个fputs(data, fp1)后直接调用getc读取内容——根据C标准,在更新模式下从写操作切换到读操作时,必须先调用定位函数(比如fseek、rewind)或者fflush,否则会触发未定义行为,导致文件指针位置混乱,读取到垃圾数据(也就是你看到的大量空格)。
2. gets函数的安全性隐患
gets是已被废弃的不安全函数,它不会检查缓冲区长度,还会丢弃输入的换行符;更关键的是,你定义的char data[50]是局部变量,未初始化时会包含随机值。虽然gets会在输入字符串末尾加'\0',但如果输入过程出现异常,可能导致缓冲区溢出,进而写入多余的垃圾字符。
3. 文本模式的换行符转换干扰(Windows平台)
在Windows系统中,默认文本模式会自动把文件中的\n转换为\r\n存储,读取时再反向转换。这会导致fseek计算的指针位置与文件实际字节数不匹配,多次移动指针并写入时,可能产生额外空白字符,甚至导致写入位置错误。
修正后的代码示例
我针对性修改了你的代码,解决了上述问题:
#include <stdio.h> #include <string.h> int main() { FILE *fp1; char ch; char data[50]; // 用二进制更新模式打开,避免文本模式的换行转换干扰 fp1 = fopen("file1.txt", "rb+"); if(fp1 == NULL) { printf("Error in Opening the file\n"); return 0; } printf("Read and Write Mode. The data in the file is\n"); while((ch = getc(fp1)) != EOF) { putc(ch, stdout); } // 用fgets替代不安全的gets,并处理输入中的换行符 printf("\nEnter some data to be written to the file\n"); fgets(data, sizeof(data), stdin); // 去掉fgets读取到的换行符 data[strcspn(data, "\n")] = '\0'; // 追加数据到文件末尾 fseek(fp1, 0, SEEK_END); fputs(data, fp1); // 回到文件开头覆盖写入 fseek(fp1, 0, SEEK_SET); fputs(data, fp1); // 读写切换前调用rewind定位到开头,符合C标准要求 rewind(fp1); printf("\ndata in file after write operation is\n"); while((ch = getc(fp1)) != EOF) { putc(ch, stdout); } fclose(fp1); return 0; }
关键修改点说明
- 改用
rb+二进制更新模式打开文件,避免Windows文本模式的换行符转换,保证指针位置计算准确。 - 替换
gets为fgets,并通过strcspn去掉输入中的换行符,既安全又符合预期。 - 在第二个
fputs之后调用rewind(fp1)完成定位,再执行读取操作,符合C标准中更新模式的读写切换要求。 - 如果希望覆盖整个文件内容(而非部分覆盖原内容),可以先关闭文件,再用
w+模式重新打开,这样会清空原文件后再写入。
内容的提问来源于stack exchange,提问作者Rajesh
相关产品推荐
相关产品推荐

