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

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

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

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

Q&A

解決済

2回答

1768閲覧

ダブルナンバーリサーチでベストテンが順番に表示されない

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2016/03/19 03:56

編集2016/03/19 13:15
/* ダブルナンバーサーチ・トレーニング(最近の10回の日時とベストテンの表示) curses.hを使うにはhttp://bd.tank.jp/d/20071208.htmlにゃかもとの日記参を参照する ダブルナンバーリサーチの表示がbestten3は表示はされるのですが 順番になっていない。どこが悪いのかいろいろやったのですが どうしてもうまくいきません。とにかく正しい表示になるようにしたいです。 */ #include <stdio.h> #include <time.h> #include <float.h> #include <ctype.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include "getputch.h" #define MAX_STAGE 3 #define swap(type, x, y) do { type t = x; x = y; y = t; } while (0) #define MAX_NUM 10 char dtfile[] = "LACKNUM3.DAT"; char dtfile2[] = "LACKNUM4.DAT";/* 最高記録用のファイル */ typedef struct { int tm_year; int tm_mon; int tm_mday; int tm_hour; int tm_min; int tm_sec; double best; } BEST_TEN; // --------------- 比較用の関数 cmp ------------------- int cmpptr( const void *p, const void *q ) { return (*(BEST_TEN**)p)->best - (*(BEST_TEN**)q)->best; } // ---------------------------------------------------- //1回実行したとき進むポイントの大きさを求める int kaime_p(fpos_t* kaime_p1) { FILE *fp; struct tm local; double best; fp = fopen(dtfile, "rb"); fread(&local, sizeof(struct tm), 1, fp); fread(&best, sizeof(double), 1, fp); //ファイルポインタの位置を取得 fgetpos(fp,kaime_p1); //ファイルfpの現在のファイル位置を取得して // kaime_p1の示す場所に格納します。 printf("ファイルポインタの位置kaime_p1は「%d」です。\n",*kaime_p1); fclose(fp); return *kaime_p1; } //local のデータを新しい順にならべる。 void new_local_data(fpos_t ft,int k) { FILE *fp; // これまでの履歴を指すポインタ FILE *fp2; // これまでの最短所要時間を指すポインタ double best; //これまでの履歴の所要時間 double best2; //これまでの最短所要時間のベストテンも保存しておく int i; //構造体変数 localの大きさ struct tm local; if ((fp = fopen(dtfile, "rb")) == NULL) { printf("ファイルを作成します。\n\n"); best = DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ } else { printf("最近の10回の点数とそれらの実行日時は\n\n"); for(i=ft-k; i>=ft-10*k; i -= k){ //構造体変数 localの大きさkaime_p1で44 //ファイルポインタを先頭からiまで移動 fseek(fp,i,SEEK_SET); fread(&local, sizeof(struct tm), 1, fp); printf("%d年 %d月 %d日 %d時 %d分 %d秒\n", local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec); fread(&best, sizeof(double), 1, fp); printf("得点(所要時間)は%.1f秒\n\n", best); } printf("enterキーで開始します。\n"); fflush(stdin); getchar(); } fclose(fp); } /*--- 過去のトレーニング情報を取得・表示して最高得点を返す ---*/ double get_data(int *count) { FILE *fp; /* これまでの履歴を指すポインタ */ FILE *fp2; /* これまでの最短所要時間を指すポインタ */ double best; //これまでの履歴の所要時間 double best2; //これまでの最短所要時間 int i,j=0; BEST_TEN best_ten[100]={0}; if ((fp = fopen(dtfile, "rb")) == NULL) { printf("ファイルを作成します。\n\n"); best = DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ } else { struct tm local; double line[256]; printf("\n過去の履歴\n-------------------------- \n"); while((i = fread(&local, sizeof(struct tm), 1, fp)) > 0 ){ printf("%d年 %d月 %d日 %d時 %d分 %d秒\n", local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec); fread(&best, sizeof(double), 1, fp); printf("得点(所要時間)は%.1f秒\n\n", best); best_ten[j].tm_year=local.tm_year; best_ten[j].tm_mon=local.tm_mon; best_ten[j].tm_mday=local.tm_mday; best_ten[j].tm_hour=local.tm_hour; best_ten[j].tm_min=local.tm_min; best_ten[j].tm_sec=local.tm_sec; best_ten[j].best=best; j++; (*count)++; } printf("count1は%d\n\n", *count); } BEST_TEN *plst[*count]; for( i = 0; i < *count; i++ ) plst[i] = &best_ten[i]; qsort( plst, *count, sizeof(BEST_TEN*), cmpptr ); printf("\n過去のbestten3\n-------------------------- \n"); // 並べ替え後の内容を表示 for(i=0;i<10;i++){ printf( "%d年 %d月 %d日 %d時 %d分 %d秒 %.lf秒\n" ,plst[i]->tm_year+1900, plst[i]->tm_mon+1, plst[i]->tm_mday, plst[i]->tm_hour,plst[i]->tm_min,plst[i]->tm_sec ); printf("得点(所要時間)は %.1f秒です。\n\n", plst[i]->best); } best=plst[0]->best; fflush(stdin); fclose(fp); printf("count2は%d\n\n", *count); return best; } /*--- 今回のトレーニング情報を書き込む ---*/ void put_data(double best, double best2) { FILE *fp; //fpはfopenされたdtfileを指すポインタ FILE *fp2; //fp2はfopenされたdtfile2を指すポインタ、最短時間が格納されている time_t t = time(NULL); struct tm *local = localtime(&t); time(&t); local = localtime(&t); if ((fp = fopen(dtfile, "ab")) == NULL){ printf("ファイルがあーりません"); fflush(stdout); }else { fwrite(local, sizeof(struct tm), 1, fp); //fpに書き込む fwrite(&best, sizeof(double), 1, fp); //fpに書き込む fclose(fp); } if(best <= best2){ if((fp2 = fopen(dtfile2, "wb")) ==NULL){ printf("ファイルがあーりません"); fflush(stdout); }else{ //point配列にbestをいれ、best2をベスト2にいれる。dtfile[0]にbest1,dtfile[1]にbest2.....dtfile[9]にbest10 fwrite(local, sizeof(struct tm), 1, fp2); fwrite(&best2, sizeof(double), 1, fp2); fclose(fp2); } } } /*--- トレーニングを実行して得点(所要時間)を返す ---*/ double go(void) { int i, j, x,no,stage; int dgt[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int a[10]; double jikan; // 時間 clock_t start, end; // 開始時刻・終了時刻 printf("\n\nダブっている数字を入力してください。\n"); printf("スペースキーで開始します。\n"); while (getch() != ' ') ; start = time(NULL); for (stage = 0; stage < MAX_STAGE; stage++) { x = rand() % 9; /* 0~8の乱数を発生 */ i = j = 0; while (i < 9) { /* dgt[x]をダブらせてコピー */ a[j++] = dgt[i]; if (i == x) a[j++] = dgt[i]; i++; } for (i = 9; i > 0; i--) { /* 配列aをシャッフル */ int j = rand() % (i + 1); if (i != j) swap(int, a[i], a[j]); } for (i = 0; i < 10; i++) /* 全要素を表示 */ printf("%d ", a[i]); printf(":"); fflush(stdout); do { no = getch(); if (isprint(no)) { /* 表示可能であれば */ putch(no); /* 押されたキーを表示 */ if (no != dgt[x] + '0') /* 正解でなければ */ putch('\b'); /* カーソルを一つ戻す */ else printf("\n"); /* 改行 */ } } while (no != dgt[x] + '0'); } end = time(NULL); jikan = (double)difftime(end, start) printf("%.1f秒かかりました。\n", jikan); if (jikan > 25.0) printf("鈍すぎます。\n"); else if (jikan > 20.0) printf("少し鈍いですね。\n"); else if (jikan > 17.0) printf("まあまあですね。\n"); else printf("素早いですね。\n"); term_getputch(); return (jikan); } int main(void) { int retry,count=0; // もう一度? double score; // 今回の所要時間 double best; // 最短所要時間 double jikan; // 時間 FILE *fp; fpos_t ft; fpos_t kaime_p1; struct tm local ; int k; int i, j, x, stage; best= get_data(&count); // get_data()で前回までの最短所要時間を // ファイルから読み込んでbestに代入する。 printf("bestは%.1f1\n\n", best); printf("count3は%d\n\n", count); fp = fopen(dtfile, "rb"); kaime_p(&kaime_p1); k=kaime_p1; //ファイルポインタの位置を取得 printf("mainのkaime_p(&kaime_p1)後のkの値は「%d」です。\n\n",k); //ファイルポインタを末尾まで移動 fseek(fp,0,SEEK_END); //ファイルポインタの位置を取得 fgetpos(fp,&ft); //ファイルfpの現在のファイル位置を取得して // &ftの示す場所に格納します。 new_local_data(ft,k); fgetpos(fp,&ft); //best = get_data(ft); // get_data()で前回までの最短所要時間を //ファイルから読み込んでbestに代入する。 init_getputch(); //ライブラリの初期処理235p、initscr(),cbreak(),noecho(),refresh() srand(time(NULL)); // 乱数の種を初期化 do { score = go(); // トレーニング(go)で実行、返却された所要時間(jika)をscoreに代入する。 if (score < best) { printf("最短所要時間を更新しました!!\n"); best = score; /* 最高得点更新 */ } printf("もう一度しますか … (0)いいえ (1)はい:"); scanf("%d", &retry); } while (retry == 1); put_data(score,best); /* 今回の日付・時刻・得点を書き込む */ fflush(stdout); fclose(fp); term_getputch(); //ライブラリの初期処理235p,endwin() return 0; } /* 実行結果 C:\Users\username\chap09\kadai\kadai9-2>gcc -I. -o kad9_2_1b kad9_2_1b.c pdcurses.a C:\Users\username\chap09\kadai\kadai9-2>kad9_2_1b 過去の履歴 -------------------------- 2015年 10月 27日 19時 9分 59秒 得点(所要時間)は11.0秒 2016年 1月 4日 19時 15分 11秒 得点(所要時間)は8.0秒 ......省略...... count1は12 過去のbestten3 -------------------------- 2016年 1月 4日 19時 21分 44秒 0秒 得点(所要時間)は 8.0秒です。 2016年 1月 4日 19時 15分 11秒 0秒 得点(所要時間)は 8.0秒です。 2016年 3月 19日 11時 43分 16秒 0秒 得点(所要時間)は 7.8秒です。 2016年 1月 4日 19時 16分 8秒 0秒 得点(所要時間)は 9.0秒です。 2016年 1月 4日 19時 21分 11秒 0秒 得点(所要時間)は 10.0秒です。 2016年 1月 4日 19時 19分 7秒 0秒 得点(所要時間)は 10.0秒です。 2016年 1月 5日 21時 33分 29秒 0秒 得点(所要時間)は 10.0秒です。 2016年 3月 19日 11時 41分 52秒 0秒 得点(所要時間)は 10.7秒です。 2016年 1月 4日 19時 16分 39秒 0秒 得点(所要時間)は 10.0秒です。 2015年 10月 27日 19時 9分 59秒 0秒 得点(所要時間)は 11.0秒です。 count2は12 bestは8.0 cunt3は12 ファイルポインタの位置kaime_p1は「44」です。 mainのkaime_p(&kaime_p1)後のkの値は「44」です。 最近の10回の点数とそれらの実行日時は 2016年 3月 19日 11時 43分 16秒 得点(所要時間)は7.8秒 2016年 3月 19日 11時 41分 52秒 得点(所要時間)は10.7秒 ........省略........ enterキーで開始します */ コード

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは。

