1. 程式人生 > >C/C++中的結束輸入條件判斷 (scanf、EOF、getchar()、cin.get()、getline)

C/C++中的結束輸入條件判斷 (scanf、EOF、getchar()、cin.get()、getline)

本教程主要適用於一些程式比賽或大公司機試中的輸入資料的處理,總的來說,可以分為以下三種情況:

情況一:輸入的測試樣例有多組,每組需要相同邏輯的處理;

處理方案:在C語言中可利用scanf("%d",&n)!=EOF,在C++中可以使用while(cin>>n)。

例如:計算兩數之和,輸入可能有多組樣例。

#include <iostream>
using namespace std;

int main(){
    int a,b;
    while(scanf("%d %d",&a,&b)!=EOF){
        cout<<a+b<<endl;
    }
    return 0;
}

或者使用C++的寫法:

#include <iostream>
using namespace std;

int main(){
    int a,b;
    while(cin>>a>>b){
        cout<<a+b<<endl;
    }
    return 0;
}

結果是這樣的:

解釋一下C語言中的scanf()函式,它的返回值可以分為以下幾種情況:一般是返回按照指定格式輸入變數的個數,但若遇到錯誤或者遇到end of file,則返回-1. 而恰好EOF是一個系統預定義的一個常量,它的值是-1。這樣也就解釋清楚了,下面驗證一下:

#include <iostream>
using namespace std;

int main(){
    int a,b;
    cout<<"EOF的值為:"<<EOF<<endl;
    int temp1 = scanf("%d",&a);
    cout<<"此時scanf()函式的返回值:"<<temp1<<endl;
    int temp2 = scanf("%d %d",&a,&b);
    cout<<"此時scanf()函式的返回值:"<<temp2<<endl;
    int temp3 = scanf("%d %d",&a,&b);
    cout<<"此時scanf()函式的返回值:"<<temp3<<endl;
    return 0;
}

情況二:當輸入一個數組時,無法確定其長度時,通過輸入換行還結束輸入。

處理方案:在C語言中可利用getchar(),在C++中可以使用cin.get()。兩者都表示從stdio流中讀一個字元,也就是說從控制檯中讀取下一個字元。

例如:輸入一個整型陣列,再按序輸出,注意沒有給定輸入陣列的長度。

#include <iostream>
using namespace std;

int main(){
    int A[100];
    int i = 0;
    for(i=0;;i++){
        cin>>A[i];
        if(getchar()=='\n')
            break;
    }
    for(int j=0;j<i+1;j++)
        cout<<A[j]<<endl;
    return 0;
}

或者簡寫成:

#include <iostream>
using namespace std;

int main(){
    int A[100];
    int i = 0;
    while(cin>>A[i] && getchar()!='\n'){
        i += 1;
    }
    for(int j=0;j<i+1;j++)
        cout<<A[j]<<endl;
    return 0;
}

C++的寫法:

#include <iostream>
using namespace std;

int main(){
    int A[100];
    int i = 0;
    while(cin>>A[i] && cin.get()!='\n'){
        i += 1;
    }
    for(int j=0;j<i+1;j++)
        cout<<A[j]<<endl;
    return 0;
}

本題若是沒有給定陣列長度的上界,也就是陣列不知道開多大,因為可能有100個數,1000個數,10000個數的輸入。我們可以利用vector動態陣列來實現:

#include <iostream>
#include <vector>
using namespace std;

int main(){
    vector<int> vec;
    int i = 0;
    int x;
    for(i=0;;i++){
        cin>>x;
        vec.push_back(x);
        if(cin.get()=='\n')
            break;
    }
    for(int j=0;j<i+1;j++)
        cout<<vec[j]<<endl;
    return 0;
}

情況三:處理字串的情況,在C++中因為支援了string型別,所以大大簡化了關於字串的一系列操作;

方案:處理連續非空的字串,我們只要輸入即可cin>>str;對於字串中含有空格的情況,使用getline函式實現

#include <iostream>
using namespace std;

int main(){
    string str;
    cin>>str;
    cout<<str<<endl;
    return 0;
}

#include <iostream>
using namespace std;

int main(){
    string str;
    getline(cin,str);
    cout<<str<<endl;
    return 0;
}

這裡要注意的是,如果在一個程式中先使用cin>>str輸入,然後再使用getline函式的話,需要再cin>>str之後使用cin.get()處理回車才行,也就是把回車當做cin.get()的輸入,畢竟使用者確實輸入了一個回車。

#include <iostream>
using namespace std;

int main(){
    string str;
    cin>>str;
    cout<<str<<endl;
    cin.get();
    getline(cin,str);
    cout<<str<<endl;
    return 0;
}

希望本篇部落格可以讓大家少走很多彎路。