質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.55%

【c++】キャスト時の例外処理対策

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 3,378

SeventhBell

score 12

【質問】(c++今日はじめました)
例えば、string→intの際、intの許容量を超える場合に皆様はどのように対策されていますか?

【求動作】
"intの許容量を超えているため"ということがわかるエラーを出力したいです。
(方法があれば変換前にチェックするでも、例外処理を拾うでも)
初心者ゆえ視野が狭いので、求動作以外にも、私はこうしてますという意見も募集です。

【例外処理例】

string str = 2147483648;  // intの許容量を超える
int i = std::stoi(str);

【やってみたこと】
試しにtry文を書いてみましたが、以下のエラーを吐きcatchできません。
可能なら、エラー内容1の様な情報が得られると嬉しいです。。。

--ソース一部

string str;
cin >> str;
try {
  cout << std::stoi(str) * 2 << endl;
}
  catch (char *e) {> 
  // これだとハンドルできない
  // 引数に...を指定すればそのcatchがハンドルするけど・・・
}

--エラー内容1(VisualStudio2015でデバッグ実行したとき)

${アドレス1} で例外がスローされました (ConsoleApplication1.exe 内): Microsoft C++ の例外: std::out_of_range (メモリの場所 ${アドレス2})

--エラー内容2(デバッグ実行しなかったとき)

Debug Error!
Program:
...${実行ファイルのアドレス}
abort() has been called
(Press Retry to debug the application)

【環境】
OS:windows7 64bit
処理系:Visual C++
IDE:VisualStudio2015

【余談】
例えば、javaのtry文では特定の拡張されたExceptionクラスを指定しなくともとりあえずExceptionを指定しておけば、スタックトレースを吐かせられますが、c++では細かく指定しないとだめなのでしょうか・・・?

稚拙で申し訳ないですが、ここまで、ご覧くださりありがとうございます!
質問方法への指摘等でも結構ですので、ぜひご意見ください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

STLの例外クラスはexceptionクラスから派生させているので、とりあえず
catch(std::exception &e)
としておけばキャッチできます。
例外の種類によって処理を分けたいときは、

try
{
    int a = std::stoi(str);
}
catch(std::invalid_argument &e)
{
    // 文字列が数値でなかったときの処理
}
catch(std::out_of_range &e)
{
    // 数値がintの範囲外だった時の処理
}


このように細かく指定します。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/24 17:37

    なるほど、ちゃんと派生元があるんですね!
    c++のexceptionのリファレンス拝読しました。
    what関数を利用したらそれっぽい内容(stoi argument out of range)が出たのでもうちょっと想定外例外へ対応させる方法も考えてみます。

    キャンセル

0

こんにちは。

たぶん、下記でキャッチできると思います。

catch (std::out_of_range& e)

C++では原則としてキャッチしたい例外を指定します。

catch (...)

とすれば全ての例外をキャッチします。(SEH除く)

後、C++でスタックトレースを吐くためにはかなり面倒なプログラムが必要です。しかし、Visual Studioでブレークを貼っておけば簡単に見れます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/24 17:26

    キャッチできました。
    おっしゃられる面倒なプログラムを実装しない場合は、あらかじめ例外を想定しないとですかね。。。
    VisualStudioも使い始めなのでご教授ありがとうございます。

    キャンセル

  • 2016/05/24 17:45

    C++でスタックトレースを表示させるには、IDEの機能を使うのが最も簡単です。
    例外をcatchしたところにブレークを張っていれば容易に見れます。
    あらかじめ例外を想定しなくても全ての例外をcatchすればそれが可能です。

    JavaとC++では言語の考え方が大きく異なります。
    Javaで簡単にできることがC++では苦労するケースは少なくないです。
    逆に、C++にできることがJavaではどんなに苦労してもできないケースも少なく無いです。
    頑張ってください。

    キャンセル

0

C言語になりますが、strtol関数はerrnoから判定できるようです。
オーバーフロー、アンダーフローのときにERANGEが設定される。
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/strtol.3.html

C++の場合、std::strtolで同様の動きになるようです。

ご提示のstd::stoiでも、内部的にはstrtolを使っているようなので、同様の判定ができるみたいですね。
http://cpprefjp.github.io/reference/string/stoi.html

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/24 17:27

    後程、リンク先を拝見してみます。
    取り急ぎお返事まで。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.55%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る