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

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

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

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

Q&A

解決済

3回答

1062閲覧

構造体を利用したデータの読み込みと表示

matti0518

総合スコア10

C

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

0グッド

0クリップ

投稿2017/12/25 10:35

###前提・実現したいこと
Cで構造体を利用してbaseball_player.defというファイルを読み込み、各データを逆順に表示するプログラムなのですが、コアダンプになってしまいます。読み込んだデータを格納するポインタ配列data[MAX_LEN]を二次元配列data[player_num][MAX_LEN]にしてみたりもしましたがうまくいきませんでした。
どこが間違っているのでしょうか?できれば詳しい解説等もつけてくださればありがたいです。
変更するのはmain関数内のみで、関数等は変更しないようにお願いします。

###ソースコード

C

1#include <stdio.h> 2#include <stdlib.h> 3 4#define MAX_LEN 100 5 6/*PLAYER構造体の定義*/ 7typedef struct string 8{ 9 char name[10]; /*名前*/ 10 int number; /*背番号*/ 11 int at_bat; /*打数*/ 12 int hit; /*安打数*/ 13 double ave; /*打率*/ 14}PLAYER; 15 16 17 18/*makePlayerData関数の定義*/ 19PLAYER makePlayerData(char *data) 20{ 21 PLAYER a; 22 23 /*文字列より各種データの読み込み*/ 24 sscanf(data, "%s %d %d %d", a.name, &a.number, &a.at_bat, &a.hit); 25 /*打率の計算*/ 26 a.ave = (double)a.hit / (double)a.at_bat; 27 28 return a; 29} 30 31 32 33/*printPlayerData関数の定義*/ 34void printPlayerData(PLAYER a){ 35 printf("%s %d %d %d %f\n", a.name, a.number, a.at_bat, a.hit, a.ave); 36} 37 38 39 40int main(int argc, char *argv[]) 41{ 42 char buff[MAX_LEN]; 43 char *filename; 44 FILE *fp; 45 int i; 46 int player_num; 47 char *data[MAX_LEN]; 48 PLAYER p[player_num]; 49 50 51 if(argv[1] != NULL) filename = argv[1]; 52 53 /*コマンドラインパラメータの数が間違っている場合の処理*/ 54 if(argc != 2){ 55 printf("Usage: ./print_player_data.c [filename]\n"); 56 exit(1); 57 } 58 59 /*ファイルを開く*/ 60 fp = fopen(filename, "r"); 61 62 /*ファイルが存在しない場合の処理*/ 63 if(fp == NULL) { 64 printf("File %s doesn't exist.\n", filename); 65 exit(1); 66 } 67 68 /*ファイルの読み込み*/ 69 i = 0; 70 while(fgets(buff, sizeof(buff) , fp) != NULL){ 71 sscanf(buff, "%s", data[i]); 72 p[i] = makePlayerData(data[i]); 73 i++; 74 } 75 76 /*ファイルを閉じる*/ 77 fclose(fp); 78 79 /*データの表示*/ 80 player_num = i; 81 for(i = player_num - 1; i >= 0; i--){ 82 printPlayerData(p[i]); 83 } 84 85 return 0; 86} 87

#baseball_player.defの内容

Tanaka 3 483 125 Yamada 9 509 143 Takahashi 24 503 152 Abe 24 498 138 Suzuki 31 518 149

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

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

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

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

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

guest

回答3

0

まず、

C

1PLAYER p[player_num];

player_numに値を設定してない状態で、これはマズイですね。
人数の最大値が決まっているのであれば、例えば

C

1#define MAX_PLAYER 10

C

1PLAYER p[MAX_PLAYER];

とでもやっておけば良いのですが。

あと、

C

1sscanf(buff, "%s", data[i]);

これも、data[i]はポインタだけど値を設定してませんね。
さらに、空白の手前までしか入力できない。

投稿2017/12/25 12:08

okrt

総合スコア366

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

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

0

ベストアンサー

C

1 /*ファイルの読み込み*/ 2 i = 0; 3 while(fgets(buff, sizeof(buff) , fp) != NULL){ 4 sscanf(buff, "%s", data[i]); 5/* 6 * ここで一旦 data[i] をプリントしてみよう。 7 * data[i] にはファイルから読んだ一行分("Tanaka 3 483 125"とか) 8 * が納められてなきゃ makePlayerData() に与えられんよね。 9 * ...ちょっとマテ。data[i]には一行分の文字列を納めるのに十分な領域が確保されているかい? 10 */ 11 p[i] = makePlayerData(data[i]); 12 i++; 13 }

投稿2017/12/26 00:28

episteme

総合スコア16614

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

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

0

とりあえず目についたのは、これです。
コマンドライン引数がないときもargv[1]が評価されてしまいます。

C

1if(argv[1] != NULL) filename = argv[1];

次のように処理の順序を変えると良いでしょう。

C

1if(argc < 2){ 2 printf("Usage: ./print_player_data.c [filename]\n"); 3 exit(1); 4} 5 6filename = argv[1];

そもそも適切に実行しているかも不明です。
コマンドライン引数をどのように与えているかも書くべきでしょう。

投稿2017/12/25 10:38

編集2017/12/25 10:45
LouiS0616

総合スコア35660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問