C语言使用系统调用向文件末尾写入数据的两类问题排查
C语言系统调用追加写入文件问题修复
问题1:输入内容遇空白字符截断
- 根因:读取待写入内容时使用
scanf("%s", Data),%s格式符默认以空白字符(空格、换行、制表符等)作为输入终止符,遇到首个空白就会停止读取。 - 修复方案:改用
%[^\n]格式符匹配除换行符外的所有输入字符,同时读取前清空上一次输入遗留的换行符,避免读取到空内容。
问题2:写入内容后附带乱码
- 根因:调用
write时指定的写入长度为sizeof(Data),即整个数组的1024字节,但用户实际输入的内容仅占数组前小部分空间,剩余未初始化的数组区域是随机垃圾值,被一并写入文件就产生了乱码。 - 修复方案:通过
strlen(Data)计算用户输入字符串的实际长度,以此作为write的写入长度参数。
隐藏问题修复
原代码中将write的返回值直接赋值给原文件描述符变量fd,导致后续close(fd)关闭的不是真实的文件描述符,会造成资源泄漏,改为用独立变量接收write的返回值;同时补充了错误分支的文件关闭逻辑,避免资源泄漏。
修复后完整代码
#include<stdio.h> #include<stdlib.h> #include<io.h> #include<fcntl.h> #include<string.h> int main() { char Fname[30]; char Data[1024]; int fd = 0; int iRet = 0; int write_ret = 0; printf("Enter The File Name: -"); // 限制读取长度避免数组溢出,%[^\n]读取到换行为止 scanf("%29[^\n]",Fname); // 吃掉输入缓冲区遗留的换行符 getchar(); // 可选优化:open时加O_APPEND标志,可省去手动lseek操作,多进程写入时更安全 fd = open(Fname,O_RDWR); if(fd == -1) { printf("Unable To Open File"); return -1; } else { printf("File Open Successfully\n"); } printf("Enter The String To Write At End Of The File: -"); // 前面的空格用于跳过开头的空白字符,限制读取长度为1023避免溢出 scanf(" %1023[^\n]",Data); iRet = lseek(fd,0L,SEEK_END); if(iRet == -1) { printf("Unable To Perform Operation On File"); close(fd); return -1; } // 按字符串实际长度写入,不写入多余的数组内容 write_ret = write(fd,Data,strlen(Data)); if(write_ret == -1) { printf("Unable To Write Data Into File"); close(fd); return -1; } else { printf("Data Written Into The File Successfully\n"); } close(fd); return 0; }
内容的提问来源于stack exchange,提问作者Manish Tambe
相关产品推荐
相关产品推荐

