Q&A (電気電子)

例外がスローされましたを解決する方法

どうもメガネです。

私はプログラムは初心者レベルの技量しかありませんが、

いろいろやっていたら「例外がスローされました」と表示された際に解決する方法が分かってきたので備忘録としてメモしておきます。

「例外がスローされました」と出た際にメモをとる

プログラムの練習中にバグが出るのはわかるし、

コンパイル時のエラーとしてデバッグウィンドウに表示してくれると原因がすぐわかります。

ですが「例外がスローされました」とでるとどこが間違っているか全然わかりません、

バグなのか、自分のコードのエラーなのか、オーバーフローなのか。

そこで上記の画像のように「例外がスローされました」という旨のエラーが出た際に

問題があったプログラムとその関数についてメモを取ることにしました。

私が練習で使うようなプログラムはそこまで難しいものはないので、エラーが出ても数十分あればなんとか対処できるものがほとんどです。

ですがここであえて「別の書き方」を選ばずにその関数を使ってなるべく分を変えずに修正するということを続けてみました。

もちろん修正できたメモもです。

結果

毎度毎度エラーが出るわけではないが、出たたびにメモっておいたところ、

だんだん傾向が分かってきたんですよね。

上記のエラーの例だと、文字列系のバグなんだと分かりました。

やっぱりコンパイルしたときのエラーってエディタのアップデートなどでエディタ本体に問題があることってほとんどないので

大抵自分に問題があるんですよねぇ、、、、、

メモして傾向を観察してみたらやっぱりって感じでした。

例えば上記の画像で出たエラーだと、特に明記はされてないんですが、

「fscanf_s関数に与える引数の数が違う」というバグなんですよね。

引数が全部int型やdouble型のような数字ならば引数の数はこれであっているんですけど、

これが文字型配列の場合は引数に"文字列の大きさ"を追加しなければならないようです。
よってこの場合に限っては引数の個数が変わってくるんですよね。

備考

よくわからないことだらけなんですが、

C++環境でコンパイルする際にはCで使えたscanfやfscanfを"_s"を付けたものに直さなきゃならないんですよね。

なんだか危険だか何だかという理由で。

そしてC++では文字列系を引数にする場合は引数を一つ追加して“大きさ”を加えてあげないといけないんですよね。

なのですが、「文字列の大きさ」という引数を入力し忘れていてもコンパイルは通ってしまうということが分かりました。、、、(今回の学びです。。)

例えばfscaf_sに数字系の引数だけの場合は

fscanf_s(fp, "%s%lf%lf", name, &height, &weight)

という書き方で正しく、コンパイルが通るのですが、文字列として表示したい%sに割当たってる引数の
「name」は「例外がスローされました」と表示されます。

以下のように引数に文字列の大きさ「100」という引数を新しく追加すれば正しく動作します。

fscanf_s(fp, "%s%lf%lf", name,100, &height, &weight)

そーいえばscanf_sでも似たように文字列の大きさ与えなければだめでしたね、、、

せっかくVisual Studio優秀なんだからこれもコンパイル時のエラーとして出せばいいのに、、、
いや、正確にはエラーではないから例外、なのか?....ということなんですかね。

まとめ

ちょっとグダグダと述べてしまいましたが、

①「例外がスローされました」には大抵の場合原因がちゃんとあり、

②ノート等にメモったりして傾向をつかむと、

③次に例外が「スローされました」と表示された原因を知って解決できる。

というわけですね。

まぁ、学習の基本中の基本の型ではありますが、ついつい忘れてしまいます、、、。

今回の場合に限っては、

とりあえずCで使えたけどC++では使えない"fscanf"や"scanf"を"fscanf_s"、"scanf_s"のように「_s」を使って使う場合は、文字列の大きさを示す引数を追加し忘れない!ということですねぇ。

何事も観察がとても大事ですね。(^▽^)/

覚えておこうと思います。

追記:こんなことを繰り返したり記憶していたら、最近はほとんど「例外がスローされました」が 
   出なくなりました。やったぜ。

それでは。

-Q&A (電気電子)
-,