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

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

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

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

Q&A

解決済

2回答

3676閲覧

main関数が途中でとまる

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2016/02/26 23:53

編集2016/02/27 05:51

プログラム実行でmain関数がbest= get_data(count); の実行後途中で止まり、enterキーで実行されるのですが、enterキー無しで最後まで実行したいのですが
どうしてとまるのか分からないので教えてくだい。

/* ラックナンバーサーチ・トレーニング 過去の履歴と最近の10回分だけを表示している。 */ #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[] = "LACKNUM.DAT"; char dtfile2[] = "LACKNUM2.DAT"; double score2; 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; struct tm local; if ((fp = fopen(dtfile, "rb")) == NULL) { printf("ファイルを作成します。\n\n"); best = DBL_MAX; } else { printf("最近の10回の点数とそれらの実行日時は\n\n"); for(i=ft-k; i>=ft-10*k; i -= k){ 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); } /*--- 過去のトレーニング情報を取得・表示して最高得点を返す ---*/ int get_data(int count) { FILE *fp; FILE *fp2; double best; double best2; int i,j=0; BEST_TEN best_ten[25]={0}; if ((fp = fopen(dtfile, "rb")) == NULL) { printf("ファイルを作成します。\n\n"); best = 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("countは%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過去のbestten\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); } fflush(stdin); fclose(fp); return count; } /*--- 今回のトレーニング情報を書き込む ---*/ void put_data(double best, double best2) { FILE *fp; FILE *fp2; 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); fwrite(&best, sizeof(double), 1, fp); fclose(fp); } if(best <= best2){ if((fp2 = fopen(dtfile2, "wb")) ==NULL){ printf("ファイルがあーりません"); fflush(stdout); }else{ fwrite(local, sizeof(struct tm), 1, fp2); fwrite(&best2, sizeof(double), 1, fp2); fclose(fp2); } } } /*--- トレーニングを実行して得点(所要時間)を返す ---*/ double go(void) { int i, j, stage; int dgt[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int a[8]; double jikan; clock_t start, end; printf("欠けている数字を入力してください。\n"); printf("スペースキーで開始します。\n"); while (getch() != ' ') ; start = time(NULL); for (stage = 0; stage < MAX_STAGE; stage++) { int x = rand() % 9; int no; i = j = 0; while (i < 9) { if (i != x) a[j++] = dgt[i]; i++; } for (i = 7; i > 0; i--) { int j = rand() % (i + 1); if (i != j) swap(int, a[i], a[j]); } printf("%d回目:", stage+1); for (i = 0; i < 8; 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"); return (jikan); } int main(void) { int retry,ndata,count=0; double score; double best; double jikan; FILE *fp; fpos_t ft; fpos_t kaime_p1; struct tm local ; int k,bango; int i, j, x, stage; int dgt[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int a[10]; int no; clock_t start, end; printf("1. ラックナンバーリサーチ\n"); printf("2. ダブルナンバーリサーチ\n"); printf("どのゲームを行いますか。番号を入力してください ==> "); scanf("%d", &bango); switch (bango) { case 1: ndata= get_data(count); printf("ndataは%d\n\n", ndata); 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); new_local_data(ft,k); fgetpos(fp,&ft); init_getputch(); srand(time(NULL)); do { score = go(); if (score < best) { printf("最短所要時間を更新しました!!\n"); best = score; } printf("もう一度しますか … (0)いいえ (1)はい:"); scanf("%d", &retry); } while (retry == 1); put_data(score,best); fclose(fp); term_getputch(); break; case 2: init_getputch(); srand(time(NULL)); printf("ダブっている数字を入力してください。\n"); printf("スペースキーで開始します。\n"); fflush(stdout); while (getch() != ' ') ; start = clock(); for (stage = 0; stage < MAX_STAGE; stage++) { x = rand() % 9; i = j = 0; while (i < 9) { a[j++] = dgt[i]; if (i == x) a[j++] = dgt[i]; i++; } for (i = 9; i > 0; i--) { 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 = clock(); jikan = (double)(end - start) / CLOCKS_PER_SEC; 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(); break; default: // 上記以外 printf("番号が不当です\n"); } return 0; }

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

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

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

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

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

otn

2016/02/27 00:07

プログラムは、コードを削って現象が再現する最小限のソースにするか、それが出来ないなら全部省略せずに書くか。
退会済みユーザー

退会済みユーザー

2016/02/27 05:09

いつもぐちゃぐちゃのコードですみません。全てのコードを載せました。
guest

回答2

0

質問の要点としては

printf("もう一度しますか … (0)いいえ (1)はい:");
scanf("%d", &retry);

で、0とenterキーとか、1とenterキー じゃなく、0 か 1 だけで先に進むようにしたい
ということですか?
そうなら、バッファリングしない設定をする必要が有ります。
UNIXならstty とか ioctl でやるんだったと思いますが・・・
「端末 バッファリング」などで、検索してみて下さい。

投稿2016/02/27 04:57

nob.

総合スコア711

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

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

退会済みユーザー

退会済みユーザー

2016/02/27 05:13

main関数の中でget_dataが実行された後止まるのですが。 エンターキーで最後まで実行されます。これをエンターキーを押さなくても 最後まで実行したいのです。
nob.

2016/02/27 12:13

enterキーなしでするなら、端末の入力制御を「バッファリングしない」に設定してください。 ioctl()を使う事になると思います。 標準入力、バッファリング、ioctl()、stty などで検索してみてかださい。
guest

0

ベストアンサー

こんにちは。

get_data()関数の中でscanf()等の標準入力から入力するコードが実行されているのだろうと思います。
もし、見当たらない時は、get_data()関数をご提示下さい。

質問とは無関係ですが、get_data(count)のcountはget_data()から値を受け取りたいのだろうと思いましたが、このままでは受け取れないです。countの値がコピーされてget_data()へ渡りますので。countへのポインタを渡す必要が有ります。


【追記】

enterキー無しで最後まで実行したいのですがどうしてとまるのか分からないので教えてくだい。

この原因は、get_data()関数最後の方にある、getchar();です。これがEnterキーの入力を待ちます。
1文字入力関数なので、Enter以外のキーでも良いように思えますが、実は標準入力はバッファリングされているため、Enterキーが押されるまで戻ってこないのです。Enterキーが押されてから、ユーザが入力した文字列が標準入力から読み出されるのです。

countの件ですが、get_data()の戻り値で戻していたのですね。それならば大丈夫です。
てっきり、バラメータの方で戻そうしているのかと勘違いしました。

投稿2016/02/27 00:20

編集2016/02/27 05:27
Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2016/02/27 04:27

いつもお世話になっています。int get_data(count)で返値をcountにしています。get_data(count)をのせます。
Chironian

2016/02/27 05:24

回答文に追記します
退会済みユーザー

退会済みユーザー

2016/02/27 05:59

こんにちは、何とか課題9-1が完成しましたが、いろいろ手直しするところがありますが 次回にしたいと思います。ご指摘のgetchar();をはずして動きました。ちなみに必要のないコードでした。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問