名前を入力して、各教科の点数を入力したあと、それを表示するプログラムを作りました。
完成はしたのですが、分からないところがあるので質問させて頂きます。
#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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
数字以外が入力されたらエラー...
-
*をユーザーが入力した数字の数...
-
正負を反転させて出力するプロ...
-
プログラミング初心者です。 Py...
-
至急教えてください!プログラ...
-
cout関数を使っているのですが...
-
scanfでの可変引数
-
scanfが2回使えない・・・?;
-
batプログラム上で文字列を入力...
-
プログラミングの問題です 「金...
-
C言語・標準入力でquitを入力で...
-
java初心者です。入力されたの...
-
日数を計算する方法
-
C++:cinが上手く使えない
-
C言語scanf_sで何故か2回入力に...
-
C言語について
-
入力エラーの処理について。
-
scanf が無視されます
-
Linuxで入力待ちなしkeyread関...
-
Eclipseコンソール表示を、リセ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
double型が正常に認識されてい...
-
プログラミング初心者です。 Py...
-
正負を反転させて出力するプロ...
-
Excel VBAで、Application.Inpu...
-
C言語について。
-
batプログラム上で文字列を入力...
-
*をユーザーが入力した数字の数...
-
cout関数を使っているのですが...
-
漢字のソートについて
-
数字以外が入力されたらエラー...
-
Userformの入力順序をタブオー...
-
ワードで文字を入力する時の変...
-
Linuxで入力待ちなしkeyread関...
-
java初心者です。入力されたの...
-
EDITコントロールで入力できる...
-
Eclipseコンソール表示を、リセ...
-
小数か整数かを判定する方法
-
C言語scanf_sで何故か2回入力に...
-
VB.NETで16進数+16進数や16進...
-
Linuxプログラミングで、キーボ...
おすすめ情報