
名前を入力して、各教科の点数を入力したあと、それを表示するプログラムを作りました。
完成はしたのですが、分からないところがあるので質問させて頂きます。
#include <stdio.h>
#include <string.h>
typedef struct {
char name[32];
int kokugo;
int rika;
} siken;
int main() {
siken tensu[5]; // = {"三村",80,45,"大竹",90,85,"松本",75,60,"狩野",100,100,"大江",95,90};
char name[32],point[16],end[6];
int i=0;
do {
printf("名前を入力してください。 : ");
gets(tensu[i].name);
//tensu[i].name = name;
printf("国語 : ");
gets(point);
tensu[i].kokugo = atoi(point);
printf("理科 : ");
gets(point);
tensu[i].rika = atoi(point);
i++;
printf("入力を終わりますか?(YES=0,NO=1) : ");
gets(end);
} while (atoi(end));
i=0;
do {
printf("氏名を入力して下さい。 : ");
gets(name);
while (strcmp(name,tensu[i].name))
i++;
printf("氏名 : %s\n国語 : %d\n理科 : %d\n",tensu[i].name,tensu[i].kokugo,tensu[i].rika);
printf("終わりますか?(YES=0,NO=1) : ");
gets(end);
if (atoi(end)==0)
break;
else if(atoi(end)!=1) {
printf("入力に誤りがあります。もう一度入力して下さい。 : ");
gets(end);
continue;
}
} while (atoi(end));
return 0;
}
このプログラムの
printf("名前を入力してください。 : ");
gets(tensu[i].name);
//tensu[i].name = name;
printf("国語 : ");
gets(point);
tensu[i].kokugo = atoi(point);
printf("理科 : ");
gets(point);
tensu[i].rika = atoi(point);
i++;
printf("入力を終わりますか?(YES=0,NO=1) : ");
gets(end);
の部分で、点数を入力するとき、
scanf("%d",tensu[i].kokugo);
とすると、入力を終了するための入力が飛ばされ、いきなり表示に行きます。(入力を終わりますか?の表示のだけですぐデータ表示のための「氏名を入力してください」が表示される感じです。)
また、この部分の最後のendをint型のj(初期化したものです)に置き換えると「入力を終わりますか?」の入力はできるのですがデータの表示がエラーでできなくなります。
この部分が分からず、もやもやが残っているので質問させていただきました。
長文で申し訳ないです。
回答よろしくお願いいたします。
No.2ベストアンサー
- 回答日時:
まず。
scanfとかgetsとかで「キーボード」から入力、と習ったかと思いますが、正確には違います。
「標準入力」からの入力です。
この標準入力が、端末からの入力に割り当てられているので「キーボードからの入力」に見えるのです。
gets等が実行された時点でキー入力を受け付けるわけではなく、
端末は端末で勝手にキー入力を受け付け送信してくるし、
受け取ったOS側もOS側で、勝手に蓄えておいて、要求されたら要求されただけの文字を送ります。
国語 :
と表示されたから
95リターン
と入力したら、次へ実行が移った
...かのように見えますが、実際は、入力(gets,scanf)が実行された時点で、「溜め込んだ入力が無い」ので「入力が溜るまで待っていた」ためで。
逆に言えば、「溜め込んだ入力」が既にあるのなら、それから読み出され、キーボード入力など待たないのです。
scanf("%d",tensu[i].kokugo); では、数値だけを読み込みます。
数値を入力するとき
95リターン
というようにキーを入力しているかと思います。
scanf("%d"では、数値だけしか読み込まないので、「95」だけが読み込まれ、「リターン」は「溜め込んだ入力」に残ったままになります。
続いてscanf("%d",tensu[i].rika); とすると
あなたは「87リターン」と入力したつもりかもしれませんが、プログラムは
(残っている)リターン87
までを読み込み、その後のリターンは残ったままです。
gets(end)ですが、getsはリターンまでを読み込みます。
ここで、先程のリターンが残っているので、その(残っている)リターンを読み込み、getsの処理は終了です。
この場所でキーボード入力を待つ必要なく、getsを終了させることができます。
・溜め込んだ物を使わないようにする
・scanfを使わない
・endの 入力内容をatoiに頼らずに、ちゃんと値が入っているか確認する
等、対処方法はたくさんあります。
なお、 scanf("%d",tensu[i].kokugo); はコンパイル時にエラーにはなりませんが、実行時に問題になります。
なるほど、scanfとgetsにはそういう違いがあるのですね。
入力が溜まるというのは以前参考書で読みましたが、よく分からなかったので覚えていませんでした…
ありがとうございます。
No.3
- 回答日時:
2点、scanfの使い方に、勘違いがありそうです。
・scanfでは、格納場所のポインタを指定しますので、
scanf("%d",tensu[i].kokugo);
→
scanf("%d",&tensu[i].kokugo);
ですね。
・scanfでは、改行文字が残ること、忘れていませんか?
http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-3
参考URL:http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-3
No.1
- 回答日時:
実行して検証はしていませんが…
>scanf("%d",tensu[i].kokugo);
コールした時、tensu[i].kokugoには何が入っているんでしょうか?
ちゃんと「tensu[i].kokugoのアドレス」を値として入れましたか?
# まぁ普通はそんなコトしませんけど。
# int型の変数に自分自身のアドレスを予め入れておく。なんてことは。
gets()とsacnf()併用すると、入力ストリームの状態どうなるんでしたっけかね?
# http://detail.chiebukuro.yahoo.co.jp/qa/question …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
至急教えてください!プログラ...
-
正負を反転させて出力するプロ...
-
小数か整数かを判定する方法
-
奇数の足し段
-
数字以外が入力されたらエラー...
-
*をユーザーが入力した数字の数...
-
c言語でひらがなのしりとりをで...
-
Excel VBAで、Application.Inpu...
-
Eclipseコンソール表示を、リセ...
-
scanfが2回使えない・・・?;
-
C言語でgetchar();が上手く使え...
-
キーイベントに関してなのです...
-
VisualStudio2019のコードアナ...
-
C言語でscanfが認識されません
-
キーボード入力について初歩的...
-
コンソールアプリの入力時に改...
-
プログラミング初心者です。 Py...
-
linux C言語について ./ファイ...
-
C言語 atoi関数
-
【C言語初心者です】制御文をル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
数字以外が入力されたらエラー...
-
java初心者です。入力されたの...
-
Eclipseコンソール表示を、リセ...
-
正負を反転させて出力するプロ...
-
プログラミング初心者です。 Py...
-
scanfが2回使えない・・・?;
-
Excel VBAで、Application.Inpu...
-
"scanf"でエンターで改行させな...
-
scanf が無視されます
-
C言語 逆ピラミッドの作り方
-
プログラミングの問題です 「金...
-
if文の条件にscanf関数を使うと…?
-
C言語でgetchar();が上手く使え...
-
UWSCで変数をキー入力
-
4桁の数字以外を入力したらエラ...
-
EDITコントロールで入力できる...
-
C言語でつるかめ算をするにはど...
-
Userformの入力順序をタブオー...
-
C言語scanf_sで何故か2回入力に...
おすすめ情報