最近我需要一个简单的程序来对标准输入上出现的所有整数求和,每行一个整数。输入碰巧包含一些未设置的行,其中包含一个减号 ('-') 符号,以及一些带有垃圾字符的行(将被忽略)。
我相信这将是一个微不足道的程序。但事实证明,单个减号并没有表现得像其他错误输入。在正常的非整数输入上,设置失败标志并且错误输入保留在输入缓冲区中。但是对于单个减号(或加号),设置了失败标志,但删除了 +/- 号,导致程序跳过下一个(有效)整数(导致错误的总和)。
我写了一个小测试程序(如下)来分析行为。上述带有 +/- 符号的行为是错误还是功能?
#include <iostream>
using namespace std;
int main()
{
string s;
int n;
while (true)
{
n = -4711;
cin >> n;
cerr << (cin.bad() ? "ERROR: badbit is set\n" : "");
cerr << (cin.fail() ? "ERROR: failbit is set\n" : "");
cerr << (cin.eof() ? "ERROR: eofbit is set\n" : "");
if ( cin.bad() || cin.eof() )
break;
if ( cin.fail() )
{
cin.clear();
cin >> s;
cerr << "ERROR: ignored string '" << s
<< "' (integer is '" << n << "')" << endl;
}
else
{
cout << "OK: read integer '" << n << "'" << endl;
}
}
return 0;
}
运行程序(输入:“1 asdf 2 - 3 + 4 qwer 5”):
~ $ ./a.out
1 asdf 2 - 3 + 4 qwer 5
OK: read integer '1'
ERROR: failbit is set
ERROR: ignored string 'asdf' (integer is '0')
OK: read integer '2'
ERROR: failbit is set
ERROR: ignored string '3' (integer is '0')
ERROR: failbit is set
ERROR: ignored string '4' (integer is '0')
ERROR: failbit is set
ERROR: ignored string 'qwer' (integer is '0')
OK: read integer '5'
(我已经通过读取字符串解决了我最初的问题,并使用带有异常的 C++11 stoi 来识别错误的输入。)
编辑:如果有人对我原来的问题的解决方案感兴趣:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int sum = 0;
string n;
while ( cin >> n )
{
try {
sum += stoi(n);
cout << n << endl;
}
catch (exception& e)
{
cerr << e.what() << " ERROR: '" << n << "' is not a number." << endl;
}
}
cout << sum << endl;
return 0;
}