c语言 scanf 输入流有空格,逗号 说明

scanf 分隔符完整详解

基础规则:%d%lf%f%s 这类转换符,默认自动跳过 空格 、Tab\t、回车换行\n,这三类叫空白符 。 遇到 , ; : # 这类普通字符不会自动跳过,会停止读取

情况 1:想用别的符号当分隔符(比如逗号 ,

输入样例:100,88.5,72 数字用逗号隔开

方法:把分隔字符直接写进 scanf 格式字符串里面

复制代码
int a;
double b,c;
//格式串里面写逗号 ,
scanf("%d,%lf,%lf", &a, &b, &c);

✅输入必须:100,88.5,72

原理:scanf 读到%d读完数字之后,去格式串找一个逗号,去输入流里面吃掉这个逗号字符,才继续读下一个 % lf

⚠️坑:输入不能多空格! 比如输入 100 , 88.5 ,72(逗号两边带空格),上面代码读取失败。 想要允许逗号前后随便带空格,写成:

复制代码
scanf("%d ,%lf ,%lf", &a, &b, &c);

%d后面加一个空格:scanf 空格代表吃掉任意数量空白(0 个 / 多个空格 tab 回车),然后再读逗号。

示例 1:分号;做分隔,输入:50;20.5;33

复制代码
scanf("%d;%lf;%lf", &a, &b, &c);

示例 2:输入格式 id:123 score:98.5

复制代码
int id;
double score;
scanf("id:%d score:%lf", &id, &score);

输入就必须照样子输入:id:123 score:98.5

scanf 格式串里面除了%格式符号,其余普通字符要求输入流原样匹配吃掉


区分两个概念非常重要

  1. 格式串里面的空白字符(空格、\t、\n) scanf("%d %lf", &a,&b);

这里两个 % d 中间多个空格:吃掉输入中任意多空白(0、1、N 个空格 /tab/ 换行都可以)。 👉 不管输入中间 1 个空格、10 个空格、换一行,全部兼容。

  1. 格式串里面写普通可见字符 , ; : - scanf("%d,%lf", &a,&b);

要求输入流必须实实在在出现这个字符,scanf 才会把它读走丢弃;没读到这个字符,直接终止读取,后续变量读取失败,值是垃圾。


常见坑演示

❌错误例子

复制代码
int a,b;
scanf("%d%d",&a,&b);

输入:10,20(用逗号分隔)

  • %d读走 10,接下来输入缓冲区字符是 ,%d遇到逗号不是数字直接停止。
  • b 读取失败,b 里面是随机垃圾值,输出 0 或者乱码。

这就是你刚才牛客自测输入写17140216;80.845,90.55,100.00全部变成 0 的根源!


拓展:如果分隔符不确定,一会逗号,一会空格怎么办?

scanf 本身做不到,这种场景就不要用 scanf,改用getchar()手动读取吃掉多余字符。

复制代码
int a,b;
scanf("%d", &a);
getchar(); //手动吃掉逗号/分号
scanf("%d", &b);

% c 特殊(重中之重刷题坑)

%c不会自动跳过空白符!!

复制代码
char ch;
scanf("%c", &ch);

输入: A(前面有空格),ch 读到的是空格字符,不是 'A'。

如果想要读字符,跳过前面空格,两种写法:

写法 1(最常用):scanf(" %c", &ch);

%c格式符前面加一个空格

复制代码
char ch;
scanf(" %c", &ch);

写法 2:手动调用getchar()吃掉空白字符

手动循环把空格、换行、tab 全部读走丢掉,直到遇到普通字符。

简单版本(只吃掉 1 个字符,只适合确定只有 1 个空白)

复制代码
char ch;
getchar(); //手动吃掉前面那一个空格
scanf("%c", &ch);

❌缺点:如果前面有好几个空格 / 多个换行,只吃掉 1 个,剩下空格依旧被 % c 读进去,不安全,OJ 不推荐。

✅健壮循环版本(真正第二种标准写法,处理任意多个空白)

复制代码
char ch;
//只要读到的还是空白字符,就一直丢弃
while( (ch = getchar()) == ' ' || ch == '\t' || ch == '\n' )
{
    //循环体空,什么都不干,仅仅消耗掉空白字符
}
//退出循环的时候ch已经读到非空白字符A

原理:循环不断 getchar,遇到空格、tab、换行就扔掉;读到 A 就退出循环,ch 存 'A'。
对比:

  • scanf(" %c", &ch)scanf 内部已经帮你封装好了这个循环,一行搞定,刷题首选。
  • while+getchar 循环:手动实现,自由度更高,可以自定义要跳过哪些字符(不止空格,也可以跳过逗号分号)。

补充拓展:还有scanf()集合 %[ ] 高级格式(了解即可,入门很少用)

复制代码
char ch;
scanf("%*[ \t\n]%c", &ch);

%*[ \t\n]

  • []:匹配括号内的字符集合
  • *读取但是不保存到变量,直接丢弃 含义:读入并丢弃所有空格、tab、换行,之后再读取一个字符到 ch。 效果等价于" %c",属于 scanf 高级语法,刷题几乎不用。
相关推荐
Logic1011 小时前
C语言/数据结构位运算题解:异或XOR找出货船中的“独特载货量“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
xx~t5 小时前
嵌入式——51单片机3
linux·c语言·嵌入式硬件·51单片机
山下梅子酒2256 小时前
洛谷-入门-B2042
c语言
ysu_03146 小时前
08-二叉树遍历:四种方式详解
c语言·数据结构·算法·leetcode
ocean21036 小时前
2025-2026年C语言专题面试高频知识点洞察
c语言·面试·面试经验
Lzh编程小栈7 小时前
STM32 DMA深度解析|原理、完整工作流程、寄存器、中断联动,嵌入式面试高频考点(F1系列)
c语言·stm32·单片机·mcu·面试
刃神太酷啦8 小时前
Redis 核心进阶:哨兵、集群、缓存问题与分布式锁详解----《Hello Redis!》(6)
linux·c语言·数据库·c++·redis·分布式·缓存
luj_17688 小时前
生物体如何应对功能击穿?
c语言·开发语言·c++·经验分享·算法
wuyk5558 小时前
从零吃透 MQTT 通信|第 11 章 MQTT 项目调试验证、性能优化、常见疑难问题、OTA 升级基础
c语言·开发语言·stm32·学习·性能优化