みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

MacでC言語を勉強しています

最近C言語に興味を持って
趣味程度に、ハーバート・シルトさん著の「独習C」を、
Xcodeを使ってCが使える感じにして、
プログラミングを打って、ビルドして、コンソールで結果を見て、ふむふむ、ってやっていたのですが、
第8章の総合理解度チェックの問題で、
「簡単な図書カードカタログプログラムを作成してください。
~省略~
ユーザーが「1.入力」を選んだ場合には、書名、著者名、出版社を繰り返し入力させます。書名として空白行が入力されるまで、これを続けます。~~省略~~」
ということになっていまして、この入力を選んだ場合がうまくいきません・・・。作り途中のプログラムですが・・・

/*8の総合理解度チェック2test1「メニュー関数の完成」*/

#include <stdio.h>
#include <string.h>

#define MAX 100

void inputf(void);
void name_sarch(void);
void title_sarch(void);

char names[MAX][80], titles[MAX][80], pubs[MAX][80];


int main(void)
{
int i;

do {
printf("図書カードカタログ:\n");
printf(" 1.入力\n");
printf(" 2.著者名による検索\n");
printf(" 3.書名による検索\n");
printf(" 4.終了\n");
printf("いずれかを選択してください:");

scanf("%d", &i);

switch (i) {
case 1:
inputf();
break;
case 2:
name_sarch();
break;
case 3:
title_sarch();
break;
case 4:
break;
default:
printf("メニューにありません\n");
break;
}
} while (i != 4);

printf("正常に終了します");

return 0;
}

/*インプット部分*/
void inputf(void)
{
int i;

for (i = 0; i < MAX; i++){
printf("書名を入力してください:");
gets(titles[i]);
if (! *titles[i])
break;
printf("著者名を入力してください:");
gets(names[i]);
printf("出版社を入力してください:");
gets(pubs[i]);
}

if (i == MAX)
printf("これ以上は入力出来ません\n");
}

/*著者名による検索*/
void name_sarch(void)
{
int i;
printf("臨時テスト関数です\n書名の配列番号を入力してください");
scanf("%d", &i);
printf("%s", titles[i]);

}

/*書名検索*/
void title_sarch(void)
{
printf("書名検索関数\n");
}



と作りまして、これをコンパイルしてコンソールで見ると、



[Session started at 2008-03-18 21:30:34 +0900.]
図書カードカタログ:
1.入力
2.著者名による検索
3.書名による検索
4.終了
いずれかを選択してください:1     (←僕はここで1を押して、enterキーを押しました)

warning: this program uses gets(), which is unsafe.
書名を入力してください:図書カードカタログ:
1.入力
2.著者名による検索
3.書名による検索
4.終了
いずれかを選択してください:



と言うふうに勝手に、書名の部分をエンターでか、終わらせて、メニューに帰ってきてしまいます。
これは一体どういう事で、どうすれば解決できるんでしょうか、是非教えてください。

投稿日時 - 2008-03-18 21:46:29

QNo.3874594

困ってます

質問者が選んだベストアンサー

訂正です。gets() は警告は出ますが実行できるようですね。
で、本題については、scanf("%d", &i); に対して 1(リターン)と入力した時に、1 は i に渡されますが、(リターン)がキーボードバッファに残ったままになっているのが原因です。そのため、次に gets() で入力を求められた時に自動的に(リターン)が入力されてしまうわけです。
従って、scanf("%d", &i); の代わりに scanf("%d%*c", &i); を使えば解決します。

投稿日時 - 2008-03-18 23:46:07

お礼

出来ました!!
なるほど・・・、入力をそうやると処理できるわけですか・・・。
sevenlessさん、本当にいつもありがとうございます!!
独習しているとこういった泥沼は本当に難しいので、とても助かっています。
ありがとうございます。

投稿日時 - 2008-03-19 00:37:35

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

gets() 関数にはバグがあり、バッファオーバーフローを意図的に引き起こすセキュリティホールとして度々狙われてきました。そのため、デフォルトでは実行できなくしてあります。代わりに fgets() 関数を使ってください。
詳しくは man gets してください。

投稿日時 - 2008-03-18 23:18:43

あなたにオススメの質問