4

我正在编写一个模板函数,它将检查用户是否分配了答案应该包含的正确数据类型。例如:

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;
}

现在,如果我尝试输入 astring而不是a ,这将起作用integer,但是当我输入 a 时double,它只会分配它的第一个值。例如 5.678 变为 5。

double如果 a被读入a ,我可以在模板函数中做些什么来标记int

4

2 回答 2

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";
    }
  }
}


注意:如果您的编译环境中没有可用的 boost,那么您lexical_cast自己实现起来相当简单。如果您遇到困难,请寻求帮助。


参考:


编辑这是一个经过全面测试的版本,不依赖于 Boost。

#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);
}
于 2012-04-24T16:20:40.600 回答
1

您必须检查 inputstream 的整个输入是否已被消耗。operator>> 在遇到第一个非数字时停止转换为整数。同样,“3.14qwe”将转换为 3.14 双精度。

于 2012-04-24T16:18:57.997 回答