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

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

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

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

Q&A

解決済

4回答

3668閲覧

コンパイルは通るけど実行過程でエラーが出て終了する

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2016/03/16 04:33

コンパイルは通るのですがコードretryのところで
0 か 1を選んでも表示がでなくて1を押すと
エンター2回押しで再実行できるのですが
0を押すとエラー表示がでて終了
します。エンターキー1回押しで実行したいのですが
教えてください。MinGWで実行しています。

C:\Users\username\chap09\kadai\kadai9-2>gcc -I. -o lacknum3 lackn

um3.c pdcurses.a

C:\Users\username\chap09\kadai\kadai9-2>lackn

um3
欠けている数字を入力してください。
スペースキーで開始します。
3 4 6 9 5 1 7 :8
2 1 9 5 3 7 8 :6
7 2 9 6 4 5 1 :8
1.2秒かかりました。
素早いですね。
最高得点(所要時間)を更新しました!!
もう一度しますか … (0)いいえ (1)はい:エラー発生!!

/* ラックナンバーサーチ・トレーニング(その3:前回の日時・最高得点を表示)*/ #include <time.h> #include <float.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include "getputch.h" #define MAX_STAGE 3 #define swap(type, x, y) do { type t = x; x = y; y = t; } while (0)//この処理は常に1回しか実行されずしかも内容がない。 char dtfile[] = "LACKNUM.DAT"; /* ファイル名 */ /*--- 前回のトレーニング情報を取得・表示して最高得点を返す ---*/ double get_data(void) { FILE *fp; double best; // 最高得点 if ((fp = fopen(dtfile, "r")) == NULL) { printf("本プログラムを実行するのは初めてですね。\n\n"); best = DBL_MAX; /* float.hに定義されている。double型で表現できる最大値を表すマクロDBL_MAX */ } else { int year, month, day, h, m, s; fscanf(fp, "%d%d%d%d%d%d", &year, &month, &day, &h, &m, &s); fscanf(fp, "%lf", &best); // stream(fp)が指すストリームから&bestに読み込む //fscanf 関数は format が指す書式文字列に従って //stream(fp) が指すストリームからデータを読込み, //format(&year, &month, &day, &h, &m, &s) に続く引数の指すオブジェクトに代入します. printf("前回の終了は%d年%d月%d日%d時%d分%d秒でした。\n\n", year, month, day, h, m, s); printf("これまでの最高得点(最短所要時間)は%.1f秒です。\n\n", best); // 画面が一瞬で消えてしまうのを防止 // 一瞬で画面が消えてしまう場合には、 // 以下の文を入力します。 //fflush(stdout); fclose(fp); } return (best); } /*--- 今回のトレーニング情報を書き込む ---*/ void put_data(double best) { FILE *fp; time_t t = time(NULL); //時間を取得する関数は time_t time(time_t *) と clock_t clock(NULL) があります。 //time() の戻り値は time_t 型、 clock() の戻り値は clock_t 型です。 //これらの型は time.h の中で定義されています。 普通は long 型として定義されていますが、 //これらの型はそれぞれの時間を表しきれる精度を持った型という意味 //time(time_t *) は精度は低いですがプロセスの切り替えに影響されず実時間を取得できます。 //time() で時間を取得するときは(変数 t に入れるとする)time(&t); //t=time(NULL); //time(&t); struct tm *local = localtime(&t); if ((fp = fopen(dtfile, "w")) == NULL) printf("エラー発生!!"); else { fprintf(fp, "%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); fprintf(fp, "%f\n", best); fclose(fp); } } //--- トレーニングに要した所要時間を返す --- 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; // 開始時刻・終了時刻 // clock() の精度は機種に依存しますが // 大体 1ms 単位程度の精度があるようです // clock() の戻り値は、秒以下の単位まで整数型で表せるように // 適当な整数が掛けられています。 その適当な整数とは // time.h の中で CLOCKS_PER_SEC という定数として定義されています。 // ですから、 clock() で得られた値を CLOCKS_PER_SEC で割ると秒数が求まります。 // clock() で求まる時間はそのプロセスが消費したプロセッサ時間になります。 // 一方、time(time_t *) で求まる時間は歴時間です。 printf("\n欠けている数字を入力してください。\n"); printf("スペースキーで開始します。\n"); while (getch() != ' ') ; start = clock(); // clock() の戻り値は、秒以下の単位まで整数型で表せるように // 適当な整数が掛けられています。 その適当な整数とは // time.h の中で CLOCKS_PER_SEC という定数として定義されています。 // ですから、 clock() で得られた値を CLOCKS_PER_SEC で割ると秒数が求まります。 // clock() で求まる時間はそのプロセスが消費したプロセッサ時間になります。 for (stage = 0; stage < MAX_STAGE; stage++) { int x = rand() % 9; // 0~8の乱数を発生 ,1から9までのうち8文字を表示するための数字 int no; // 読み込んだ値 ,キーボードから打ち込んだ数字 i = j = 0; while (i < 9) { // dgt[x]を飛ばしてコピー if (i != x) a[j++] = dgt[i];// dgt[x]は1から9までの数字が入っている配列 i++; } for (i = 7; i > 0; i--) { // 配列aをシャッフル、配列の添字は0から7までの8個である int j = rand() % (i + 1); // 配列aの添字は0から7までの8個である。jは1から7まで変化する if (i != j) // jは1から7まで変化する。iとjの添字でシャッフルする。 swap(int, a[i], a[j]); } 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 = clock(); jikan = (double)(end - start) / CLOCKS_PER_SEC; // clock() で得られた値を CLOCKS_PER_SEC で割ると秒数が求まります。 // clock() で求まる時間はそのプロセスが消費したプロセッサ時間になります。 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; // もう一度? double score; // 今回のトレーニングの所要時間 double best; // これまでのトレーニングの最短所要時間 best = get_data(); // 前回までの最短所要時間を得る init_getputch(); srand(time(NULL)); // 乱数の種を初期化 do { score = go(); // トレーニング実行で帰ってくる値は score=double jikan;である。 if (score < best) { printf("最高得点(所要時間)を更新しました!!\n"); best = score; // 最短所要時間の更新 } printf("もう一度しますか … (0)いいえ (1)はい:"); scanf("%d",&retry); } while (retry == 1); put_data(best); // 今回の日付・時刻・得点を書き込む term_getputch(); return (0); }

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

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

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

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

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

