关于c语言的scanf用来读取字符的一些总结

关于c语言的scanf用来读取字符的一些总结

scanf() 是带有缓冲区的。遇到 scanf() 函数,程序会先检查缓冲区中是否已经有数据

  1. 如果没有,就等待用户输入。用户从键盘输入的每个字符都会暂时保存到缓冲区,直到按下回车键,输入结束,scanf() 再从缓冲区中读取数据,赋值给变量。
  2. 如果有数据,哪怕是一个字符,scanf() 也会直接读取,不会等待用户输入。
  3. 注意:scanf() 匹配到想要的数据后,会将匹配到的数据从缓冲区中删除,而没有匹配到的数据仍然会留在缓冲区中。

scanf("%c",&ch)类型

1.单纯使用%c

#include<stdio.h>
#include<stdlib.h>
 int main(){
 	system("color F4");
	int i=0;
	char c;
	char s[5];
	for(i=0;i<5;i++){
		scanf("%c",&s[i]); 
		c = s[i];
		printf("%c %c\n",s[i],c);
	} 
	return 0;
 } 

在这里插入图片描述
输入过程理解:
第一次:你认为你输入的是a,缓存区里面是a'\n'
结果就是s[0]=c=a,打印a,a 然后换行,i=1;缓存区剩下'\n',然后是s[1] = s[1] = ‘\n’,打印 ‘\n’,’\n’,然后换行。i=2,缓冲区空。

第二次:同理,你认为你输入了c,缓冲区里面是c'\n'
结果就是s[2]=c=‘c’,打印c,c 然后换行,i=3;缓冲区剩下'\n',然后是s[3] = s[3] = ‘\n’,打印 ‘\n’,’\n’,然后换行。i=4,缓冲区空。

第三次:你认为你输入了d,缓冲区里面是d'\n'
结果就是s[4]=c=‘d’,打印d,d 然后换行,i=5,结束。
解决办法
修改格式,我们忽略缓冲区上一次的残留。

scanf(" %c",&s[i]);

在这里插入图片描述
2.当要输入整数又要输入字符时

#include<stdio.h>
#include<stdlib.h>
int main()
{
	system("color F4");
	char a,b,c;
	int number;
	scanf("%d",&number);
	scanf("%c%c%c",&a,&b,&c);//"%c %c %c"三个%c之间没有空格
	if(a == 10)	printf("字符a是换行\n");
	else if(a == 32)	printf("字符a是空格\n");
	else printf("a = %c\n",a);

	if(b == 10)	printf("字符b是换行\n");
	else if(b == 32)	printf("字符b是空格\n");
	else printf("b = %c\n",b);

	if(c == 10)	printf("字符c是换行\n");
	else if(c == 32)	printf("字符c是空格\n");
	else printf("c = %c",c);
	return 0;
}

在这里插入图片描述
我们就能知道scanf读取的过程了。所以要十分注意。
可以适当的加上语句getchar()来接受输入时带来的换行或者空格(空格可以在scanf()双引号中的格式中控制)。

scanf函数 注意事项及使用的形式

使用形式

  1. 返回值
    scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。如:scanf("%d %d",&a,&b);
    函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2;如果只有a被成功读入,返回值为1;如果a和b都未被成功读入,返回值为0;如果遇到错误或遇到end of file,返回值为EOF。end of file为Ctrl+z 或者Ctrl+d。
  2. 非空白符与空白符
    非空白符使 scanf() 在流中读一个匹配的字符并忽略之。例如,"%d,%d" 使 scanf() 先读入一个整数,读入中放弃逗号,然后读另一个整数。如未发现匹配,scanf() 返回。空白字符会使scanf函数在读操作中略去输入中的一个或多个空白字符。
  3. 百分号(%)与格式符之间的星号(*)表示读指定类型的数据但不保存。因此,如:scanf("%d%*c%d",&x,&y);对 10/20 的读入操作中,10 放入变量 x,20 放入 y。
  4. 格式命令可以说明最大域宽。 在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。例如,希望向 address 读入不多于 20 个字符时,可以书写成如下形式:
    scanf("%20s",address);
    如果输入流的内容多于 20 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。
  5. ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C:
    %[ABC]
    使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符,返回时,数组中放置以 null 结尾、由读入字符组成的字符串。用连字符可以说明一个范围(C99无)
    如%[A-Z]则可以读取A-Z的字符
  6. "%n[a-z]" 读入最多n个字符,如果遇到非a-z的字符,停止;"%[^=]" 读入任意多的字符,直到遇到"=“停止;”%n[^=]" 读入"="号前的至多n 个字符

注意事项

  1. 在高版本的 Visual Studio 编译器中,scanf 被认为是不安全的,被弃用,应当使用scanf_s代替 scanf。
  2. 对于字符串数组或字符串指针变量,由于数组名可以转换为数组和指针变量名本身就是地址,因此使用scanf()函数时,不需要在它们前面加上"&"操作符。
  3. scanf中要求给出变量地址,如给出变量名则会出错。经常可能会犯的,要注意!!!
  4. scanf函数中没有类似printf的精度控制。如scanf("%5.2f",&a); 是非法的。不能企图用此语句输入小数为2位的实数

一些例子

One 如何让scanf()函数正确接受有空格的字符串?如: I love you!
在这里插入图片描述
解决办法是修改输入的格式
在这里插入图片描述
Two 键盘缓冲区残余信息问题
除了scanf(" %c",&s[i]);加空格忽略上一次的缓冲区字符,使用getchar()吃掉也行。
在这里插入图片描述
百度百科

发布了94 篇原创文章 · 获赞 66 · 访问量 5481

猜你喜欢

转载自blog.csdn.net/qq_44861675/article/details/105007846