浮点数据意外地成功将 istream 输入为整数

Floating point data unexpectedly succeeds on istream input into an integer

本文关键字:istream 输入 整数 成功 数据 意外      更新时间:2023-10-16

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

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

我会尝试与你略有不同的方法。具体来说,我不会尝试修改输入流的错误状态:

// 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是相当简单的。如果您遇到困难,请寻求帮助。

<小时 />引用:

  • http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast.html

<小时 />编辑这是一个经过全面测试的版本,不依赖于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);
}

您必须检查输入流的整个输入是否已被消耗。 运算符>>每当遇到第一个非数字时都会停止转换为整数。同样,"3.14qwe"将转换为 3.14 双倍。