2012-04-24 61 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倍。