这两天被人问到一个小题,题目是是这样的:
输入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