
こちらには初めての質問です、よろしくお願いします。
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);
}
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
アドバイスありがとうございました。詳しいアドバイスをしてもらったのですが、知識不足のせいでまだ解決していません。いろいろな原因を考えながらもう少しがんばって見ます。
No.5
- 回答日時:
おぉ、そういえば'\n'までついてしまうんでしたね。
けれど、'\n'が必ずつくとは限らないことを考えると、ANo3さんのようにstrchrを使うべきですね。
> 全データを表示させるには、(printf()関数) を利用すればいいのでしょうか?
そうですね。
実際は様々なテクニックがありますが、
初めのうちはprintfやputsで十分だと思いますよ。
例えばこのような感じで・・・
for(loop = 0; loop < 10; loop++) {
puts(name[loop]);
puts(phone[loop]);
}
もし仕事であれば・・・
デバッグコードを消し忘れる可能性もあるので、
このような手抜きは許されません(笑)
この回答への補足
度々のアドバイスありがとうございます。今の私のレベルは、まだまだ初歩の段階です。アドバイスしていただいた方法を参考にしたいと思います。
補足日時:2007/04/07 21:44アドバイスありがとうございました。まだ原因が分からず、解決していませんが、デバッグのやり方を参考にしてもう少しがんばってみます。

No.4
- 回答日時:
> それから、そもそも'\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:52No.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すると、最後の文字を上書きしてしまいますよ。
あとは、データ入力が終わったら、一度全データを表示させてみてはいかがですか?
そうすれば、ある程度原因も見当がついていたはずです。
必要なくなれば、そのデバッグコードは無効にしてしまえばよいのですから。
この回答への補足
詳しいアドバイスありがとうございます。参考にしている本には書いてない事ばかりなので、大変参考になります。
追加の質問になってしまうのですが、全データを表示させるには、(printf()関数) を利用すればいいのでしょうか?
こちらに質問をする前に、exit()関数で、デバッグをしてみたのですが
使い方が理解できませんでした。もしprintf()関数を使うのでしたら、今後の参考にしたいのですが教えていただけますか。
No.1
- 回答日時:
> name[loop][strlen(name[loop]) -1] = '0';
> phone[loop][strlen(phone[loop]) -1] = '0';
'0'を代入してはまずいです。
文字列終端用の'\0'を代入してください。
この回答への補足
アドバイスありがとうございます。ご指摘のとおり、'0'では無く
'\0'ですね。学習したのですが、'0'と'\0'についてきちんと理解してなかったです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Visual Basic(VBA) InputBoxでキャンセルボタンを押したらファイル自体を閉じたい 3 2022/07/23 17:52
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SUN BBSの改造方法
-
電話番号を読み込むプログラム...
-
入力フォームに全角・半角スペ...
-
ラジオボタンが両方とも選択で...
-
掲示板(kentさんの所のsunbbs...
-
select値をhiddenのvalueに渡し...
-
[HTML]プルダウンメニューの横...
-
valueに ' や " を使う時
-
socketを使って外部のファイル...
-
PHPで検索ボタンを押さずに検索...
-
Error: No Recipient というエ...
-
チェックボックスの返す値
-
CGIプログラムでのボタン表...
-
「value」に2つの値をセットす...
-
検索フォーム設置時のnameの文...
-
隠しフォーム(hidden)を使いたい
-
チェックボックスとセレクトボ...
-
Lightboxの表示位置に関して質...
-
select name が反映されません...
-
横スクロールを縦スクロールに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SUN BBSの改造方法
-
perlで書いたcgiでsqliteの使い...
-
tracert ができない原因
-
perl ヒア文(print <<"EOM" ...
-
入力フォームに全角・半角スペ...
-
Windows7でVBScriptによるネッ...
-
name属性をperlに引き継ぎたい
-
sendmailのメール送信ができま...
-
チェックボックスでのor検索
-
CGI(Perl)内での必須項目チェ...
-
CGIで合計を書き出す方法
-
日本語文字化け(GETメソッド?)
-
KENTWEBのBASIC認証について
-
【CGI】画像の表示の仕方【Mini...
-
配列をグループ化して出力したい。
-
Perlでuse socketを使用してフ...
-
文字って数字で表現・・・
-
yoyaku.cgi の改造
-
掲示板(kentさんの所のsunbbs...
-
ラジオボタンが両方とも選択で...
おすすめ情報