关于scanf的多种应用场景与相关知识

经过本次期中考试,我深刻认识到我对输入的各种方法不太熟悉,所以我写下这篇总结,巩固一下自己的知识。顺便记录下我学习中遇到的输入方法及输入的相关知识。


1. 输入格式:输入在一行中给出若干字符,最后一个回车表示输入结束,不算在内。

while ((c=getchar())!='\n')
{
}

意思为:一直循环,直到输入回车为止,结束循环,只要用户输入的不是回车,while循环就会一直执行。

调用getchar时,用户输入的字符被存放在键盘缓冲区中。当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符。

有的人会有疑问:

为什么是一个字符一个字符读取的?而非一起读入?

这就是getchar() 的作用-----每次从控制台读入一个字符,虽然输入的时候是一起输入的 但是字符被放在缓存区里,一次只读入一个。

应用场景:

要求编写程序,输入一行字符,统计其中数字字符、空格和其他字符的个数。建议使用switch语句编写。

输入格式:输入在一行中给出若干字符,最后一个回车表示输入结束,不算在内。

输出格式:在一行内按照 blank = 空格个数, digit = 数字字符个数, other = 其他字符个数 的格式输出。请注意,等号的左右各有一个空格,逗号后有一个空格。

输入样例:在这里给出一组输入。例如:

Reold 12 or 45T 

输出样例:在这里给出相应的输出。例如:

blank = 3, digit = 4, other = 8

代码:

#include <stdio.h>
int main()
{
    char c;
    int letters = 0, space = 0, digit = 0, other = 0;
    while ((c = getchar()) != '\n')
    {
        if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
        {
            other++;
        }
        else if (c == ' ')
        {
            space++;
        }
        else if (c >= '0' && c <= '9')
        {
            digit++;
        }
        else
        {
            other++;
        }
    }
    printf("blank = %d, digit = %d, other = %d", space, digit, other);
    return 0;
}

2. 输入格式:输入在一行中给出用户连续输入的若干个编号

  • 已知数量,个数较少
scanf("%d%d%d",&a,&b,&c);
  • 已知数量,个数较多
#include<stdio.h>
int main()
{
	int n;
	int a[100];
	for (int i = 0; i < n; i++)//n - 已知个数
	{
		scanf("%d", &a[i]);
	}
	return 0;
}
  • 未知数量

我在 实验3-5 查询水果价格中遇到了一个问题:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int i,choice;
	printf("[1] apple\n[2] pear\n[3] orange\n[4] grape\n[0] exit\n");
	for(i = 0;i < 5;i++)
	{
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:printf("price = 3.00\n");
			      break;
			case 2:printf("price = 2.50\n");
			      break;
			case 3:printf("price = 4.10\n");
			      break;
			case 4:printf("price = 10.20\n");
			      break;
			case 0:
			      exit(0);
			default:printf("price = 0.00\n");
                    break;
		}
	}	
	return 0;
}

在这里插入图片描述
我们都知道所有从键盘输入的数据,不管是字符还是数字,都是先存储在内存的缓冲区中,叫作 “键盘输入缓冲区”,那么为什么空格不会被当作数据输出呢?

经过一番查询,原来:

对于 %d,在缓冲区中,空格、回车、Tab 键都只是分隔符,不会被 scanf 当成数据取用。%d 遇到它们就跳过,读取下一个数据。
(本质上,控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。)

但是:

如果是 %c,那么空格、回车、Tab 键都会被当成数据输出给 scanf 取用
(很显然,我弄混了%c和%dhhh~)

例如:

# include <stdio.h>
int main(void)
{
    int a, c;
    char b;
    scanf("%d%c%d", &a, &b, &c);
    printf("a = %d, b = %c, c = %d\n", a, b, c);
    return 0;
}

在这里插入图片描述
由结果可以看出:数字 1 赋给变量 a,而因为变量 b 是 %c,所以前三种情况分别将空格、回车和 Tab 键赋给变量 b,然后数字 5 赋给变量 c,而数字 6 仍然在缓冲区中,等待下一个 scanf 来取。

3. 缓冲区问题

应用场景:
ASCII码排序
Problem Description
输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符。

Input
输入数据有多组,每组占一行,有三个字符组成,之间无空格。

Output
对于每组输入数据,输出一行,字符中间用一个空格分开。

Sample Input

qwe
asd
zxc

Sample Output

e q w
a d s
c x z

int main()
{
	char a, b, c;
	char t;
	while (scanf("%c%c%c", &a, &b, &c) != EOF)
	{
		getchar(); //必须得加这玩意
		if (a > b)
		{
			t = a;
			a = b;
			b = t;
		}
		if (a > c)
		{
			t = a;
			a = c;
			c = t;
		}
		if (b > c)
		{
			t = b;
			b = c;
			c = t;
		}
		printf("%c %c %c\n", a, b, c);

	}
	return 0;
}

没有加getchar()函数,结果是不正确。

  • 从键盘输入的字符,会存放到缓冲区中,包括回车符。如输入“abc回车”之后,缓冲区中存了有四个字符’a’、‘b’、‘c’、’\n’,如果上面程序中没有getchar(),则第一次从缓冲区中提取了三个字符之后,还剩下了一个’\n’,则下次再输入三个字符时,缓冲区中会把上次剩下的回车符也算进去。
  • getchar()是从缓冲区中读取一个字符,如果只是去除缓冲区中的字符,不需要用赋值表达式,可以使用getchar()。如果是要获取字符,可以使用m=getchar()

原来scanf函数有这么多需要注意的点,怪不得在VS中scanf被视为不安全的函数hhhhh~

要想更深入的了解scanf函数,大家可以去看看这些资料
百度百科 - scanf
C语言清空输入缓冲区完全攻略

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值