目录
一、scanf函数的定义
二、scanf函数的返回值
三、scanf函数的控制符
四、scanf函数控制符的使用
1.一般用法
2.scanf()函数%[]控制符的用法
2.1%[]控制符的两种形式
2.2 "-"字符的使用
3.键盘缓冲区残余信息问题
4.scanf()函数错误输入造成程序死锁或出错的解决方法
声明:本人是正在学习C语言的小白一枚,以下是本人目前对scanf函数的理解,如有错误欢迎评论区指正。
一、scanf函数的定义
int scanf( const char *format [,argument]... );
scanf函数是C语言的一个库函数,它在头文件stdio.h中被定义。所以想要使用scanf必须加上#include<stdio.h>。scanf()函数的功能是按指定的格式把数据输入指定的变量中。
二、scanf函数的返回值
scanf函数返回成功读入的数据项数返回值为int型,读入数据时遇到了“文件结束”则返回EOF。例:
注意:如果scanf中%d是连着写的如“%d%d%d”,在输入数据时,数据之间不可以用逗号分隔,只能用空白字符(空格或tab键或者回车键)分隔——“1 (空格)2(tab) 3” 或 “1(tab)2(回车)3”等。若是“%d,%d,%d”,则在输入数据时需要加“,”,如“1,2,3”。
int main()
{
int a, b, c;
int d = scanf("%d%d%d", &a, &b, &c);
printf("%d,%d,%d\n", a, b, c);
printf("scanf函数返回值=%d\n",d);
return 0;
}
1.scanf函数成功读入a,b,c则函数返回3.
2.scanf函数只成功读入a,b则函数返回2.
3.输入错误的格式scanf函数一项也没能读入则函数返回0.
4.错误或遇到end of file,返回值为EOF(-1).
三、scanf函数的控制符
scanf()函数的控制符太多了,以下是我从网上找到的一部分可能不够全面。
修饰符
修饰符 |
意义 |
* |
滞后赋值;示例:"%*d" |
域宽 |
指定输入数据所占宽度(列数),域宽应为正整数 |
hh |
b把整数读作signed char或unsigned char;示例:"%hhd" "%hhu" |
ll |
b把整数读作long long或unsigned long long(c99);示例:"%lld" "%llu" |
h,l或L |
"%hd"和"%hi"指示该值将会储存在一个short int中。"%ho"、"%hx"和"%hu"指示该值将会储存在一个unsigned short int中。"%ld"和"%li"指示该值将会储存在一个long中。"%lo"、"%lx"和"%lu"指示该值将会储存在一个unsigned long中。"%le"、"%lf"和"%lg"指示该值以double类型储存。将L(而非l)与e、f和g一起使用指示该值以long double类型储存。如果没有这些修饰符,d、i、o和x指示int类型,而e、f和g指示float类型; |
转换说明符
转换说明符 |
意义 |
%c |
把输入解释称一个字符 |
%d |
把输入解释称一个有符号十进制整数 |
%e,%f,%g,%a |
把输入解释称一个浮点数(%a是c99标准) |
%E,%F,%G,%A |
把输入解释称一个浮点数(%A是c99标准) |
%i |
把输入解释称一个有符号十进制整数 |
%o |
把输入解释称一个有符号八进制整数 |
%p |
把输入解释称一个指针(一个地址) |
%s |
把输入解释称一个字符串,输入内容以第一个非空白字符作为开始,并且包含直到下一个空白字符的全部字符 |
%u |
把输入解释称一个无符号十进制整数 |
%x,%X |
把输入解释称一个无符号十六进制整数 |
[] |
字符集合 |
四、scanf函数控制符的使用
1.一般用法
#include<stdio.h>
int main()
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
printf("%d,%d,%d\n", a, b, c);
return 0;
}
(1) &a、&b、&c中的&是地址运算符,分别获得这三个变量的内存地址。
(2) "%d%d%d"是按十进值格式输入三个数值。输入时,在两个数据之间可以用一个或多个空格、tab键、回车键分隔。
#include<stdio.h>
int main()
{
int a, b, c;
scanf("a=%d,b=%d,c=%d", &a, &b, &c);//假如输入1 2 3这三个数,输入格式为a=1,b=2,c=3
printf("%d,%d,%d\n", a, b, c);
return 0;
}
(1)scanf()的格式控制串可以使用其它非空白字符,但在输入时必须输入这些字符。
在用"%c"输入时,空格和“转义字符”均作为有效字符。
例:
scanf("%c%c%c",&c1,&c2,&c3);
输入:a(空格)b(空格)c(回车)
结果:a→c1,(空格)→c2,b→c3 (其余被丢弃)
2.scanf()函数%[]控制符的用法
2.1%[]控制符的两种形式
#include<stdio.h>
int main() {
char String[100] = { 0 };
scanf("%s",String);
printf("%s",String);
return 0;
}
如果想实现输入 "I am bit"这样的字符串,你会发现得不到想要的结果。因为遇到了空格只读了第一个空格前的数据。针对这种带空格的字符串,可以使用%[]控制符来实现输入。
%[]控制符有两种形式,一种是以"^"开头, %[^……],在读字符时匹配[ ]中所有字符,如果输入的字符和[ ]中的任意字符相同就结束。另一种是不带"^",%[……],在读字符时匹配[ ]中所有字符,如果输入的字符和[ ]中的任意字符不相同就结束。
#include<stdio.h>
int main()
{
char String[100];
scanf("%[^z]",String);//带^,当输入字符为z的时候字符串输入结束
printf("%s\n",String);
return 0;
}
#include<stdio.h>
int main()
{
char String[100];
scanf("%[abcd]",String);//不带^,当输入字符除abcd外任意字符的时候字符串输入结束
printf("%s\n",String);
return 0;
}
2.2 "-"字符的使用
"-"字符在其两边都有有效字符的时候表示"-"两边字符间的所有字符(按ASCLL表排序)如a-d表示abcd这四个字符,0-9表示012……9这10个字符,如果"-"只有一边有有效字符或者两边都没有有效字符则它只表示一个"-"字符。
#include<stdio.h>
int main()
{
char String[100];
scanf("%[^0-9]",String);//当输入字符为0 1 2 …… 9中任意字符的时候字符串输入结束
printf("%s\n",String);
return 0;
}
3.键盘缓冲区残余信息问题
#include<stdio.h>
int main() {
int a=0 ;
char b=0 ;
scanf("%d",&a);
scanf("%c",&b);
printf("a=%d b=%cb=%d",a,b,b);
return 0;
}
执行这段代码会发现scanf("%c",&b);这句不用输入数据到输入缓冲区,它自己就能拿到数据。什么原因呢?我们用printf("c=%d",b);将C用int表示出来,发现结果是 b=10 ,ASCII值为10是什么?就是换行(\n).对了,第一个scanf("%d",&a)我们打一下"Enter"键,向键盘缓冲区发去一个“回车”(\n),而\n被scanf()函数“错误”地赋给了b。
解决办法:可以在两个scanf()函数之后加个fflush(stdin);,还有加getch(); (这是别人说的,我发现在vs编译器下getch,并不会从输入缓冲区拿数据,更像是直接从键盘拿)getchar();也可以,但是要视具体scanf()语句加哪个,但是加fflush(stdin);不管什么情况都可行。
函数名: fflush
功 能: 清除一个流
用 法: int fflush(FILE *stream);
#include<stdio.h>
int main() {
int a=0 ;
char b=0 ;
scanf("%d",&a);
fflush(stdin);
scanf("%c",&b);
printf("a=%d b=%cb=%d",a,b,b);
return 0;
}
4.scanf()函数错误输入造成程序死锁或出错的解决方法
//
#include <stdio.h>
int main()
{
int a,b,c; /*计算a+b*/
scanf("%d,%d",&a,&b);
c=a+b;
printf("%d+%d=%d",a,b,c);
}
//
如上程序,如果正确输入a,b的值,那么没什么问题,但是一旦输入了错误的类型,你的程序不是死锁,就是得到一个错误的结果,这可能所有人都遇到过的问题吧?
解决方法:scanf()函数执行成功时的返回值是成功读取的变量数,也就是说,你这个scanf()函数有几个变量,如果scanf()函数全部正常读取,它就返回几。但这里还要注意另一个问题,如果输入了非法数据,键盘缓冲区就可能还个有残余信息问题。
正确的例程:
//
#include <stdio.h>
int main()
{
int a,b,c; /*计算a+b*/
while(scanf("%d,%d",&a,&b)!=2)fflush(stdin);
c=a+b;
printf("%d+%d=%d",a,b,c);
}
//
参考文章
scanf函数详解