アプリ版:「スタンプのみでお礼する」機能のリリースについて

こちらには初めての質問です、よろしくお願いします。
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);
}

A 回答 (5件)

★『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

この回答への補足

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

補足日時:2007/04/06 22:45
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/09 22:06

おぉ、そういえば'\n'までついてしまうんでしたね。


けれど、'\n'が必ずつくとは限らないことを考えると、ANo3さんのようにstrchrを使うべきですね。


> 全データを表示させるには、(printf()関数) を利用すればいいのでしょうか?

そうですね。
実際は様々なテクニックがありますが、
初めのうちはprintfやputsで十分だと思いますよ。
例えばこのような感じで・・・

  for(loop = 0; loop < 10; loop++) {
    puts(name[loop]);
    puts(phone[loop]);
  }

もし仕事であれば・・・
デバッグコードを消し忘れる可能性もあるので、
このような手抜きは許されません(笑)

この回答への補足

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

補足日時:2007/04/07 21:44
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/09 22:11

> それから、そもそも'\0'を付加するためにstrlenを使用するのは矛盾しています。


> (strlenが動作するためには文字列が'\0'で終端している必要がある)
> しかもstrlenの結果に-1すると、最後の文字を上書きしてしまいますよ。

fgets()で読み取った文字列の最後に付いている(通常は余分な)'\n'を
取り除くための、ごく一般的な方法です。

fgets()で文字列を読み取ったとき、例えば
'a', 'b', 'c', '\n', '\0'
のように格納します。このとき、strlen()で求まる文字列長は'\n'までの4です。
でもって、'\n'を取り除いて'a', 'b', 'c', '\0'という状態にするには、
質問者の方が書かれたような方法で行なうのです。

この回答への補足

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

補足日時:2007/04/06 22:52
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/09 22:09

> 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すると、最後の文字を上書きしてしまいますよ。


あとは、データ入力が終わったら、一度全データを表示させてみてはいかがですか?
そうすれば、ある程度原因も見当がついていたはずです。
必要なくなれば、そのデバッグコードは無効にしてしまえばよいのですから。

この回答への補足

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

補足日時:2007/04/06 22:40
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/09 22:02

> name[loop][strlen(name[loop]) -1] = '0';


> phone[loop][strlen(phone[loop]) -1] = '0';

'0'を代入してはまずいです。
文字列終端用の'\0'を代入してください。

この回答への補足

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

補足日時:2007/04/06 22:13
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/09 21:57

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