C语言goto回跳局部标签未调用strcpy却篡改namalengkap变量问题
问题根因
这个异常和strcpy没有任何关系,是两处基础逻辑错误叠加导致的。文件写入内容正常是因为写文件的fprintf逻辑本身没有问题,故障完全出在后续读文件回显的代码段:
- 第一处错误:
rewind(fp)写在了goto scan之后,属于永远不会执行的死代码。
每次跳回scan标签时,文件指针始终停在上一次读取结束的位置,根本没有回到文件开头,后续读取会顺着文件偏移一直往后读,直到读到文件末尾。 - 第二处错误:
fscanf的格式串书写错误,除了第一个字符串匹配符,后续所有[^\n]前都漏了必需的%前缀。
错误写法:
格式串里没有加fscanf(fp,"%[^\n]\n[^\n]\n%d\n%d\n%d\n[^\n]",namalengkap,gender,&umur,&tb,&bb,tdeeprint);%的[^\n]会被当成普通字符序列做匹配,要求文件里出现连续的[、^、\、n、]字符,和文件实际内容完全不匹配,所以fscanf从第一次调用开始就没有完成所有字段的正确赋值——第一次看到输出正常,只是因为此时namalengkap/gender/umur等变量还保留着之前用户输入阶段写入的值,不是读文件读到的正确结果。
现象对应解释
每次跳转后namalengkap依次变成Laki-Laki、82、5,是两个错误叠加的必然结果:
- 第一次进入
scan时,文件指针在开头,fscanf的第一个%[^\n]正确把第一行用户名读入namalengkap,之后尝试匹配字面的[字符失败,函数直接返回,其余变量保留之前输入的值,所以第一次输出看起来完全正常。 - 第一次输入1触发跳转时,因为没有执行
rewind,文件指针停在第一行末尾,第二次调用fscanf时,第一个%[^\n]直接把第二行的性别值Laki-Laki读入namalengkap,之后匹配失败返回,其余变量值不变,就出现了welcome Laki-Laki的输出。 - 后续每次跳转,文件指针都会往后顺移一行,第一个
%[^\n]就会依次把第三行的年龄82、第四行的身高5读入namalengkap,和贴出的运行结果完全吻合。
修复方法
- 调整代码顺序,把
rewind(fp)放到goto scan之前,保证跳转回读取逻辑前文件指针回到开头:if(check==1) { rewind(fp); goto scan; } - 修正
fscanf的格式串,给所有字符串匹配段加上%前缀:fscanf(fp,"%[^\n]\n%[^\n]\n%d\n%d\n%d\n%[^\n]",namalengkap,gender,&umur,&tb,&bb,tdeeprint); - 额外注意:代码里的
fflush(stdin)属于C标准未定义行为,fflush仅对输出流有明确定义,清空输入缓冲区残留换行建议用循环读空白符的方式实现,不要依赖这个写法。
内容的提问来源于stack exchange,提问作者LearnerC
相关产品推荐
相关产品推荐

