- ベストアンサー
C言語初心者の方の質問について
- C言語初心者の方が、構造体を使用した名簿の作成について質問しています。
- 具体的には、(1)入力判定時に先頭が0入力の場合にエラーを返す方法と記述と、(2)一覧表示時の不正な文字入力によるエラーの原因を知りたいとのことです。
- 解決策を提案する前に、他にも修正が必要な部分があるかを確認する必要があります。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
せっかく fgets→ sscanf としているのだから ・fgetsの戻り値を確認。 行が長すぎて、読み込んだ配列の長さと同じになってないか、逆に読み込み失敗で0になってないかを確認する。 ・bufferの中身を確認。 期待している文字列になっているかを確認する。 例えば、人数を入力するところでは、最初に出てきた文字が0でない数字になっているか、数字がintで収まらないくらい連続していないか確認する。 とすればよいのでは? > {//**確保できた場合はメモリを動的に確保**// > kok = (Meibo *)malloc( sizeof(Meibo) * num); > if(kok==NULL) > { > stop_func(); > } > free(kok); > } これを含めてなのですが、コメントはわざとですか? C言語の従来型のコメントは /* から */までです。改行等も含めて */ が現れるまでがコメントの範囲で、入れ子不可です。逆に1行の途中の部分だけコメントアウトすることもできます printf( "%d", /* 1, */ 2 ) ; /* 2を出力する。 1はコメントアウトされている */ C++で // が追加になりました。これは //から行末までがコメントになります。後に、C言語でも // を行末までのコメントとして使えるようになりました。正し、古いコンパイラ等、対応していないものもあります。 これらを理解しているのならよいのですが、全部 //** **//になっているのを見ると、誤解している気がします。 さて、ここですが、 kokの領域を確保してすぐに解放しています。これでは、まったく意味がありません。 >case 1 ://**登録**// >n = add(data, n,*kok,num); >break; >case 2 : //**一覧**// >n = printall(data, n,*kok,num); >break; しかも、そのあとでkokが使われています。 free関数は、領域の解放はしますが、変数の初期化はしません。よって、この *kok は kokが指すMeibo型(しかし、その領域はすでにfreeで解放済み)ということになります。 現在はたまたま動作しているかもしれませんが、いつ不具合が起ってもおかしくない状態です。 > sscanf(t->from,"%s",&kok); このような行がいくつもありますが ・scanf系関数の"%s"に対応するのは、char *型です。 kokが引数で「Meibo kok」と宣言されているので、 &kokは「Meibo *型」です。scanfはこのような場合、「何もチェックせずchar *型だと勝手に思いこんで処理します」 ・しかも、kokは関数でのローカル変数ですから、returnした段階でメモリから無くなります。参照渡しをしたいのなら、ポインタと実体が逆です。(しかも、先に書いたように、呼び出しがわでは、解放済みの領域を使おうとしています) もう一度落ち着いて設計をやりなおしたほうがよいのではないでしょうか。
お礼
素早い回答有難うございます。 kmee様の助言お陰で、疑問点は無事に解決することが出来ました。 また、他の点もご指摘頂き有難うございます。 コメント行に関しましては、自分の勘違いが原因です。 Cを始めたての頃「//**~**//」でコメントアウトされているものを見て、 その記述が正しいものだと誤解していたようです。 疑問が解決でき、その他の部分も修正が出来たので本当に助かりました。 また何かありましたらご相談するかと思いますが、その時はまた宜しくお願い致します。