ざっと見てみました。2~3問題に気が付きました。

①startとendを取得する関数が異なる。前者はtime(NULL)、後者はclock()
たぶん、統一しないと適正な結果にはならないのでは?
②go()関数が常に0を返却してます。
これをキーにしてソートしているのでソートされないのではないかと思います。

後、データがない時、起動すると落ちます。
167行目のfor(i=0;i<10;i++){for(i=0;i<*count;i++){へ変更してとりあえず落ちませんでした。
(cursesを入れるのは手間なので、普通の関数で代用しました。)

たぶん、いいところまでできていると思います。頑張って下さい。

投稿2016/03/19 06:46

Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2016/03/19 10:28

いつもお世話になっています。 おっしゃる通りで修正してとおりましたので 全体のプログラムのかんせいです。去年からの自由課題9-1,9-2、9-3が完成します。 ラックナンバーリサーチができていましたので、コピーしてやったつもりでしたが 変更箇所にきずきませんでした。
退会済みユーザー

退会済みユーザー

2016/03/19 10:29

ありがとうございました(^^)
Chironian

2016/03/19 10:42

頑張り凄いですね。お疲れ様でした!!
退会済みユーザー

退会済みユーザー

2016/03/19 13:21

すみません1回成功したのですが、いろんなこののプログラムを 整理している最中、成功したものがどこかにいってしまい。 もとにもどってしまいました。いちおう教えていただいたとおりに 修正してみたのですが、大体ちさい順になっているのですが 順番がおかしいので、もう一度見ていただけませんか。 今日朝からやっていて、くたくたなんで、 あしたみなおすつもりですが、よろしくおねがいいたします
Chironian

2016/03/19 15:23

ちょっと見てみましたが、走らせるだけで一苦労です。 sanchu52さんの学習のために何故に私が苦労してデバッグしなければならないのか?という疑問もありますし、もう少し絞り込んでから再度ご質問頂けたらと思います。
退会済みユーザー

退会済みユーザー

2016/03/19 23:50

おしゃる通りでした。お忙しい方にお願いしてすみませんでした。 デバッグを少し勉強したいと思います。 これからの投稿には、ご返事は結構です。ありがとうございました。
guest

0

発想の転換の回答です。
書籍であれば飛ばして次に行くのも手ですね、また戻ってくればいいですし。


おそらく以下書籍の問題に基づいて質問をされている可能性がありそうですね。
プロフィールで確認致しました。
・柴田望洋著 新版明解C言語 中級編、実践編

投稿2016/03/19 04:08

lib

総合スコア446

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

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

退会済みユーザー

退会済みユーザー

2016/03/19 04:32

おしゃるとおりです。今飛ばすと余計わからなくなるとおもいます。 自由課題9-1,9-2,9-3をやっているところで 90%から95%できています。もっと複雑なんですが おかしいところだけ切り取って質問しています 600行ぐらいになっています。ありがとうございます ラックナンバーリサーチのベストテンは正常に表示になっているので ダブルナンバーも同じように書き直してやっているのですが、間、趣味ですので がんばってみます。 どこかが間違っていると思うのですが
lib

2016/03/19 15:05 編集

発想の転換の理由は暗に答えをもとめるのではなく、以下のポイントから再考の余地ありと判断したからですね。 ・頑張るのは構わないですが質問をした時点で相手の時間を奪うかもしれません。 →一人で頑張るのは趣味の時間としていれば特に異論はありません。 ・悩むのに1か月費やすのと1日費やすのをどっちを選ぶと聞かれたらどうしますか? ・時間をおいて、後で見直して気づくこともあります。(視点が客観的になるので) ただし非常におしい実装をしていたので、後で見直したら気づくかなーという考えもありました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問