• ベストアンサー

ISBNチェッカー

猫でもできるプログラミング(http://www.kumei.ne.jp/c_lang/index.html)のc言語第一部を最初からやっているのですが、ISBNチェッカーを作成するページで躓いてしまいました。 第10章(http://www.kumei.ne.jp/c_lang/intro/no_10.htm)の一番下に書いてあるように、続けて他の番号を入力できるように作り変えたいのですが、cygwinでコンパイルして実行すると「次のチェックを行いますか」と表示された後にエラーが出てしまいます。自分でも確認してみたのですがどうしてか分からなかったので、こちらで質問させていただきました。 どの個所がまずいのでしょうか?助言をお願いします。 #include <stdio.h> #include <string.h> int input_isbn(void); int check_isbn(char *); int main() { char ch; do { input_isbn(); printf("次のチェックを行いますか? y/n\n"); scanf("%c",ch); }while(ch=='y'); printf("終わりだよ!"); return 0; } int input_isbn(void) { char isbn[64]; int ret; printf("ISBNを入力してください。\n"); scanf("%s", isbn);//文字列は、%sで ret = check_isbn(isbn); switch (ret) { case -2:printf("入力ミスです\n"); break; case -1:printf("不正番号です\n"); break; case 0:printf("正しい番号です\n"); break; } return 0; } int check_isbn(char *bango) { int gokei, suuchi[10], i; if(strlen(bango) != 10) return -2; gokei = 0; for (i = 0; i <= 8; i++) { suuchi[i] = bango[i] -48; } for(i = 0; i <= 8; i++) gokei = gokei + suuchi[i]*(10-i); if(bango[9] == 'X'||bango[9] =='x') gokei = gokei + 10; else gokei = gokei + bango[9] - 48; printf("gokei = %d\n", gokei); if (gokei%11==0) return 0; else return -1; }

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

scanf における %s や %c の仕様を調べれば自明だったりします. %s は「空白文字が来たら変換を停止する」 (そしてその空白文字は入力ストリームに残ったまま) し, %c では「どんな文字だろうと必ず 1文字読み込む」という動作をします. つまり, %s で読み込んだときに最後に打った (はずの) 改行が残ってそのまま %c で読み込まれているはずです.

saku0513
質問者

お礼

てっきり空白文字も文字列の中に組み込まれるものだと思っていました。入力ストリームに残ったままなんですね。 しっかり調べていなかったのが原因です。 でもだんだん理解してきた気がします。ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

代入抑制の * を使えば無駄な変数はいらないですよ>#3. %*c とするか %*[^\n]\n のようにするかについてはいろいろとありそうですが.

saku0513
質問者

お礼

代入抑制というものを初めて知ったのですが、読み込む値を指定できるんですね。 %*cとして動作しました。%*[^\n]\nはどういう仕組みかまだ理解できていないのでこれから調べてみます。 問題なく動作するようになったので一旦回答募集を締め切ります。 回答してくださった皆様、ありがとうございました! これで次のステップに進めます!

すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

終わってしまうのは input_isbnの中のscanfで入力を求めた際に押された『Enter』キーの入力がキューに残っているためでしょう 1234-4545-3321[Enter] と入力した際にscanf("%s", isbn); では『1234-4545-3321』までは読み込まれますが[Enter]キーの『\n』が残ってしまいます この残った『\n』を main側の scanf( "%c", &ch ); で読み込んでしまうので whileの条件不成立となり終了します そこで[Enter]まで input_isbn側で面倒を見るように char dummy; scanf( "%s%c", isbn, &dummy ); といった具合にして見ましょう

saku0513
質問者

お礼

なるほど、余分な\nを納めるのはdummyという変数を使えばいいのですね。 上記のとおりにやってみたら動作しました!一旦完成です。 ありがとうございました。

すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2127/6290)
回答No.1

コード全体を見たわけではありません。 パッと気づいたのは >scanf("%c",ch); 第2引数がchのアドレスでないことです。

saku0513
質問者

お礼

初歩的なミスで恥ずかしいです。ご指摘ありがとうございます。  scanf("%c",ch);を  scanf("%c",&ch);と直して再度コンパイル、実行してみると 「次のチェックを行いますか」と表示された後のエラーは出なくなりましたが、文字入力を待たずにそのままプログラムが終わってしまいました。 引き続きアドバイスを募集しています。

すると、全ての回答が全文表示されます。

関連するQ&A