質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

2387閲覧

ファイルから読み取って配列に入れて表示したい c

ceb

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2019/07/04 16:22

編集2019/07/04 16:28

前提・実現したいこと

初心者です。C言語で住所録を作りたいです。
①入力した名前・住所・電話番号を配列に入れて、ファイルに書き込む機能と
②ファイルから読み込んで配列に入れて表示する機能を作りたいです。
①書き込む機能はなんとかできたのですが②読み込んで表示が上手くいきません。「全%d件の登録を読み込みます。」だけ表示されて終了してしまいます。
どこを直せばいいかご教授ください。
また、参考のお手本の中ではwrite関数のfprintfのdataの前に&がなかったのですが、入れないと①が②と同様に途中で止まってしまうため入れました。何か問題が起こりますでしょうか。ついでに教えていただけると幸いです。
長いですが、一応全文載せました。初歩的な問題で申し訳ありませんがよろしくお願いいたします。

発生している問題・エラーメッセージ

該当のソースコード

#include <stdio.h> int n; /*グローバル変数 */ /*プロトタイプ宣言 */ void write(void); void read(void); int main(void) { char data[3][30]; int bunki; printf("住所録です。名前と住所と電話番号を30件まで記録できます。\n"); printf("新規登録を行うには0、登録先を読み込むには1、指定された住所を含む登録先を読み込むには2を入力してください\n"); scanf("%d", &bunki); if(bunki == 0) { write(); } else { if(bunki == 1) { read(); } else { if(bunki == 2) { printf("作成中\n"); } else { printf("0,1,2以外が入力されています。やり直してください。\n"); } } } return 0; } /*新規登録を行う関数write */ void write(void) { char data[30][3]; FILE *fpn; /*ファイルポインタ mame=名前*/ FILE *fpa; /*ファイルポインタ address=住所*/ FILE *fpp; /*ファイルポインタ phone=電話番号 */ FILE *fpr; /*ファイルポインタ 登録が何番目かを記録するファイル*/ fpr = fopen("numberfile.txt", "r"); /*nの値をファイルから読み込む */ fscanf(fpr, "%d", &n); fclose(fpr); if(n >= 29) { printf("これ以上登録できません\n"); } else { if(n <= 28) { printf("%d番目の新規登録を行います。\n", n+1); /*n+1 0番目始まりは違和感があるので1~30番で表示されるようにした */ printf("名前を入力してください\n"); scanf("%s", &data[n][0]); /*[n][0]にはn番目の登録の、名前の情報が入る*/ fpn = fopen("namefile.txt","a"); fprintf(fpn, "%s\n", &data[n][0]); fclose(fpn); printf("住所を入力してください\n"); scanf("%s", &data[n][1]); /*[n][1]にはn番目の登録の、住所の情報が入る*/ fpa = fopen("addressfile.txt","a"); fprintf(fpa, "%s\n", &data[n][1]); fclose(fpa); printf("電話番号を入力してください\n"); scanf("%s", &data[n][2]); /*[n][2]にはn番目の登録の、電話番号の情報が入る*/ fpp = fopen("phonefile.txt","a"); fprintf(fpp, "%s\n", &data[n][2]); fclose(fpp); printf("%d番目の登録が完了しました。\n", n+1); n++; fpr = fopen("numberfile.txt", "w"); /*nの値を更新してファイルに保存 */ fprintf(fpr, "%d\n", n); fclose(fpr); } } } /*読み込みを行う関数read */ void read(void) { char data[30][3]; FILE *fpn; FILE *fpa; FILE *fpp; FILE *fpr; fpr = fopen("numberfile.txt", "r"); /*nの値をファイルから読み込む */ fscanf(fpr, "%d", &n); fclose(fpr); if(n == 0) { printf("一件も登録されていません。\n"); } else { fpn = fopen("namefile.txt","r"); fpa = fopen("addressfile.txt","r"); fpp = fopen("phonefile.txt","r"); int m; for(m=0; m<=n; m++) { fscanf(fpn, "%s", &data[m][0]); fscanf(fpa, "%s", &data[m][1]); fscanf(fpp, "%s", &data[m][2]); } fclose(fpn); fclose(fpa); fclose(fpp); printf("全%d件の登録を読み込みます\n", n); for(m=0; m<=n; m++) { printf("名前:%s 住所:%s 電話番号:%s\n", data[m][0], data[m][1], data[m][2]); } } }

試したこと

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

scanf の "%s" は、char の配列に、入力文字列を読み込む
変換指定子です。十分な大きさの配列を用意してください。
プログラム中の文字列は最後に '\0' が付きます。
char data[3] では、2文字しか入りません。

scanf は、入力を読み込む変数へのポインタを指定しないといけ
ないのですが、変数が配列の場合、配列は自動的に配列の先頭要素
へのポインタに変換されるので & を付ける必要はありません。

次のプログラムについて、よく考えてみてください。

C

1#include <stdio.h> 2 3int main(void) 4{ 5 char name[32]; 6 printf("name: "); 7 scanf("%31s", name); 8 printf(" name = '%s'\n", name); 9 10 char names[3][32]; 11 for (int i = 0; i < 3; i++) { 12 printf("names[%d] = ", i); 13 scanf("%31s", names[i]); 14 } 15 for (int i = 0; i < 3; i++) 16 printf(" names[%d] = '%s'\n", i, names[i]); 17 return 0; 18}

投稿2019/07/05 00:51

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ceb

2019/07/06 10:40

ご回答ありがとうございます! 配列の要素数の意味をよく理解していませんでした。無事解決することができました。ありがとうございました。
guest

0

fscanf(fpn, "%s", &data[m][0]);

scanf関係は全部ダメです
引数は、配列のアドレスを指定します。現状では文字のアドレスとなってしまっていて、領域外のアクセスになってしまいます。

scanf,fscanfの記述は全部修正しましょう


で、Cのコードを組むなら、VisualStudioとかEclipseとかのデバッグできる環境を整えましょう
任意の行で実行を止め、変数の値を見ることができるようになります。また、1行づつ実行することもできます
そうすれば、あてずっぽでコードを組まなくて済むようになります

投稿2019/07/04 21:55

編集2019/07/04 21:58
y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ceb

2019/07/06 10:48

ご回答ありがとうございます! 配列について理解が足りていませんでした。これから復習していきます。お恥ずかしながらデバッグも上手く動かせず困っていたところでした。;; 無事解決できました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問