C ++:Linux和Windows之间的cin帮助

我有一个我写的Win32控制台程序,它工作正常。 该程序从用户获取input并执行一些计算并显示输出 – 标准的东西。 为了好玩,我试图让程序在我的Fedora盒子上工作,但是当用户input与我的variablestypes不匹配的东西时,我遇到了清除cin的问题。 这是有问题的代码:

void CParameter::setPrincipal() { double principal = 0.0; cout << endl << "Please enter the loan principal: "; cin >> principal; while(principal <= 0) { if (cin.fail()) { cin.clear(); cin.ignore(INT_MAX, '\n'); } else { cout << endl << "Plese enter a number greater than zero. Please try again." << endl; cin >> principal; } } m_Parameter = principal; 

}

此代码在Windows中工作。 例如,如果用户试图inputchar数据types(相对于double),那么程序会通知用户错误,重置cin,并允许用户input另一个机会来input有效值。

当我把这段代码移到Fedora的时候,编译好了。 当我运行程序并input无效数据types时,while循环从不中断,以允许用户更改input。

我的问题是 如何在Fedora环境中input无效数据时清除cin? 另外,我应该如何编写这个代码才能在两种环境(Windows和Linux)中工作?

在此先感谢您的帮助!

我认为使用格式化输入来读取用户响应是个不错的主意。 我会使用getline – 如下所示:

 #include <iostream> #include <string> #include <sstream> using namespace std; template <typename T> bool Read( T & t, istream & is ) { string s; if ( ! getline( is, s ) ) { return false; } else { istringstream ss( s ); return ss >> t; } } int main() { while(1) { double d; if ( ! Read( d, cin ) ) { cout << "invalid\n"; } else { cout << "You entered " << d << "\n"; } } } 

在Windows上工作 – 我没有我的Linux机箱在此刻打开。

我认为cin.ignorecin上设置了失败的标志,这使得它永远停留在最上面的if语句中。 INT_MAX是一个非常大的数字 – 你确定它允许在所有平台上cin.ignore?

我会切换到使用getline读取输入,然后解析一个stringstream

 double principal = 0; string temp; while (principal <= 0) { getline(cin, temp); istringstream converter(temp); if (!(converter>>principal) || !(converter>>std::ws).eof() || principal <= 0) { cout << "Try again" << endl; principal = 0; } } 

我同意安德斯·亚伯(Anders Abel)和夏布(Johannes Schaub) 我想也可能不能保证在出现错误的情况下不改变主体,所以你可以考虑添加principal=0.0; 在周期的开始。

顺便说一下,为了执行这种工作,我通常使用这个模板函数:

 template<typename InType> void AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString, InType & Result) { do { Os<<Prompt.c_str(); if(Is.fail()) { Is.clear(); Is.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } Is>>Result; if(Is.fail()) Os<<FailString.c_str(); } while(Is.fail()); } template<typename InType> InType AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString) { InType temp; AcquireInput(Os,Is,Prompt,FailString,temp); return temp; } 

如果你想避免复制,第一个重载可能是首选,第二个可能更适合内置类型。 用法示例:

 //1st overload double aDouble; AcquireInput(cout,cin,"Please insert an integer: ","Invalid value.\n",aDouble); //2nd overload (more convenient, in this case and in general with POD) double aDouble=AcquireInput(cout,cin, "Please insert an integer: ","Invalid value.\n"); 

在你的情况下,你可以用这种方式改变你的代码:

 double principal=0.0; const char * errMsg="Plese enter a number greater than zero. Please try again.\n"; while(principal<=0.0) { principal=0.0; principal=AcquireInput(cout,cin,"Please enter the loan principal: ",errMsg); if(principal<=0.0) cout<<errMsg; }