scanf函数的读取

scanf的处理机制

scanf()以删除的方式从缓冲区读取数据(输入设备的数据存储缓冲区,比如键盘);也就是说,scanf从缓冲区读入一个数据项,该数据项在缓冲区中就被清除掉了。而如果scanf需要读取一个数据项,返现缓冲区当前是空的,那么程序就会在scanf代码处阻塞,等待用户输入,scanf函数接收到相应的数据项之后,在缓冲区中将这一数据项清除,scanf函数返回,程序继续执行。
格式化字符串(format string)

格式化字符串

规定了 scanf 等函数如何从输入缓冲 stdin 中读取数据,其组成字符的含义如下所示:

(1)空白字符(whitespace)。scanf 会读取并忽略在 stdin 中下一个非空白字符之前的所有空白字符(空格、换行和 tab),然后读取格式化字符串中规定格式的数据。若格式化字符串中包含空白字符,则该空白字符会与输入缓冲区中任意数量的连续空白字符相匹配,并将其从缓冲区中清除(包括0个)。例如格式化字符串"%d %d",会要求 scanf 首先从缓冲区中读取一个整型(若之前存在空白字符则跳过),再跳过输入缓冲区中连续的空白字符(与格式化字符串中的空白字符匹配),最后再读取一个整形;

(2)非空白字符(non whitespace)。对于格式化字符串中既非空白字符又不是格式说明符(format specifier,由%标识)的一部分的字符,scanf 会尝试从 stdin 中读取输入,并将输入与该字符比较,若匹配,则继续进行后续读取,若不匹配,则函数返回错误信息;

(3)格式说明符。以 % 开头的用于指定输入数据格式的字符。如 %d 指定需要读取一个整形,%s 需要读取一个字符串。scanf 等函数首先根据格式说明符尝试去解析 stdin 中的数据,如对于 %d ,scanf 会尝试对 stdin 中已有数据以整型的格式进行解析。若解析成功,则将上述解析结果存放到指定的内存中,若解析失败,如 stdin 中仅存在一个字符 ‘a’,scanf 会退出并返回,但是上述不匹配的数据并不会从缓冲区中清除,后续的 scanf 调用仍从上述输入开始读取
  除了%c 其他转化说明都会自动跳过待输入值前面所有的空格

scanf的返回值

scanf通常返回的是成功赋值(从标准输入设备赋值到参数列表所指定的内存区域)的数据项数,如果出错或是遇到end of file(注意,如果想从键盘输入EOF,在windows的DOS窗口用Ctrl+Z 或F6;在UNIX系统上,用CTRL+D。),则返回EOF

1.格式不匹配问题

#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
	int nNum = 0;

	scanf("%d",&nNum);//输入AB

	printf("%d\n",nNum);

	char chA = '0';
	chA = getchar();
	printf("%c\n",chA);
	return 0;
}

在这里插入图片描述

将AB送到缓冲区,scanf函数读取缓冲区内容,发现与格式不匹配,不会把值赋给nNum,他并不会丢弃该内容,而是将其放回缓冲区,下一次缓冲区读取仍从这里开始,所以下面chA的值为A

2.scanf的返回值

#include "stdafx.h"
#include <stdio.h>

int main(int argc, char* argv[])
{
	int nNum = 0;
	char chA = '0';

	int nResult = scanf("%d%c",&nNum,&chA);//输入AB

	printf("nNum = %d\n",nNum);
	printf("nResult = %d\n",nResult);
	printf("chA = %c\n",chA);


	scanf("%c",&chA);
	printf("Again chA = %c\n",chA);

	return 0;
}

在这里插入图片描述

我们可以看到当第一个参数读取失败的时候,后面的所有都不会被读取,
当再次尝试为chA赋值的时候 缓冲区还是从指向A,从他开始读取。
而且返回值是0,表示读取成功了0个参数。

2.1

int main(int argc, char* argv[])
{
	int nNum = 0;
	char chA = '0';

	int nResult = scanf("%c%d",&chA,&nNum);//输入AB

	printf("nNum = %d\n",nNum);
	printf("nResult = %d\n",nResult);
	printf("chA = %c\n",chA);

	scanf("%c",&chA);
	printf("Again chA = %c\n",chA);

	return 0;
}

在这里插入图片描述
我们可以看到参数的返回值是1,表示读取成功了一个参数,就是chA = ‘A’;
然后scanf尝试为参数nNum读取时,发现不匹配,将字符B放回缓冲区,并结束该次的scanf,当再次从缓冲区为chA读取数据时,读取的便是字符B了

3空白字符问题(空格 换行 和 Tab)

int main(int argc, char* argv[])
{
	int nNum = 0;
	char chA = '0';

	int nResult = scanf("%c%d",&chA,&nNum);//输入空格AB

	printf("nNum = %d\n",nNum);
	printf("nResult = %d\n",nResult);
	printf("chA = %c\n",chA);


	scanf("%c",&chA);
	printf("Again chA = %c\n",chA);

	return 0;
}

在这里插入图片描述
chA读取的便是空格 第二次才读取到A,%c不会忽略空白字符,别的都会忽略,可以自己去尝试

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值