scanf使用%s格式符是否会跳过输入缓冲区的前导空白字符?
问题结论
scanf("%s", ch); 会默认跳过之前输入残留的所有前导空白字符(包括空格、制表符、换行符等),你观察到的现象完全符合C语言标准对scanf函数的行为定义。
行为差异的底层规则
- C语言ISO标准中明确规定了scanf函数不同格式说明符的前导空白处理逻辑:
- 仅
%c、%[、%n三类格式说明符不会跳过前导空白字符,会直接读取输入流中当前的第一个字符,不管是不是空白 - 其余所有格式说明符(包含
%d、%s、%f、%x等)都会先丢弃输入流中所有连续的前导空白字符,直到找到第一个非空白字符后,才开始匹配读取对应格式的内容
- 仅
你的测试场景解释
第一段测试代码逻辑
你已经理解的部分符合规则:%d读完整数10后,输入缓冲区中残留了输入时按下的换行符\n,而%c不跳过前导空白,所以直接把这个换行符读取到str变量中,输出时就会看到str对应的位置是空的(换行符为不可见字符)。
第二段测试代码逻辑
%s属于会跳过前导空白的格式说明符:当执行scanf("%s", str)时,首先会把缓冲区中残留的换行符作为空白字符直接丢弃,之后遇到后续输入的test的第一个字符t(非空白)才开始正式读取,直到遇到test之后的空白字符停止读取,同时自动在字符串末尾追加\0结束符,因此最终输出的str就是test。
补充注意事项
- 使用
%s读取字符串时,要注意传入的字符数组长度需要预留至少1位存储自动追加的\0结束符,避免缓冲区溢出风险。你示例中定义的str[54],更安全的写法是scanf("%53s", str),限制最多读取53个非空白字符,避免越界。 - 如果需要让
%c也跳过前导空白,可以在格式符前加空格,写成scanf(" %c", &str),前面的空格会指示scanf先跳过所有前导空白字符,再读取下一个字符。
内容的提问来源于stack exchange,提问作者Paras Mittal
相关产品推荐
相关产品推荐

