• ベストアンサー

電話番号を読み込むプログラムについて教えてください

こちらには初めての質問です、よろしくお願いします。 C言語の基礎を独学で学習中の初心者です。 テキストファイルに、名前と電話番号をあらかじめ書き込んでおき、 検索したい人の名前を入力すると、電話番号が表示されるというプログラムについて教えてください。 1、名前は漢字で入力    (山野 桜) 2、電話番号は、半角で入力 (001234567\n) この様にして10人分のデータが、入力してあります。 実行時に名前を入力しても電話番号が表示されません。 エラーメッセージも出ません、プログラムに問題があるのか、作成したテキストファイルに問題があるのか判断できません。 アドバイスをお願いします。 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char name[10][22]; char phone[10][13]; char input[21]; int loop; FILE *FP; if((FP = fopen("address.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return(1); }     /*ファイルからデータを読み込む*/ for(loop = 0; loop < 10; loop++) { fgets(name[loop], 22, FP); name[loop][strlen(name[loop]) -1] = '0'; fgets(phone[loop], 13, FP); phone[loop][strlen(phone[loop]) -1] = '0'; } printf("電話番号を検索したい名前を入力してください\n"); gets(input); /*検索と表示*/ for(loop = 0; loop < 10; loop++) { if(strcmp(name[loop], input) == 0) {  printf("%sさんの電話番号は : %s\n", input, phone[loop]); } } return (0); }

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★『fgets』関数の戻り値をチェックするようにしましょう。 ・あと改行コードを『\0』の終端文字に置き換えたいようですが、この場合は『strchr』の  関数で検索して見つかったらば『\0』に書き換えるようにすれば良い。 ・下にループ部のみを記述します。 ループ部: char *find; ←宣言部に追加 /*ファイルからデータを読み込む*/ for ( loop = 0 ; loop < 10 ; loop++ ){  if ( fgets(name[loop],sizeof(name[0]),FP) != NULL ){   if ( (find = strchr(name[loop],'\n')) != NULL ){    *find = '\0'; ←『0』ではなくて『\0』です。注意!   }  }  if ( fgets(phone[loop],sizeof(phone[0]),FP) != NULL ){   if ( (find = strchr(name[loop],'\n')) != NULL ){    *find = '\0'; ←ここも『\0』です。   }  } } その他: ・最後の方で『検索と表示』を行っていますが、データが 10 人以下の場合はデタラメな  データが name、phone に入っているため『strcmp』関数で上手く比較できないと思います。 ・そこで、 name、phone の2つの変数を初期化しておきます。  宣言部を次のようにします。  (1)初期化方法1…『static』を付ける   static char name[10][22];   static char phone[10][13];  (2)初期化方法2…『{ 0 }』を付ける   char name[10][22] = { 0 };   char phone[10][13] = { 0 };  (3)初期化方法3…宣言部ではなくて『fopen』関数の前に実行   memset( name, '\0', sizeof(name) );   memset( phone, '\0', sizeof(phone) ); ・以上。上記のを今後の参考に。

参考URL:
http://www9.plala.or.jp/sgwr-t/lib/memset.html
noname#220054
質問者

お礼

アドバイスありがとうございました。詳しいアドバイスをしてもらったのですが、知識不足のせいでまだ解決していません。いろいろな原因を考えながらもう少しがんばって見ます。

noname#220054
質問者

補足

貴重なアドバイスありがとうございます。ご指摘の方法を参考にして、実行してみます。

その他の回答 (4)

  • 1839cc
  • ベストアンサー率54% (12/22)
回答No.5

おぉ、そういえば'\n'までついてしまうんでしたね。 けれど、'\n'が必ずつくとは限らないことを考えると、ANo3さんのようにstrchrを使うべきですね。 > 全データを表示させるには、(printf()関数) を利用すればいいのでしょうか? そうですね。 実際は様々なテクニックがありますが、 初めのうちはprintfやputsで十分だと思いますよ。 例えばこのような感じで・・・   for(loop = 0; loop < 10; loop++) {     puts(name[loop]);     puts(phone[loop]);   } もし仕事であれば・・・ デバッグコードを消し忘れる可能性もあるので、 このような手抜きは許されません(笑)

noname#220054
質問者

お礼

アドバイスありがとうございました。まだ原因が分からず、解決していませんが、デバッグのやり方を参考にしてもう少しがんばってみます。

noname#220054
質問者

補足

度々のアドバイスありがとうございます。今の私のレベルは、まだまだ初歩の段階です。アドバイスしていただいた方法を参考にしたいと思います。

回答No.4

> それから、そもそも'\0'を付加するためにstrlenを使用するのは矛盾しています。 > (strlenが動作するためには文字列が'\0'で終端している必要がある) > しかもstrlenの結果に-1すると、最後の文字を上書きしてしまいますよ。 fgets()で読み取った文字列の最後に付いている(通常は余分な)'\n'を 取り除くための、ごく一般的な方法です。 fgets()で文字列を読み取ったとき、例えば 'a', 'b', 'c', '\n', '\0' のように格納します。このとき、strlen()で求まる文字列長は'\n'までの4です。 でもって、'\n'を取り除いて'a', 'b', 'c', '\0'という状態にするには、 質問者の方が書かれたような方法で行なうのです。

noname#220054
質問者

お礼

アドバイスありがとうございました。まだ解決していませんが、ほかの原因を考えながらもう少しがんばって見ます。

noname#220054
質問者

補足

詳しいアドバイスありがとうございます。今回の間違いは、fgets()での代入が'0'と'\0'の間違いのようです。ここを書き換えてもう一度実行してみます。

  • 1839cc
  • ベストアンサー率54% (12/22)
回答No.2

> name[loop][strlen(name[loop]) -1] = '0'; > phone[loop][strlen(phone[loop]) -1] = '0'; '0'ではまずいというか、この2行は入れないほうがよいですね。 strncpyなどは'\0'が入らないことがあるので、 このような処理が必要になってきます。 しかし、fgetsでは'\0'が保障されますので必要ないでしょう。 それから、そもそも'\0'を付加するためにstrlenを使用するのは矛盾しています。 (strlenが動作するためには文字列が'\0'で終端している必要がある) しかもstrlenの結果に-1すると、最後の文字を上書きしてしまいますよ。 あとは、データ入力が終わったら、一度全データを表示させてみてはいかがですか? そうすれば、ある程度原因も見当がついていたはずです。 必要なくなれば、そのデバッグコードは無効にしてしまえばよいのですから。

noname#220054
質問者

お礼

アドバイスありがとうございました。いろいろ試してみたのですが、まだ解決していません。ほかの原因も考えて見ます。

noname#220054
質問者

補足

詳しいアドバイスありがとうございます。参考にしている本には書いてない事ばかりなので、大変参考になります。 追加の質問になってしまうのですが、全データを表示させるには、(printf()関数) を利用すればいいのでしょうか? こちらに質問をする前に、exit()関数で、デバッグをしてみたのですが 使い方が理解できませんでした。もしprintf()関数を使うのでしたら、今後の参考にしたいのですが教えていただけますか。

noname#26650
noname#26650
回答No.1

> name[loop][strlen(name[loop]) -1] = '0'; > phone[loop][strlen(phone[loop]) -1] = '0'; '0'を代入してはまずいです。 文字列終端用の'\0'を代入してください。

noname#220054
質問者

お礼

アドバイスありがとうございました。0と\0を入れ替えてみたのですが、解決できませんでした。ほかの原因を探して見ます。

noname#220054
質問者

補足

アドバイスありがとうございます。ご指摘のとおり、'0'では無く '\0'ですね。学習したのですが、'0'と'\0'についてきちんと理解してなかったです。

関連するQ&A