了解C中scanf单整数读取,C++中cin.peek()用法

这两天被人问到一个小题,题目是是这样的:

输入1个8位以上的数,将个位上的偶数取出,并按照原来从高位到低位相反的顺序组成一个新数,并输出这个新数:

输入:27638496
输出:64862

水题当然是水题,用char类型数组很快就能写出来,但是想用读取整数的方式能不能写出来呢?

我想到了之前用到的一个逐个读取整数型的scanf("%1d", &num)方法;

// 失败
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int num[100];
    int need[100];
    int j = 0;
    char ch;
    for (int i = 0; scanf("%1d", &num[i]); i++)
    {
    	if (num[i] % 2 == 0)
    		need[j++] = num[i];
    }
    for (int k = j-1; k>=0; k--)
    {
    	printf("%d", need[k]);
    }
    system("pause");
}

但其实这里是有问题的,scanf()函数每次以"1d"方式读取不管是字符还是数组时,读取到的都将是0到9内的数(’\n’的ASCII值为10, 空格space的为32),就算遇到’\n’这样原本是结束字符的也不能终止读入,本方法解决失败

不放弃的我又想到了用getchar()函数探测下一个字符是不是’\n’来判断终止条件,但是这种情况只适用于每两个字符间有一个空格(或其他什么无关紧要的字符),结尾无空格的情况。
例1 2#3%4(结尾无空格及其它字符)
此时,没到结尾时getchar()用于吸收空格,结尾时getchar()判断’\n’。

// 只适用于每两个字符间有一个无关字符,结尾无无关字符的情况
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int num[100];
	int need[100];
	int j = 0;
	char ch;
	for (int i = 0; scanf("%1d", &num[i]) && (ch = getchar()!= '\n'); i++)
	{
		if (num[i] % 2 == 0)
			need[j++] = num[i];
	}
	for (int k = j-1; k>=0; k--)
	{
		printf("%d", need[k]);
	}
	system("pause");
}

再增加一种条件,如果我们知道了数字串的长度len,scanf("%1d", &num)方式确实也可以用:

// 适用于已知数字串长度len的情况
// 若len = 6
int j = 0;   // 这里初始化为0是因为如果每一位都是奇数,后面print时会报错
for (int i = 0; i<len; i++)    // 输入:259840
{
	scanf("%1d", &num[i]);
	if (num[i]%2 == 0)
		need[j++] = num[i];
}
for (int i = j-1; i>=0; i--)
	printf("%d", need[i]);     // 输出:0482

这时,如何完美解决问题呢,就用我们C++的cin.peek()函数了,顾名思义,就像一个窥探函数。(终于成功了!)

其功能是从输入流中读取一个字符 但该字符并未从输入流中删除。其返回值是一个char型的字符,其返回值是指针指向的当前字符,但它只是观测指针,停留在当前位置并不后移;如果要访问的字符是文件结束符,则函数值是EOF(-1) ;更直白一点的说法,就像是偷看了一下当前指针指向的字符(或者说不管是数字还是字符,都当做字符看了一眼,没做什么实际行动,不影响后面其他函数读取它的方式)。

若把输入流比作一个 栈类 那么这里的peek函数就相当于栈的成员函数front(或者说像取top),而cin.get()则相当于栈的成员函数pop(直接删除掉top元素)

// 成功!
#include<iostream>
using namespace std;
int main()
{
	int num[100];    // 能读取100位数字的数组
	int need[100];   // 存储掉数字是偶数的位
	int j = 0;
	scanf("%1d", &num[0]);
	for (int i = 1; cin.peek()!='\n'; i++)  // 看一眼当前下标(指针)i 指向的"字符"是不是'\n',是就终止
	{
		scanf("%1d", &num[i]);
		if (num[i]%2 == 0)
			need[j++] = num[i];   // 提取偶数位数字
	}
	for (int k = j-1; k>=0; k--)
	{
		printf("%d", need[k]);
	}
	
	system("pause");
}

那么在C语言没有这样一个库函数可以实现C++的cin.peek()函数,不过可以自定义函数实现类似的功能。
有兴趣请参考 https://blog.csdn.net/cFarmerReally/article/details/78474979

猜你喜欢

转载自blog.csdn.net/weixin_43469047/article/details/83617670