2012-04-24 69 views
4

我正在寫一個模板函數,將檢查用戶是否分配到正確的數據類型,答案應該在例如:浮點數據意外成功的istream的輸入到一個整數

int main(){ 

    int E; 
    cout<<"Enter an integer: "<<endl; 
    E = clear_and_read<int>(cin); 
    cout<<E<<endl; 

} 

其中函數clear_and_read被定義爲:

template <class T> T clear_and_read(istream& inputstream){ 
    cin.sync();//removes anything still in cin stream 
    cin.clear(); 
    T input; 
    inputstream>>input;  
    while(inputstream.fail()){ 
     cout<<endl<<"Please ensure you are inputting correct data type. Suggested data type: "<< typeid(input).name() <<"."<<endl; 
     cin.sync(); 
     cin.clear(); 
     inputstream>>input; 
    } 
    return input; 
} 

現在這個作品,如果我嘗試輸入string而不是integer,但是當我進入一個double它只是賦予它的第一個值。例如5.678變爲5.

我能在模板函數內部做些什麼來標記double正被讀入int

+0

'typeid的(輸入)'這只是要求你能想到的更多的麻煩。 – orlp 2012-04-24 16:19:05

+0

我認爲這不會太有害,因爲我只是將它用作幫助用戶的建議 - 不在代碼中進行比較? 另外:感謝編輯sixlettervariables。 – QuantumO 2012-04-24 16:22:07

回答

3

我會嘗試一個稍微不同的需要比你有。具體而言,我不會試圖修改輸入流的錯誤狀態:

// Untested 
template <class T> T clear_and_read(istream& inputstream) { 
    std::string inputString; 
    while(1) { 
    try { 

     // Grab one maximally-sized whitespace-delimited chunk of input 
     inputstream >> inputString; 

     // Note: lexical_cast throws if there are any extraneous characters. 
     return boost::lexical_cast<T>(inputString); 

    } catch (boost::bad_cast&) { 
     std::cout << "\nPlease ensure you are inputting correct data type. Suggested data type: "<< typeid(input).name() <<".\n"; 
    } 
    } 
} 


注意:如果沒有可用的提升你的編譯環境, lexical_cast是相當容易實現自己。如果您遇到困難,請尋求幫助。


參考文獻:


編輯這裏是一個完全測試版,即不依賴於加速。

#include <exception> 
#include <sstream> 
#include <string> 
#include <iostream> 
#include <typeinfo> 

template <class T> T clear_and_read(std::istream& inputstream) { 
    std::string inputString; 
    while(inputstream) { 
     // Grab one maximally-sized whitespace-delimited chunk of input 
     inputstream >> inputString; 
     std::istringstream itemstream(inputString); 

     // Convert it: 
     T t; 
     itemstream >> t; 

     // See if conversion worked and consumed everything 
     if(itemstream && (itemstream.get() == EOF)) { 
     // SUCCESS 
     return t; 
     } 

     // oops 
     std::cout << "\nPlease ensure you are inputting correct data type. Suggested data type: "<< typeid(T).name() <<".\n"; 
    } 
    std::cout << "What to do with EOF?\n"; 
    return T(); 
} 

int main() { 
    clear_and_read<int>(std::cin); 
    clear_and_read<double>(std::cin); 
} 
+0

增強外部庫嗎? - 不幸的是,我必須堅持使用標準C++編寫我正在編寫的代碼。 – QuantumO 2012-04-24 16:31:34

+0

沒關係 - 在標準C++中'boost :: lexical_cast'實現你自己是微不足道的。詢問你是否需要這樣做。 – 2012-04-24 17:31:48

+0

哇。輝煌的答案!謝謝。是否可以改變這個代碼來接受白色間隔的字符串(例如「John Smith」)? – QuantumO 2012-04-24 18:41:05

1

您必須檢查inputstream的整個輸入是否已被消耗。運算符>>遇到第一個非數字時停止轉換爲整數。同樣,「3.14qwe」將轉換爲3.14倍。