- ベストアンサー
プログラムが動かない
電卓のプログラムを作ろうと以下のようなソースを書いたんですが、コンパイルするときに 警告 W8070 denntaku.c 38: 関数は値を返すべき(関数 main) というエラーが出てしまいます。 原因はなんなんでしょうか? (ソース) #include <stdio.h> main() { int val1,val2,ans; char p,m,k,w,how; printf("val1? \n"); scanf("%d", &val1); printf("how? \n"); scanf("%c", &how); printf("val2? \n"); scanf("%d", &val2); switch(how) { case 'p': ans=val1+val2; printf("%d+%d=%d \n", val1,val2,ans); break; case 'm': ans=val1-val2; printf("%d-%d=%d \n", val1,val2,ans); break; case 'k': ans=val1*val2; printf("%d*%d=%d \n", val1,val2,ans); break; case 'w': ans=val1/val2; printf("%d/%d=%d \n", val1,val2,ans); break; } }
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
linux上で実際にコンパイルして実験しましたが、 printf("how? \n"); scanf("%c", &how); を複数文字読み込みにして printf("how? \n"); scanf("%s", &how); にすればうまく行きました。1文字だけ読み込みにした場合に 前の入力のせいでおかしくなるようです。 %sでの動作はとりあえず確認できています。 fflush(stdin)は試しましたがうまくいきませんでした。 何故でしょう?
その他の回答 (5)
- jacta
- ベストアンサー率26% (845/3158)
順番に問題を片付けていきましょう。 まず、 > void mainにしない場合はmainの最後にreturn 0;をつける、ということなんですよね? についてですが、先に挙げた例外事例を除いて、void mainにはできません。main関数は必ずint mainにしてください。 次に、scanfの件ですが、 scanf("%d%*[^\n]%*c", &val1); のようにすれば、おそらく問題は解決するはずです。 あるいは、getsやfgetsで1行単位で読み込んでから、sscanfやstrtolで整数値に変換してください。 fflushにstdinのような入力ストリームを指定した場合の動作は未定義です。
お礼
回答ありがとうございます。 >必ずint mainにしてください。 そーだったんですか。誤解していました。 また、scanf("%d%*[^\n]%*c", &val1);のようにすると、%cのままでもうまく実行することが出来ました。 勉強不足で記号の意味が分からないのが残念ですが・・・。 最後に、回答してくださった3人の方々へ 2度も回答していただき本当にどうもありがとうございました。 僕も皆様のようになれるようにがんばって勉強していこうと思います。
- ymmasayan
- ベストアンサー率30% (2593/8599)
>> printf文は最後に1つにまとめたほうが > これは具体的にはどうしたらいいんでしょうか? 始めたばかりならとりあえずは今のままでいいでしょう。 > 実行してみると、val1を入力後に「how?val2?」 > と2つが同時に出てきてしまって、howを入力することができません。 実は厄介です。 5Enterと入力すると2つ目のscanfでEnterを読んでしまって勝手に 3つ目のscanfに行ってしまうのです。 とりあえずの対策としては scanf fflish(stdin) をセットにして使えば入力バッファーのごみがクリアーされ正常になるはずです。 但し、あくまでも邪道らしいですが。
お礼
回答ありがとうございます。 なるほど、2つ目でENTERを読んでしまったのが原因だったのですね。 fflish(stdin)なんですが、プロトタイプ宣言がない、みたいなエラーが出てしまいました。 まだ僕にはハードルが高かったようです。 ですが、%cを%sに変更したところ、うまく実行することが出来ました。
- jacta
- ベストアンサー率26% (845/3158)
まず、mainからの返却値は原則としてintでなければなりません。そして、returnによって整数値を返さなければなりません。 「原則として」と書いたのは、若干の例外があるからです。 ・C99の場合、int以外の返却値型を持つ処理系定義の形式であっても構わないことになっています。 ・フリースタンディング環境(組み込み機器のようなOSがない環境)では、プログラム開始処理の関数の名前と型は処理系定義になります。 また、C++の場合、main関数からのreturnが省略されると、関数の末尾でreturn 0;を書いたのと同じ意味になります。 上記を踏まえた上で、(標準規格に準拠した)C++であれば、今回の警告は大きなお世話なので、無視しても問題ありません。 Cの場合、main関数の最後にreturn 0;を追加すべきです。警告メッセージから見て、C99の可能性はまずありませんし、printfなどを使っていることから見て、フリースタンディング環境でもなさそうですので、return 0;を追加する以外の選択肢はありません。
お礼
回答ありがとうございます。 えーと、まだ初心者なのでよくは分からないんですが、void mainにしない場合はmainの最後にreturn 0;をつける、ということなんですよね? それと少し質問の趣旨が変わってしまうんですが、 このプログラムではval1を入力してから、足すか引くかなどの処理(how)を入力し、最後にval2を入力すると計算結果が出る、という流れにしたかったんです。 しかし実行してみると、val1を入力後に「how?val2?」 と2つが同時に出てきてしまって、howを入力することができません。 当然その後の答えもでてきません。 どうしたら解決できるんでしょうか?
- ymmasayan
- ベストアンサー率30% (2593/8599)
No.1の方の言われる通りです。 この場合戻り値が不要でしょうから void main()とすればいいですね。 余計なお節介ですが、printf文は最後に1つにまとめたほうが判りやすいような。
お礼
回答ありがとうございます。 void mainに変えたところ、コンパイルは無事行うことができました。 >printf文は最後に1つにまとめたほうが これは具体的にはどうしたらいいんでしょうか? C言語の勉強は昨日はじめたばかりなもので・・・。 それと少し質問の趣旨が変わってしまうんですが、 このプログラムではval1を入力してから、足すか引くかなどの処理(how)を入力し、最後にval2を入力すると計算結果が出る、という流れにしたかったんです。 しかし実行してみると、val1を入力後に「how?val2?」 と2つが同時に出てきてしまって、howを入力することができません。 当然その後の答えもでてきません。 どうしたら解決できるんでしょうか?
ただのmain()としている部分がコンパイラによって int main()と解釈されているのだと思います。 int mainかvoid mainかに関して下記を参照ください。 http://www9.plala.or.jp/sgwr-t/c/sec11.html
お礼
回答ありがとうございます。 参考になりました。 void mainに変えたところ、コンパイルは無事行うことができました。 少し質問の趣旨が変わってしまうんですが、 このプログラムではval1を入力してから、足すか引くかなどの処理(how)を入力し、最後にval2を入力すると計算結果が出る、という流れにしたかったんです。 しかし実行してみると、val1を入力後に「how?val2?」 と2つが同時に出てきてしまって、howを入力することができません。 当然その後の答えもでてきません。 どうしたら解決できるんでしょうか?
お礼
回答ありがとうございます。 %sに変更したところ、きちんと実行することができました。