最近、標準入力で発生するすべての整数を、1 行に 1 つの整数で合計する単純なプログラムが必要でした。入力には、単一のマイナス ('-') 記号を含む未設定の行と、ジャンク文字 (無視される) を含む行が含まれていました。
これは些細なプログラムになるだろうと私は信じていました。しかし、結局のところ、単一のマイナス記号は他の悪い入力として動作しませんでした。通常の非整数入力では、失敗フラグが設定され、不正な入力が入力バッファに残ります。ただし、マイナス (またはプラス) 記号が 1 つあると、失敗フラグが設定されますが、+/- 記号が削除されるため、プログラムは次の (有効な) 整数をスキップします (合計が正しくありません)。
動作を分析するために、小さなテスト プログラム (以下) を作成しました。+/- 記号を使用した上記の動作は、バグまたは機能ですか?
#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;
}