第9章 ISBNチェッカーを作ろう(2)


前回は、入力部分を作りました。 今回は、入力された番号が、正しいのかどうか チェックするところを作ってみましょう。 前回、せっかく自作関数の作り方を勉強したので チェックする関数も独立して作ってみましょう。 とりあえず、関数名は check_isbn() とでもしておきましょう。 もちろん、気にくわなければ別の名前でもかまいません。 引数は、当然入力部分でもらってきた 番号ですね。 そして、この関数の中で、ISBNの番号として 正しいのかどうかを判断して、正しければ1を 正しくなければ2を返すようにしましょう。 従って、関数の戻り値はint型にしましょう。

あー、これでできたも同然ですね。

言うは易く、行うは難し!

これじゃさっぱりわからん!と言う方もおられると 思うので少しずつ解説していきます。

まず、もらった番号を、初めの位は10倍して、 次は、9倍して・・・最後の位は1倍して 合計を求めましょう。

いや待て!

もらった番号は、文字列なのでその1つ1つは 文字であって、数字じゃない。簡単にたしたり かけたりはできないのじゃないの?

ピン、ポーン!正解です。

少し復習です。

char *str = "abc";

で、str[0]は'a'を、str[1]は'b'を、str[2]は'c' を表していると考えました。そして実際には その文字のアスキーコード(番号)が入っていました。 そして'0'のアスキーコードは48(10進法)です。 '1'以降順番にアスキーコードは1ずつ増えていきます。 (嘘だと思ったらアスキーコード表を見ること!)

文字'N(数字)'のアスキーコードから48をひくと、 文字'N'を数値に変換できる!!!

と、いうことに気付きましょう。(無理ですね。 これは、たいていの入門書に書いてあります。 そのように覚えましょう。忘れたら、コード表を 眺めてみればすぐに思い出します)

今回は、さらに大事なことを書きます。

プログラムは、特に指定しなければ順番に実行されます。 これを、条件を付けて処理の順番を変えたり、繰り返したり させることができます。(もし、これができないとプログラムは ほとんど作れませんね。) まず、ある条件を満たしたときに実行 されるif文について 説明します。

if(ここが真なら){ これを実行; }else{ だめならここを実行; }

ifのあとのカッコの中が正しければ、 次の{xxx;}を実行し、正しくなければelse以下の {xxx;}を実行しなさいという意味です。 「もしiが3ならば」
は、if(i=3)ではありません!if(i==3)です。 イコールが1つの場合は、右辺の値を左辺に代入しなさいという意味で、 数学のイコールとは、全く異なります。イコールが2つくっついた物は、 右辺と、左辺を比較して等しいなら1等しくないなら0を式の値として持ちます。 詳しくは、あとから演算子という章で解説します。 実行する内容が1個(文が1つ)ならば、大カッコ{ }で囲む 必要はありません。囲っても間違いではありません。

次は、switch文です。 式(int型の値を取る物に限る!)の値により、する事をいろいろ 区別します。次の例は、式の値が、1か2になることにより、 実行する内容を変えることができます。そのあと、忘れず break文をつけてください。これを忘れると、悲惨な目に遭います。 それ以外の物が出てきたときは、defaultのところを実行します。 switch文は、if文で書き直すことができますが、 複雑になり間違いを生じやすくなります。

switch(式){ case 1:ああしろ、こうしろ; break; case 2:あれもしろ、これもやれ; break; default:例外処理; }

繰り返し処理のための、for文というのもあります。

for(ここから;ここが正しい間;変化させろ){ 実行内容; }

例:for(i=1; i <= 10; i++)

という場合、iが1から始めて、iが10以下の時は、次のことをしなさい。 そして、1回やったらiを1増やしなさい。という意味です。i<=10は、iが 10以下ならば、式の値1(真)そうでなければ0(偽)を持ちます。 ==から想像できますね。i++は、iを1ずつ増やせという意味です。 ++iというのもあるので間違えないでください。いずれも、演算子の章で 詳しく解説しますので、今は「あー、こういうもんだ」程度で充分です。 さらに、||は「または」と読みましょう。ついでに、&&は「かつ」です。 !=は、左右が等しくなければ真を等しければ偽を式の値に持ちます。 「等しくない」と読みましょう。%は、パーセントではなく、 わり算のあまりです。10%3は「10割る3は、3余り1」なので、1を表します。

次に超初心者が陥りやすい間違いを示します。

x=x+3;
これは、どういう意味でしょう。

両辺から、Xを引くと、0=3となり正しくない。これは「不能」である!

これは、すごい間違いですね。上の方に書いたように「=」は、数学の イコールではなくて「代入しなさい」という演算子です。従って、 現在のXに3をたした物を、(左辺の)Xに代入しなさい。という意味です。 現在、Xが7であれば、今度はXが10になります。これが、わからないと 今後かなり、わからないことが急速に増えてくるのでしっかりと覚えてください。 いろいろ、前置きが長くなりましたが、これらのことをふまえて プログラムを書くと次のようになります。ソースコードをじっくり読んでみてください。 そして、実際に打ち込んでブログラムを作ってみてください。

#include <stdio.h> #include <string.h> #include <conio.h>//どうしてinclude文が増えたか //考えてみてください。 int input_isbn(void); int check_isbn(char *); //今回作成した関数 int main() { input_isbn(); getch(); 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をかえす関数です //これを呼んだ側の関数で //返されたintを使っています。 { int gokei, suuchi[10], i; if (strlen(bango) != 10) //文字列の長さチェック return -2; //10文字でなければ-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); //最後がXのこともあるのだよ! 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) //合計が11の倍数なら0 return 0; else return -1; //そうでなければ−1をかえす }

実行結果です。そこら辺にある、本のISBN番号を片っ端から 調べて、不正番号を発見しよう!(そんなものあるわけないか・・)



[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Oct/24/1996 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。