瞭解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