[解決済み] std::invalid_argument エラーはどのように発生しますか?
2022-03-04 02:10:17
質問
の中にオーバーロードされた演算子があります。
Fraction
このクラスは、標準入力から整数の上の整数という形で入力を受け取るように設計されています。
1/2
または
32/4
を初期化し
Fraction
オブジェクトを作成します。うまくいくのですが、エラーが発生して困っています。
// gets input from standard input in the form of (hopefully) int/int
std::istream& operator >>(std::istream& inputStream, Fraction& frac)
{
int inputNumerator, inputDenominator;
char slash;
if ((std::cin >> inputNumerator >> slash >> inputDenominator) && slash == '/')
{
if (inputDenominator == 0)
{
std::cout << "Denominator must not be 0." << std::endl;
throw std::invalid_argument("Denominator must not be 0.");
}
frac.numerator = inputNumerator;
frac.denominator = inputDenominator;
frac.reduce();
}
else
{
throw std::invalid_argument("Invalid syntax.");
}
return inputStream;
}
このようにメソッドを呼び出しています。
Fraction frac(1, 2);
while (true)
{
try {
std::cout << "Enter a fraction in the form int/int: ";
std::cin >> frac;
std::cout << frac;
} catch (std::invalid_argument iaex) {
std::cout << "Caught an error!" << std::endl;
}
}
しかし、エラーが発生するたびに、(以下のように入力します。
garbage
) このため、入力を求めることなく、ループが永遠に続いてしまいます。この原因は何でしょうか?
解決方法は?
プログラムにどのような入力を行っているか教えてくれないので、推測するしかありません。
あなたは、cinがシーケンスとして解析できないものを入力します。
inputNumerator >> slash >> inputDenominator
そのため、フェールステートまたはバッドステートになります。例外は関数の else ブランチでスローされます (メイン関数の catch ブロックで例外のメッセージを表示することでテストできますし、そうする必要があります)。
main のループは続きますが
cin
が悪い状態のままなので、その後の入力がすべて失敗し、同じ例外が何度も投げられることになります。これを防ぐには、エラー処理中にcinの状態をクリアする必要があります。さらに、入力ストリームにパースできない悪い文字がある場合、それらを捨てなければならない、あるいは
ignore
d:
if ((std::cin >> inputNumerator >> slash >> inputDenominator) && slash == '/')
{
/* ... */
}
else
{
std::cin.clear(); // reset the fail flags
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //ignore the bad input until line end
throw std::invalid_argument("Invalid syntax.");
}
関連
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] std::string を const char* または char* に変換する方法
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] PHPのエラーを表示させるにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み] 非静的データメンバの無効な使用