guest

回答4

0

scanf("%d",&retry);
を以下のように変更しました
retry=getch()-'0';
printf("%d",retry);

投稿2016/03/16 08:52

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

こんにちは。

cursesを持っていないので、getch()→getchar()、putch()→putchar()に置き換え、init_getputch()とterm_getputch()を外して、MinGW 5.2.0でやってみました。
入力する度に1回Enterを押す必要はありますが、正常に動作しているようです。
Enterを押す必要があるのは、Windowsの仕様です。
cursesが提供するgetch()等に何か問題があるのかも知れません。

標準入出力のバッファリングを解除できれば、恐らく意図されている通りの動作になると思うのですが、分かりません。

投稿2016/03/16 05:53

Chironian

総合スコア23272

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

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

0

ベストアンサー

「エラー発生!!」と表示されるのはファイル保存できなかった時のようなので
パーミッション等を確認されては如何でしょうか。
もしくは保存先のパス(動作中のカレントディレクトリ)が期待通りか表示するなど
して確認してみるといいかもしれません。
エンター2回押しの件については

c

1 scanf("%d\n",&retry); 2 3```としてみたら改善されたりしませんかね? 4ダメそうならいっそ他同様に getch で入力した方が良いかもしれません。

投稿2016/03/16 05:14

HiroshiWatanabe

総合スコア2160

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

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

退会済みユーザー

退会済みユーザー

2016/03/16 08:39

アリガトウございます変数間違いと文字と数字の勘違いでした
guest

0

scanf()で数値だけを取ると、数値の後に続く改行コードが行末に残ってしまいます。これを適当な方法で読み捨てるか、fgetsで1行取得してから数値をsscanfで取るなど、何かしらの対策が必要となります。

投稿2016/03/16 04:51

maisumakun

総合スコア145121

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

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

退会済みユーザー

退会済みユーザー

2016/03/16 05:24

ありごとうございます具体的にscanf()のコードのあとにどんなコードを書けばいいのでしょうか? こういうretryのコードがほかにもあるのですが、以前は通っていたコードで正常に0,1が表示されていました、プログラムをいじっていてどこかが変わったのだと思うのですがよろしくお願いします
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問