重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

猫でもできるプログラミング(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;
}

A 回答 (4件)

scanf における %s や %c の仕様を調べれば自明だったりします.


%s は「空白文字が来たら変換を停止する」 (そしてその空白文字は入力ストリームに残ったまま) し, %c では「どんな文字だろうと必ず 1文字読み込む」という動作をします.
つまり, %s で読み込んだときに最後に打った (はずの) 改行が残ってそのまま %c で読み込まれているはずです.
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/05/07 22:22

代入抑制の * を使えば無駄な変数はいらないですよ>#3.


%*c とするか %*[^\n]\n のようにするかについてはいろいろとありそうですが.
    • good
    • 0
この回答へのお礼

代入抑制というものを初めて知ったのですが、読み込む値を指定できるんですね。
%*cとして動作しました。%*[^\n]\nはどういう仕組みかまだ理解できていないのでこれから調べてみます。

問題なく動作するようになったので一旦回答募集を締め切ります。
回答してくださった皆様、ありがとうございました!
これで次のステップに進めます!

お礼日時:2009/05/08 06:27

終わってしまうのは 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 );
といった具合にして見ましょう
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/05/07 22:26

コード全体を見たわけではありません。


パッと気づいたのは

>scanf("%c",ch);

第2引数がchのアドレスでないことです。
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/05/06 21:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!