Linux下printf格式化字符串%s后加逗号导致输出异常求助
问题原因分析
你的问题根源在于输入文件的换行格式与Linux系统不兼容,导致读取的字符串中混入了Windows风格的回车符\r:
- specs.dat文件是Windows换行格式(每行结尾为
\r\n),而Linux系统仅使用\n作为换行符。 - 在
read_Specs函数中,%29[^\n]的格式会读取换行符\n之前的所有字符,包括Windows换行中的\r,最终spec1->name的实际内容是"Jason Oliver\r"。 - 执行
printf("Dear %s,"...)时,%s输出"Jason Oliver\r",其中\r是回车控制符,会将光标移到当前行开头;随后输出的逗号','会覆盖行首的'D',最终就出现了,ear Jason Oliver的异常输出。
解决方法
以下三种方法任选其一即可解决问题:
方法1:手动移除字符串末尾的\r
在read_Specs函数读取完用户名后,检查并删除末尾的回车符:
void read_Specs(char fileName[],spec *spec1){ FILE *specs = fopen(fileName, "r"); if (!specs) { // 建议增加文件打开失败的判断 perror("Failed to open specs file"); return; } fscanf(specs, "%29[^\n]\n %19s\n %f\n %f\n %f", spec1->name, spec1->material,&spec1->width, &spec1->height, &spec1->depth); // 移除末尾的回车符 size_t name_len = strlen(spec1->name); if (name_len > 0 && spec1->name[name_len - 1] == '\r') { spec1->name[name_len - 1] = '\0'; } fclose(specs); }
方法2:修改fscanf格式串,避免读取\r
将读取用户名的格式符从%29[^\n]改为%29[^\r\n],同时排除\r和\n,避免回车符被读入字符串:
fscanf(specs, "%29[^\r\n]\n %19s\n %f\n %f\n %f", spec1->name, spec1->material,&spec1->width, &spec1->height, &spec1->depth);
方法3:转换文件为Linux换行格式
使用Linux自带的dos2unix工具将specs.dat转换为Linux风格的换行格式:
dos2unix specs.dat
若未安装dos2unix,可通过以下命令安装:
sudo apt install dos2unix
额外注意事项
- 建议在文件操作时增加错误判断(比如
fopen是否成功),避免因文件缺失或权限问题导致隐性错误。 read_Supervisors中的buffer大小为MAX=10,如果Builders.dat中出现更长的行(比如名字+数字超过8个字符),会导致缓冲区溢出,建议适当增大MAX的值(例如改为40)。
内容的提问来源于stack exchange,提问作者Daniel Boos
相关产品推荐
相关产品推荐

