scanf函数与输入缓冲区

本文链接:http://www.cnblogs.com/xxNote/p/4008668.html

今天看书的时候遇到scanf函数与缓冲区的问题,产生了一些猜想即:应该有一个指针来记录缓冲区中读取到了哪个字符。书上说scanf函数在%d、%f、%lf等数值控制字符时会跳过缓冲区中的空格、回车、还有制表符(TAB),若遇到+*等字符则会失败而不再跳过;而scanf函数在%c或%s控制字符时则会取走缓冲区的所有字符。此时产生一个疑问,这里的跳过说的是直接改变前面猜想中的那个指针的值还是仅仅跳过而不改变指针的值下一次读取还从指针指向的位置读取呢?

就写了下面的小程序,用这两个输入测试了一下,程序如下:

#include <stdio.h>

int main(void)
{
	int ch[5];
	//第一次输入:
	//				1++2*3 
	//第二次输入:
	//				1【空格】【空格】2【空格】3
	//两次输入将会得到不同的结果,这是因为scanf函数在%d、%f、%lf等数
	//值控制字符时会跳过缓冲区中的空格、回车、还有制表符(TAB)
	//而scanf函数在%c或%s控制字符时则会取走缓冲区的所有字符,
	//由此猜也可以猜想到应该有一个指针来记录缓冲区中读取到了哪个字符

	scanf("%d", &ch[0]);
	scanf("%d", &ch[1]);
	ch[2] = getchar();
	ch[3] = getchar();
	printf("ch[0]:%0x
", ch[0]);
	printf("ch[1]:%0x
", ch[1]);
	printf("ch[2]:%c
", ch[2]);
	printf("ch[3]:%c
", ch[3]);
	printf("%d ch[4]:%d
", scanf("%d", &ch[4]), ch[4]);
	printf("%d
", ch[4]);
	//当输入是“1【空格】【空格】2【空格】3”的时候,
	//由23行和24行的输出结果的差异反映了一个事实即:
	//__cdecl调用约定是从右到左将参数依次压入栈中
	//23行程序传递ch[4]的时候,ch[4]还没有初始化,而
	//本程序是在Debug模式下编译运行的所以打印出的值是:cccccccc
	//在10进制下这个数值是-858993460(以后见到这个数值的时候检查一下是否忘记初始化)
	//23行执行后ch[4]被赋值为我们输入的值,所以24行输出了我们预料中的值
	return 0;
}

两种输入的运行结果分别如下:

1++2*3的运行结果:

1【空格】【空格】2【空格】3的运行结果:

后面的这个输出结果比较有意思,也就是23行和24行的ch[4]的值的输出结果的差异是由于__cdecl调用约定是从右到左将参数依次压入栈中。

原文地址:https://www.cnblogs.com/xxNote/p/4008668.html