参考書「明解c言語 中級」の自由課題でエラーの原因がわかりません。
###発生している問題・エラーメッセージ
visual studio 2017で、ビルドは成功しています。 ただ実行時、retryしないを選択すると以下のエラーメッセージが表示されます。 Run-Time Check Failure #2 - Stack around the variable 'best' was corrupted.
###該当のソースコード
c
1 2/*ラックナンバーサーチ(前回の日時と過去のベスト10と過去10回の成績を記録)*/ 3 4#include <time.h> 5#include <float.h> 6#include <stdio.h> 7#include <stdlib.h> 8#include <ctype.h> 9#include <conio.h> 10 11#define MAX_STAGE 10 12#define swap(type, x, y) do{ type t = x; x = y; y = t; }while(0) 13 14char dtfile[] = "9_1_lacknum.txt"; 15 16 17/*ファイルから前回のデータを読み取る*/ 18void get_data(double *best, double *recent) { 19 FILE *fp; 20 int i; 21 22 if ((fp = fopen(dtfile, "r")) == NULL) { 23 printf("\n初めてプログラムを実行しました。\n"); 24 } 25 else { 26 int y, mon, d, h, m, s; 27 28 /*前回の日時の取得*/ 29 fscanf(fp, "%d%d%d%d%d%d", &y, &mon, &d, &h, &m, &s); 30 31 /*過去ベスト10を取得*/ 32 for (i = 0; i < 10; i++) { 33 fscanf("%f", &best[i]); 34 } 35 36 /*直近10回を取得*/ 37 for (i = 0; i < 10; i++) { 38 fscanf("%f", &recent[i]); 39 } 40 41 printf("\n前回の挑戦は%d年%d月%d日 %d時%d分%d秒でした。\n", y, mon, d, h, m, s); 42 printf("過去の最高記録(最短所要時間)は %0.2f です。\n", best[0]); 43 fclose(fp); 44 } 45} 46 47/*ファイルに実行時の時間と最高記録を書き込む*/ 48void put_data(double *best, double *recent) { 49 FILE *fp; 50 int i; 51 time_t t = time(NULL); 52 struct tm *local = localtime(&t); 53 54 if ((fp = fopen(dtfile, "w")) == NULL) { 55 printf("\nエラーが発生しました。\a\n"); 56 } 57 else { 58 /*実行日時の書き込み*/ 59 fprintf(fp, "%d %d %d %d %d %d\n", local->tm_year + 1900, local->tm_mon + 1, local->tm_mday, 60 local->tm_hour, local->tm_min, local->tm_sec); 61 62 /*ベスト10の書き込み*/ 63 for (i = 0; i < 10; i++) { 64 fprintf(fp, "%f ", best[i]); 65 } 66 fprintf(fp, "\n"); 67 68 /*過去10回の成績を書き込み*/ 69 for (i = 0; i < 10; i++) { 70 fprintf(fp, "%f ", recent[i]); 71 } 72 fprintf(fp, "\n"); 73 fclose(fp); 74 } 75} 76 77/*トレーニングの実行*/ 78double go(void) { 79 int i, j, stage; 80 int qnum[] = { 1,2,3,4,5,6,7,8,9, }; 81 int a[8]; 82 time_t start, end; 83 84 printf("\nスペースキーで開始します。\n"); 85 while (getch() != ' ') 86 ; 87 88 start = time(NULL); 89 90 for (stage = 0; stage < MAX_STAGE; stage++) { 91 int x = rand() % 9; 92 int no; 93 94 /*添え字xのqnumを飛ばして格納*/ 95 for (i = 0, j = 0; i < 9; i++) { 96 if (i != x) a[j++] = qnum[i]; 97 } 98 99 /*配列aをランダム配置にする*/ 100 for (i = 7; i > 0; i--) { 101 int j = rand() % (i + 1); 102 swap(int, a[i], a[j]); 103 } 104 105 /*問題表示*/ 106 for (i = 0; i < 8; i++) { 107 printf("%d ", a[i]); 108 } 109 putchar(':'); 110 fflush(stdout); 111 112 do { 113 no = getch(); 114 if (isprint(no)) { 115 putch(no); 116 if (no != '0' + qnum[x]) { 117 putch('\b'); 118 } 119 else { 120 printf("\n"); 121 } 122 fflush(stdout); 123 } 124 } while (no != '0' + qnum[x]); 125 } 126 end = time(NULL); 127 128 printf("\n%.2f秒かかりました。\n", difftime(end, start)); 129 130 return difftime(end, start); 131} 132 133/*得点データの更新*/ 134void update_score(double *a, double score, int n) { 135 int i; 136 137 for (i = 10; i > n; i--) { 138 a[i] = a[i - 1]; 139 } 140 a[n] = score; 141} 142 143int main(void) { 144 int i; 145 int retry; 146 int n; 147 double score; /*今回の得点*/ 148 double best[10]; 149 double recent[10]; 150 151 get_data(best, recent); 152 153 srand((unsigned int)time(NULL)); 154 155 for (i = 0; i < 10; i++) { 156 best[i] = DBL_MAX; 157 recent[i] = DBL_MAX; 158 } 159 160 do { 161 score = go(); 162 163 /*ベスト10を更新*/ 164 if (score < best[0]) printf("最高得点を更新しました!\n"); 165 for (n = 0; n < 10; n++) { 166 if (best[n] > score) { 167 update_score(best, score, n); 168 break; 169 } 170 } 171 172 /*過去10回を更新*/ 173 n = 0; 174 update_score(recent, score, n); 175 176 printf("\n best10 直近の10回\n"); 177 for (i = 0; i < 10; i++) { 178 printf("No.%2d:%.2f %.2f\n", i + 1, (best[i] != DBL_MAX) ? best[i] : 0, (recent[i] != DBL_MAX) ? recent[i] : 0); 179 } 180 181 printf("\nもう一度プレーしますか?\n"); 182 printf("はい...(0) いいえ...(1) :"); 183 scanf("%d", &retry); 184 } while (retry == 0); 185 186 put_data(best, recent); 187 188 return 0; 189} 190 191
###試したこと
エラーメッセージにあるとおり、bestに格納してある値等を変えて実行してみたのですがどうもうまくいかず。
###補足情報(言語/FW/ツール等のバージョンなど)
visual studio 2017使用
プログラムの目的は、
1~9の数字のうち欠けている数字を答える問題を10問解く時間をスコアとする。
前回実行日時とベスト10のスコア、直近10回のスコアをテキストファイルに出力する。
というものです。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/23 14:33
2017/07/23 15:18