这是一个很有意思的函数
a.scanf函数的作用是什么
该函数的主要作用就是将用户输入的内容读入,并保存在内存的某个变量中。scanf
函数会忠实地录入用户输入的信息,哪怕是空格。
函数的主要形式:
int i,j;
float x,y;
scanf("%d%d%f%f",&i,&j,&x,&y)
注意事项有:
在scanf函数中,其转换说明是可以紧密挨着的;
要注意转换说明与输入变量的数量和类型要一致;
在scanf函数中,输入变量前要有&符号;
b.scanf函数的工作方法
scanf()
函数实际上是一种模式匹配函数,其试图将转换说明和输入变量一一匹配。
实际上用户从键盘输入各种字符时,程序并没有读取输入,而是将用户的输入放在了一个隐藏的缓冲区中,而后再由scanf函数读取。
scanf()
函数也是由格式串控制的。函数被调用时,从左边开始处理格式串。
函数识别输入的数字的方法
用户在向程序中输入数值时,可能在输入第一个数值之前或在输入两个数值之间会输入多个空白字符(white-speace character,包括空格符、水平和垂直制表符、换页符和换行符)。
因此scanf函数在寻找数的位置时,会自动忽略这些空白字符。
函数在识别整数时,首先寻找正号或负号,然后读取其后的数字直到读到一个非数字为止。
函数在识别浮点数时,首先寻找正号或负号,然后读取其后的数字。在这一串数字中,可能有小数点,也可能有指数形式。在遇到一个非数字时停止。
举个例子:
使用scanf
函数读取以下数值:
1-20.3-4.0e3
语句为:
scanf("%d%d%f%f",&i,&j,&x,&y);
读取结果为:
1,20,0.3,-4.0e3
值得注意的是,.3
可以表示小数0.3
。
而函数在读取剩余两个数值的逻辑是:
转换说明的第三项是浮点数,读取字符'.' ,'3','-',因浮点数后不能带'-',那么读取.3为0.3,并放入变量x中,把'-'放回原处。
而后第四项转换说明是浮点数,读取字符'-','4','.','0','e','3',即读取-4.0X10^3^,并存入变量y中。
c.格式串中的普通字符
格式串是由转换说明和普通字符构成的。
处理格式串中的普通字符时,函数scanf
主要依赖读取的这个字符是否时空白字符。
空白字符
:当在格式串中遇到一个或多个空白字符时,scanf函数从输入中重复读空白字符,直到遇到一个非空白字符(将该空白字符放回原处)为止。格式串中的空白字符的数量无关紧要,格式串中的一个空白字符可以与输入中的任意数量的空白字符相匹配,包括零个,也就是说格式串中包含空白字符并不意味着输入中必须包含空白字符。
其他字符
:当在格式串中遇到非空白字符时,scanf函数自动将把它与下一个输入字符相比较。如果两个字符相匹配,那么函数会放弃输入字符而继续处理格式串。如果不匹配,那么函数会把不匹配的字符放回输入中,然后异常退出,而不进一步处理格式串或从输入中读取字符。
————————我是分隔符——————————————
举个例子:
假设格式串是:%d/%d
1.如果输入是:空格5/空格96
scanf函数的处理过程如下:
首先格式串第一个就是转换说明,要求输入一个整数。那么函数会从输入中寻找一个整数,但是输入首先是一个空格,也就是空白字符,函数会将其跳过,而后便是整数数值5,将其读取并存入变量中。
而后格式串第二个字符是普通字符的非空字符/
,函数便在输入中寻找与之相匹配的字符,恰好匹配,便读入内存中。
格式串的第三个字符是整数的转换说明,函数又开始在输入中寻找整数。但是输入中的字符是空格,函数将其跳过,遇到一个整数数值96,函数便将其读入内存并存入变量中。
令人迷惑的一点是,scanf函数会在寻找数字时跳过输入中的空白字符,而不是格式串中的空白字符。
2.如果输入是:空格5空格/空格96
scanf函数的处理过程如下:
首先格式串第一个就是转换说明,要求输入一个整数。那么函数会从输入中寻找一个整数,但是输入首先是一个空格,也就是空白字符,函数会将其跳过,而后便是整数数值5,将其读取并存入变量中。
而后,格式串第二个字符是普通字符的非空白字符/
,函数便在输入中寻找与之相匹配的字符。但是在输入的相应位置出现的是空格。由于此时格式串中需要匹配的不是数字,而是一个非空字符/
,函数scanf不能省略输入中的空格,因此匹配失败。函数将输入中的空格放回原处,空格/空格96
留待下一次scanf函数调用读取。
————————我是分隔符——————————————
再举个例子:
printf("Enter a number:");
scanf("%d",&i);
假设用户输入了一个有效数,后面跟着一些非数值的字符:
Enter a number: 23foo
函数scanf会读取数字23
并将其存入变量i
中,而其后的非数值字符将会被放回原处,留待下一次scanf函数调用读取。
假设用户只是输入了一些非数值字符:
Enter a number: foo
在这种情况下,scanf函数不会读取任何数值或字符,而是将这些字符放回原处,留待下一次scanf函数调用读取。