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

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

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

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

Q&A

解決済

2回答

4235閲覧

構造体配列を構造体ポインタの配列を使って書き換えたいがうまくいかない。

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2017/10/07 08:26

実行ファイルkadai9-1aがとまってしまいます。とにかくmallocとリストを使ってget_data2を get_data2aに書き換えたい。どこを直すのか見当つかないのでご助言をおねがいします。mallocとリストの勉強は一通りおわっています。 コード void get_data2(int *count) { FILE *fp; FILE *fp2; int i; int year, mon, mday, hour, min, sec; double score; double bestscore; // 最高得点 TIME_DATA stars[MAXCNT]; // 構造体配列の宣言 if ((fp=fopen(dtfile,"rb"))==NULL){ printf("本プログラムを実行するのは初めてですね。\n\n"); bestscore = DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ exit(1); } else { for(i=0; i<MAXCNT; i++){ if(fscanf(fp, "%d %d %d %d %d %d %lf\n" , // 構造体配列への読み込み &stars[i].tm_year,&stars[i].tm_mon,&stars[i].tm_mday, &stars[i].tm_hour,&stars[i].tm_min,&stars[i].tm_sec,&stars[i].score)!=7) break; (*count)++; } printf("\ncount01:%d\n\n",*count); printf("前回の終了は%d年 %d月 %d日 %d時 %d分 %d秒 で\n\n", // 構造体配列への読み出し stars[*count-1].tm_year,stars[*count-1].tm_mon,stars[*count-1].tm_mday,stars[*count-1].tm_hour, stars[*count-1].tm_min,stars[*count-1].tm_sec,stars[*count-1].score); fflush(stdout); fclose(fp); } if ((fp2=fopen(dtfile2,"rb"))==NULL) { printf("本プログラムを実行するのは初めてですね。\n\n"); bestscore=DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ exit(1); } else { fscanf(fp2, "%d%d%d%d%d%d", &year, &mon, &mday, &hour, &min, &sec); fscanf(fp2, "%lf", &bestscore); // stream(fp)が指すストリームから&bestに読み込む //fscanf 関数は format が指す書式文字列に従って //stream(fp) が指すストリームからデータを読込み, //format(&year, &month, &day, &h, &m, &s) に続く引数の指すオブジェクトに代入します. printf("前回までの最高得点(最短所要時間)は%d年%d月%d日%d時%d分%d秒で\n", year, mon, mday, hour, min, sec); fflush(stdout); printf("これまでの最高得点(最短所要時間)は%.1f秒です。\n\n", bestscore); // 画面が一瞬で消えてしまうのを防止 // 一瞬で画面が消えてしまう場合には、//getchar(); // 以下の文を入力します。 fflush(stdout); fclose(fp2); } } //--- 前回までのトレーニング情報の最高得点を返す --- void get_data2a(int *count) { FILE *fp; FILE *fp2; int i; int year, mon, mday, hour, min, sec; double score; double bestscore; // 最高得点 //構造体ポインタの宣言 TIME_DATA *stars; //動的メモリの確保。確保したメモリをstars型ポインタにキャスト。 stars=(TIME_DATA*)malloc(sizeof(TIME_DATA)*(*count)); // メンバの初期化 stars->tm_year=0; stars->tm_mon=0; stars->tm_mday=0; stars->tm_hour=0; stars->tm_min=0; stars->tm_sec=0; stars->score=0; if ((fp=fopen(dtfile,"rb"))==NULL){ printf("本プログラムを実行するのは初めてですね。\n\n"); bestscore = DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ exit(1); } else { for(i=0; i<MAXCNT; i++){ if(fscanf(fp, "%d %d %d %d %d %d %lf\n" , // 構造体配列への読み込み &stars[i].tm_year,&stars[i].tm_mon,&stars[i].tm_mday, &stars[i].tm_hour,&stars[i].tm_min,&stars[i].tm_sec,&stars[i].score)!=7)break; (*count)++; } printf("\ncount01:%d\n\n",*count); printf("前回の終了は%d年 %d月 %d日 %d時 %d分 %d秒 で\n\n", // 構造体配列への読み出し stars[*count-1].tm_year,stars[*count-1].tm_mon,stars[*count-1].tm_mday,stars[*count-1].tm_hour, stars[*count-1].tm_min,stars[*count-1].tm_sec,stars[*count-1].score); fflush(stdout); fclose(fp); } if((fp2=fopen(dtfile2,"rb"))==NULL){ printf("本プログラムを実行するのは初めてですね。\n\n"); bestscore=DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ exit(1); }else{ fscanf(fp2, "%d%d%d%d%d%d", &year, &mon, &mday, &hour, &min, &sec); fscanf(fp2, "%lf", &bestscore); // stream(fp)が指すストリームから&bestに読み込む //fscanf 関数は format が指す書式文字列に従って //stream(fp) が指すストリームからデータを読込み, //format(&year, &month, &day, &h, &m, &s) に続く引数の指すオブジェクトに代入します. printf("前回までの最高得点(最短所要時間)は%d年%d月%d日%d時%d分%d秒で\n", year, mon, mday, hour, min, sec); fflush(stdout); printf("これまでの最高得点(最短所要時間)は%.1f秒です。\n\n", bestscore); // 画面が一瞬で消えてしまうのを防止 // 一瞬で画面が消えてしまう場合には、//getchar(); // 以下の文を入力します。 fflush(stdout); fclose(fp2); } }

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

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

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

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

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

guest

回答2

0

全体でどういう風にしようとしているのがわからないので、ここに挙げられた範囲内での回答ですが、get_data2の方では構造体の配列の要素数としてMAXCNTを指定していますが、get_data2aの方では引数で渡されたcountを個数として指定しています。どっちでやりたいのでしょう?
get_data2aの方ではcountの数の分しか確保されていないにも関わらず、構造体への読み込みのループでMAXCNT個分回そうとしています。おそらく、count < MAXCNTの状況になっており、読み込みのループで指してはいけないアドレスを指してしまって落ちているのではないかと。

デバッガを使って見てみてはいかがでしょうか。


#本題と関係ないところの話
get_data2aの方で、ファイルのオープンが失敗したときの処理の中に

C

1bestscore = DBL_MAX;

としていますが、次にexit()をコールしてプログラムを終了させてますよね。無駄な処理になってますよ。

投稿2017/10/07 12:11

archiver

総合スコア1557

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

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

退会済みユーザー

退会済みユーザー

2017/10/07 23:14

1日コードを眺めているとぼーっとなっていました。ありがとうございます。
guest

0

ベストアンサー

starsは構造体の配列のポインタなんですよね?
それでしたら、各要素にアクセスする必要があるのでは。

Before

C

1//構造体ポインタの宣言 2TIME_DATA *stars;

//動的メモリの確保。確保したメモリをstars型ポインタにキャスト。
stars=(TIME_DATA*)malloc(sizeof(TIME_DATA)*(*count));

// メンバの初期化
stars->tm_year=0;
stars->tm_mon=0;
stars->tm_mday=0;
stars->tm_hour=0;
stars->tm_min=0;
stars->tm_sec=0;
stars->score=0;

After

C

1//構造体ポインタの宣言 2TIME_DATA *stars; 3 4//動的メモリの確保。確保したメモリをstars型ポインタにキャスト。 5stars=(TIME_DATA*)malloc(sizeof(TIME_DATA)*(*count)); 6 7// メンバの初期化 8for(int i = 0; i < *count; i++) { 9 stars[i].tm_year = 0; 10 stars[i].tm_mon = 0; 11 stars[i].tm_mday = 0; 12 stars[i].tm_hour = 0; 13 stars[i].tm_min = 0; 14 stars[i].tm_sec = 0; 15 stars[i].score = 0; 16}

しかし、リスト構造を実現したいのなら、このような配列は用いないのでは?
また、どうせファイルから読み取るんですから、初期化は基本的に不要です。

投稿2017/10/07 10:46

LouiS0616

総合スコア35660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問