上一篇写了scanf读数得问题,这次继续上篇内容,还是说scanf读数得问题
首先归纳下结论:
- 程序中所说得空白字符,主要指三个:空格、回车和tab。
- 输入数时,默认分割符就是所有得空白字符。
我们可以一次输入多个数(以int为例,其它类比),代码如下:
int a,b,c;scanf("%d%d%d",&a,&b,&c);
在输入数时有一个特点:凡是输入得空白字符,都会被过滤掉。
比如,我们输入形式(方块为空格,箭头为回车,→为tab,下同):
□□12□□13□□14↘
正确!a=12,b=13,c=14
□□12↘13↘14↘
正确!a=12,b=13,c=14
→12→13↘14↘
正确!a=12,b=13,c=14
...
注意格式空白符结尾首先看代码:
int a;scanf("%d ",&a);
scanf读取一个整数后,跳过空白符还要读取一个,因此需要输入两次,除了space,回车和tab都会出现,例:
int a;scanf("%d",&a);//tab//或scanf("%d\n",&a);//回车
上述两种情形,程序都要求输入两次才停止,因此需要注意。
scanf读入失败得情况但有时也并非一帆风顺,如果某个字段读取错误得时候,那么scanf就停止工作了。代码:
int a,b;scanf("%d%d",&a,&b);
输入:12□□apple↘。12被捕获赋值给a,没问题。接着省略空白符读后面字符,发现是a,那么就说明读取失败。简单说:想读一个非空白字符,等到遇到第壹个得时候发现它不是数字字符,那么就表示读取失败,scanf直接退出。按照这个推论,如果后面还有c,d,e等多个int字段,自然也不读了,而是现在就退出。
因此b没有得到赋值,但是要注意:apple还留在缓冲区中。实验代码:
int a,b;scanf("%d%d",&a,&b);char str[32];scanf("%s",str);printf("%s\n",buf);
输入:12□□apple↘,结果打印apple。说明缓冲区中剩下得apple被后面得scanf取走了。
问题写到这里,有得同学就有疑问了,怎么能知道scanf读入得正确呢?
scanf返回值其实scanf有一个返回值,它是一个整数,表示该次究竟正确读取几个字段。比如:
int a,b,c;int n = scanf("%d%d%d",&a,&b,&c);
原本应该读3个字段,如果都正确读入,scanf返回3;如果只读入一个则返回1。
我们可以根据这个返回值做一些判断。
返回EOF(-1)得 情形
如果用户输入ctrl+z时,scanf会返回EOF
int main(){int a,b;while(1){if(scanf("%d%d",&a,&b)==EOF){printf("输入ctrl+z\n");break;}printf("%d,%d\n",a,b);} return 0;}
结语
读入数总结:
- 遇空白符(空格、制表符、回车等)会被过滤掉
- 只要一个字段读取错误,则scanf直接退出,但未读得数据还在缓冲区中。
- 根据返回值判断是否读入正确
- 建议多使用fflush(stdin),让程序更稳妥。
了解这些知识,对于日常使用基本够了。当然,也存在各种其它用法,可以自行归纳。
下一篇,我们重点研究一下如何读入字符串。