C++流中的输入无效

bsxbgnwa  于 2023-05-24  发布在  其他
关注(0)|答案(2)|浏览(258)

考虑以下代码,其接受整数输入,然后打印cin流状态:

#include <iostream>  
using namespace std;

int main()
{
    int number;
    cout<<"Enter a number \n";
    cin>>number;
    cout<<cin.rdstate()<<endl;
    return 0;
}

如果输入的数字是“zzzz”,则rdstate返回值4。
如果输入的数字是“10 zzzz”,那么rdstate返回值0,number的值为10,输入流中有“zzzz”。
我的问题是:
1.为什么输入“10 zzzz”不被视为无效输入(至少应该设置一个失败位)。
2.什么是检测和处理这种情况的优雅解决方案。
Thanks!

g6baxovj

g6baxovj1#

首先,我想问一下你在做什么:

cout<<cin.rdstate()<<endl;

阅读本页以正确使用rdstate()http://www.cplusplus.com/reference/iostream/ios/rdstate/
第二:检查输入是字符串类型还是整数类型,你可能想添加一些额外的东西,它会将输入字符串转换为整数数据,并在输入无效输入时响应错误消息。
这将帮助你。

int main() {

 string input = "";

 // How to get a string/sentence with spaces
 cout << "Please enter a valid sentence (with spaces):\n>";
 getline(cin, input);
 cout << "You entered: " << input << endl << endl;

 // How to get a number.
 int myNumber = 0;

 while (true) {
   cout << "Please enter a valid number: ";
   getline(cin, input);

   // This code converts from string to number safely.
   stringstream myStream(input);
   if (myStream >> myNumber)
     break;
   cout << "Invalid number, please try again" << endl;
 }
 cout << "You entered: " << myNumber << endl << endl;

 // How to get a single char.
 char myChar  = {0};

 while (true) {
   cout << "Please enter 1 char: ";
   getline(cin, input);

   if (input.length() == 1) {
     myChar = input[0];
     break;
   }

   cout << "Invalid character, please try again" << endl;
 }
 cout << "You entered: " << myChar << endl << endl;

 cout << "All done. And without using the >> operator" << endl;

 return 0;
}
o0lyfsai

o0lyfsai2#

如果输入的数字是“zzzz”,则rdstate返回值4。如果输入的数字是“10 zzzz”,那么rdstate返回值0,number的值为10,输入流中有“zzzz”。
为了理解为什么会发生这些,我们需要理解提取操作符(操作符>>)是如何工作的。这里有几个很好的链接开始:
std::cin and handling invalid input
std::istream::operator>>
我们可以在以下几个地方深入挖掘:
operator>>(std::basic_istream)
std::basic_istream<CharT,Traits>::operator>>
std::num_get<CharT,InputIt>::get, std::num_get<CharT,InputIt>::do_get
简单地说,当写入算术类型时,只要字符序列可以准确地解释为该类型的值,就会逐个字符地分析输入。当不再可能这样做时,解析停止,并且使用直到该点为止已经获得的有效值。
“zzzz”表示无效值,而“10 zzzz”允许解析10
就解决方案而言,可以改进dennis基于字符串流的answer,以处理尾随字符,如here所示。如果有尾随字符,!myStream.eof()将计算为true。
此外,除了使用字符串流之外,还有其他选项。例如,strtolstd::stoi
此外,在此上下文中使用输入字符串流而不是字符串流会更好。参见here

相关问题