scanf函数是一个“模式匹配”函数,也就是试图把输入的字符组与转换说明匹配成组。调用scanf函数时,scanf函数会从左向右依次处理字符串中的信息。对于格式串中的每一个转换说明,scanf函数会努力从输入的数据中定位适当的类型项,并跳过必要的空格。而当scanf函数读入数据但遇到了不可能属于该类型的项时,scanf函数会停止读入。如果读入数据成功,scanf函数会继续读取下面的数据。在寻找输入数据的初始位置时scanf函数会忽略掉空白(空格、制表符、换行符、换页符)。所以可以把输入的数据中间加入空格换行等等。而在格式串中任意多的空白字符都和一个字符等效。读入的任何数据(字符数字空格换行符等等)其实本质都是字符,只不过由scanf函数根据格式串将字符转换为格式串中对应的类型。而且输入的数据都是在键盘缓冲区中存贮的,虽然scanf函数会跳过空格,但空格仍然是在键盘缓冲区的。scanf()每次从键盘缓冲区中读取一个字符(ASCII码),直到键盘缓冲区为空。如果键盘缓冲区为非空状态,执行scanf()会不等用户输入,直接在键盘缓冲区中读入下一个字符;如果键盘缓冲区为空,执行scanf()则会等待用户的输入。
见下面例子:
#include <stdio.h>
void main()
{ char a;
while(1)
{
scanf("%c",&a);
switch (a)
{
case '1':printf("123\n");break ;
case '2':printf("456\n");break;
case '3':printf("789\n");break;
case 'e': return 0;
default: return 0;
}
}
}
此程序的本意是只要输入的字符在1、2、3之中的一个,循环就不会自动退出(因为while中条件是1,循环条件一直成立),但其实不管你一次输入一个1或一个2或一个3或一次输入输入123,然后按Enter键后,程序都会退出!这就是因为键盘缓冲区的原因,当你输入一个1之后按Enter键,1的ASCII码还有Enter键的ASCII码放在了键盘缓冲区中,而第一次循环scanf接受1的ASCII码后,第二次循环scanf()函数不等用户输入,自己就从键盘缓冲区读入Enter键的ASCII码(即13和10),而13和10不在123之内,所以程序执行了default而退出。
gets()函数:
scanf函数在读入数字时会忽略掉输入的空格换行符等,但当scanf读取字符串时呢?scanf函数在读取字符串后会以空白(空格或换行符或制表符)结束,即不读入此空白(而且scanf函数在读入字符时也会忽略掉开始的空白,而gets函数则不会,gets函数会在读入换行符时结束,但不会把此换行符存贮在数组中,而是丢弃此换行符。读取的换行符被转换为null值,并由此来结束字符串。)。scanf函数读入字符串会在结束时末尾存贮一个空字符。gets函数会自动读入空白,见下例:
#include <stdio.h>
main()
{
char ch1[10],ch2[10];
scanf("%s",ch1);
gets(ch2);
printf(%s”,ch1);
printf(“\n”);
printf(“%s”,ch2);
}
输入abcde空格空格hijkl回车,然后看输出结果,
发现输出是abcde
hijkl(hijkl前面有两个空格)
scanf函数只读入了abcde,后面的都被gets()函数自动读入了。因为gets()函数可以接受空格回车制表符。
再看下面的例子:
#include <stdio.h>
main()
{
char ch1[10],ch2[10],c1,c2;
scanf("%s",ch1);
c1=getchar(); /*读取scanf读取字符串结束后的换行*/
gets(ch2); /*读取输入的字符串加换行,所以下面的getchar()函数无字符可读入*/
c2=getchar();
}
依次键入asdfg回车,asdfg回车,则ch1="asdfg\0",c1='\n',ch2="asdfg\0",c2需输入。
gets函数的读取规则:
1.只要gets遇到换行符,即便它是输入的第一个字符,gets也会停止读入并返回。如果输入的第一个字符就是换行符,则字符串将被置为空串。
2.由于gets函数读入再丢弃换行符,换行符将不会存储在字符串中。
gets的读取规则与getline是一样的。
gets函数的返回值:
1.正常读入(未遇到文件结尾)(注意,读入空串也是正常读入),则返回字符串,即返回字符串首地址,char*类型
2.遇到文件结尾,返回NULL
参考网站:站:http://blog.youkuaiyun.com/digu/archive/2010/05/11/5578821.aspx