You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言scanf读取姓名薪资时salary乱码、无法连续输入的解决方法

错误根因

原有scanf格式串存在两个致命逻辑问题:

  1. 格式串中%*c和%d之间多写了一个普通逗号字符,按照scanf的匹配规则,必须在输入流中读到完全对应的逗号,才会继续执行后续%d的整数读取逻辑。实际输入时,姓名行读完后的下一个有效字符是薪资数字的开头,不存在逗号,因此%d匹配直接失败,salary1从未被写入值,输出的是栈上的未初始化野值,也就是你看到的无意义乱码。
  2. scanf匹配失败时不会移动输入流的读指针,失败位置前的所有字符都会残留在输入缓冲区中。后续用相同逻辑读取第二名员工信息时,残留的旧输入会直接被新的scanf调用读取,触发连续匹配失败,表现为程序无法正常接收新输入。

另外原写法用%*c硬吞单个字符处理姓名后的换行容错性极差,只要用户输入姓名后多敲了空格、多按了一次回车,就会出现吞错字符、残留空白的问题。

修复方案

去掉格式串里多余的逗号,利用scanf中空白符会自动跳过任意数量连续空白(包括换行、空格、制表符)的特性处理换行残留,替换硬吞字符的逻辑。
单条员工信息读取的正确写法:

char name1[50]; // 数组长度比最大读取长度多1,预留字符串结束符\0的位置
int salary1;
printf("Enter name and salary of 'Employee 1':\n");
// 开头加空格,跳过缓冲区中可能残留的空白;%49[^\n]最多读49个非换行字符作为姓名
// 格式串中的空格自动跳过姓名后的所有连续空白,最后%d读取整数薪资
scanf(" %49[^\n] %d", name1, &salary1);

连续读取两名员工信息的可运行示例:

#include <stdio.h>

int main() {
    char name1[50], name2[50];
    int salary1, salary2;

    printf("Enter name and salary of 'Employee 1':\n");
    scanf(" %49[^\n] %d", name1, &salary1);

    printf("Enter name and salary of 'Employee 2':\n");
    scanf(" %49[^\n] %d", name2, &salary2);

    // 回显验证
    puts(name1);
    printf("%d\n", salary1);
    puts(name2);
    printf("%d\n", salary2);
    return 0;
}
避坑要点
  • 用%[^\n]读取带空格的字符串时,指定的最大读取长度必须比字符数组长度小1,预留位置给自动追加的字符串结束符\0,避免缓冲区溢出。
  • 不要在scanf格式串中随意添加无意义的普通字符,只要输入流中不存在完全匹配的对应字符,就会直接触发匹配失败,导致后续所有输入逻辑异常。
  • 处理输入中的换行、空格等空白内容时,优先用格式串中的空白符做自动匹配,不要用%*c硬吞固定长度字符,大幅提升输入逻辑的容错性。

内容的提问来源于stack exchange,提问作者John Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:06:19