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

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

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

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

Q&A

解決済

3回答

2216閲覧

番号を打ち込んでも表示されない。

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2017/07/02 07:09

編集2017/07/08 04:47
void pos_training(void)の /* ブロックを選択させる */ do { printf("番号(練習中止は99):"); scanf("%d\n", &temp); if (temp == 99) return; /* 練習中止 */ } while (temp < 1 || temp > 8); とMenu SelectMenu(void)のdo { printf("\n練習を選択してください。\n"); printf("(1) 単純ポジション (2) 複合ポジション\n"); printf("(3) C言語の単語 (4) 英会話 (0) 終了 :"); scanf("%d\n", &ch); } while (ch < Term || ch >= InValid); でprintf("番号(練習中止は99):")と(0) 終了 :のあとに番号が すぐに出てこないでenter2回押しで表示されますが、すっきりしないのですが。 番号を入力と同時に表示する方法をお願い致します。 /* 総合タイピング練習 1部省略しています*/ #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "getputch.h" #define NO 3 /* トレーニング回数 */ #define KTYPE 16 /* ブロック数 */ #define POS_LEN 10 /* ポジショントレーニングの文字数, 10個の文字がランダムに出題される */ /*--- 練習メニュー ---*/ typedef enum { Term, KeyPos, KeyPosComp, Clang, Conversation, InValid } Menu; /*--- 各ブロックのキー ---*/ const char *kstr[] = { "12345", "67890-^\\", /* 第1段 */ "!\"#$%", "&'()=~|", /* 第1段 [Shift] */ "qwert", "yuiop@[", /* 第2段 */ "QWERT", "YUIOP`{", /* 第2段 [Shift] */ "asdfg", "hjkl;:]", /* 第3段 */ "ASDFG", "HJKL+*}", /* 第3段 [Shift] */ "zxcvb", "nm,./\\", /* 第4段 */ "ZXCVB", "NM<>?_", /* 第4段 [Shift] */ }; /*--- 文字列strを表示してタイプ練習(ミス回数を返す) ---*/ int go(const char *str) { int i; int len = strlen(str); /* 文字数 */ int mistake = 0; /* ミス回数 */ for (i = 0; i < len; i++) { /* str[i]以降を表示してカーソルを先頭へ戻す,正解すると文字が1ずつ消えて行く */ printf("%s \r", &str[i]); while (getch() != str[i]) { /* getch()はタイプされた文字を返す */ mistake++; } } return (mistake); } /*--- 単純ポジショントレーニング ---*/ void pos_training(void) { int i; int stage; int temp, line; int len; /* 選ばれたブロックの文字列kstr[line]の長さlen 練習するブロックの文字数 */ int qno, pno; /* 問題番号・前回の問題番号 */ int tno, mno; /* 文字数・ミス回数 */ clock_t start, end; /* 開始時刻・終了時刻 */ printf("\n単純ポジショントレーニングを行います。\n"); printf("練習するブロックを選択してください。\n"); printf("第1段 (1) 左 %-8s (2) 右 %-8s\n", kstr[ 0], kstr[ 1]); printf("第2段 (3) 左 %-8s (4) 右 %-8s\n", kstr[ 4], kstr[ 5]); printf("第3段 (5) 左 %-8s (6) 右 %-8s\n", kstr[ 8], kstr[ 9]); printf("第4段 (7) 左 %-8s (8) 右 %-8s\n", kstr[12], kstr[13]); /* ブロックを選択させる */ do { printf("番号(練習中止は99):"); scanf("%d", &temp); if (temp == 99) return; /* 練習中止 */ } while (temp < 1 || temp > 8); line = 4 * ((temp - 1) / 2) + (temp - 1) % 2; /* 練習者が打ち込んだキーボードのブロック番号1,2,3,4,5,6,7,8 を *kstrの添字に変換する。出題するブロックの添字がlineに代入される temp=1のときline=0、temp=2のときline=1、temp=3のときline=4、temp=4のときline=5 temp=5のときline=8、temp=6のときline=9、temp=7のときline=12、temp=8のときline=13 */ printf("%d\n",temp); printf("%sの問題を%d回練習します。\n", kstr[line], NO); printf("スペースキーで開始します。\n"); while (getch() != ' ') ; tno = mno = 0; /* 文字数・ミス回数をクリア */ len = strlen(kstr[line]); /* 練習するブロックのキー数 */ start = clock(); /* 開始時刻 */ for (stage = 0; stage < NO; stage++) { char str[POS_LEN + 1]; /* strの長さPOS_LEN + 1はstrの最後に\0を入れるため+1している。 */ for (i = 0; i < POS_LEN; i++) /* 問題文字列を作成 */ str[i] = kstr[line][rand() % len]; str[i] = '\0'; /* strの最後に\0を入れる。 */ mno += go(str); /* 関数goから戻るとミス回数であるgoの返却値をmnoに加える */ tno += strlen(str); /* 出題した文字列の文字数をtnoに加える */ } end = clock(); /* 終了時刻 */ printf("問題:%d文字/ミス:%d回\n", tno, mno); printf("%.1f秒でした。\n", (double)(end - start) / CLOCKS_PER_SEC); } /*--- メニュー選択 ---*/ Menu SelectMenu(void) { int ch; do { printf("\n練習を選択してください。\n"); printf("(1) 単純ポジション (2) 複合ポジション\n"); printf("(3) C言語の単語 (4) 英会話 (0) 終了 :"); scanf("%d", &ch); } while (ch < Term || ch >= InValid); printf("%d\n",(Menu)ch); return ((Menu)ch); } int main(void) { Menu menu; /* メニュー */ init_getputch(); /* --- ライブラリ初期処理 --- static void init_getputch(void) { initscr(); //スクリーンを作成してライブラリ初期化する。cursesライブラリの利用時に最初に呼び出す cbreak(); //行バッファリングを行わないようにする noecho(); //タイプされたキーが画面に表示されないようにする refresh(); //画面を消去する } */ srand(time(NULL)); /* 乱数の種を初期化 */ do { switch (menu = SelectMenu()) { case KeyPos : /* 単純ポジショントレーニング */ pos_training(); break; case KeyPosComp : pos_training2(); break; case Term: break; case InValid: break; case Term: break; case InValid: break; //教科書のコードにはないが、コンパイルでwarningが出るので追加した。 } } while (menu != Term); term_getputch(); /* p235に説明ある */ /*--- ライブラリ終了処理 --- static void term_getputch(void) { endwin(); //ライブラリ終了処理用の関数で、Cursesライブラリの利用時に 最後に呼び出さなければならない(画面上の文字がすべて消えてしまう) } */ return (0); } /*実行結果 C:\MinGW\users\chap08>gcc -I. -o typing4-1 typing4-1.c pdcurses.a C:\MinGW\users\chap08>typing4-1 練習を選択してください。 (1) 単純ポジション (2) 複合ポジション (3) C言語の単語 (4) 英会話 (0) 終了 :1(enter2回押しで表示される。) 単純ポジショントレーニングを行います。 練習するブロックを選択してください。 第1段 (1) 左 12345 (2) 右 67890-^\ 第2段 (3) 左 qwert (4) 右 yuiop@[ 第3段 (5) 左 asdfg (6) 右 hjkl;:] 第4段 (7) 左 zxcvb (8) 右 nm,./\ 番号(練習中止は99):3(enter2回押しで表示される。) qwertの問題を3回練習します。 スペースキーで開始します。 qwretertwe (qが点滅で表示される。押すごとに消えていく) 問題:30文字/ミス:2回 33.4秒でした。 練習を選択してください。 (1) 単純ポジション (2) 複合ポジション (3) C言語の単語 (4) 英会話 (0) 終了 :0

C:\MinGW\users\chap08>

- /* getch/putch用ヘッダ "getputch.h" */ - - #if !defined(__GETPUTCH) - - #define __GETPUTCH - - #if defined(_MSC_VER) || (__TURBOC__) || (LSI_C) - - /* MS-Windows/MS-DOS(Visual C++, Borland C++, LSI-C 86 etc ...) */ - - #include <conio.h> - - static void init_getputch(void) { /* 空 */ } - - static void term_getputch(void) { /* 空 */ } - - - #else - - /* Cursesライブラリが提供されるUNIX/Linux/OS X */ - - #include <curses.h> - - #undef putchar - #undef puts - #undef printf - static char __buf[4096]; - - /*--- __putchar:putchar関数と同等(改行を[改行+復帰]で出力)---*/ - static int __putchar(int ch) - { - if (ch == '\n') - putchar('\r'); - return (putchar(ch)); - } - - /*--- putch:1文字表示してバッファを掃き出す ---*/ - static int putch(int ch) - { - int result = putchar(ch); - - fflush(stdout); - return (result); - } - - /*--- __printf:printf関数と同等(改行を[改行+復帰]で出力)---*/ - static int __printf(const char *format, ...) - { - va_list ap; - int count; - - va_start(ap, format); - vsprintf(__buf, format, ap); - va_end(ap); - - for (count = 0; __buf[count]; count++) { - putchar(__buf[count]); - if (__buf[count] == '\n') - putchar('\r'); - } - return (count); - } - - /*--- __puts:puts関数と同等(改行を[改行+復帰]で出力)---*/ - int __puts(const char *s) - { - int i, j; - - for (i = 0, j = 0; s[i]; i++) { - __buf[j++] = s[i]; - if (s[i] == '\n') - __buf[j++] = '\r'; - } - return (puts(__buf)); - } - - /*--- ライブラリ初期処理 ---*/ - static void init_getputch(void) - { - initscr(); - cbreak(); - noecho(); - refresh(); - } - - /*--- ライブラリ終了処理 ---*/ - static void term_getputch(void) - { - endwin(); - } - - #define putchar __putchar - #define printf __printf - #define puts __puts - - #endif - - #endif
*/

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

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

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

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

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

guest

回答3

0

その本は持ってないのでよく分かりませんが、getputch.hの内容は分かりますか? 多分、その中で宣言されているinit_getputch関数が内部で、キーボードのエコーを変更するなどしているのだと思います。よろしければヘッダの内容について追記願います。

参考(になるかもしれないURL)
https://oshiete.goo.ne.jp/qa/5527080.html

投稿2017/07/02 07:37

majiponi

総合スコア1720

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

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

yumetodo

2017/07/02 08:23

するとcbreak(), noecho()の呼び出しがあるから、それかも。
yumetodo

2017/07/02 08:23

C標準関数を呼ぶ前にbreakモードから戻すべきかもしらん。
退会済みユーザー

退会済みユーザー

2017/07/02 11:08

ありがとうございます。ヘッダの内容について追記をするには コードにgetputch.hを追加変更するのでしょうか? コードの文字数がギリギリなのでやってみます。
majiponi

2017/07/03 14:34

yumetodoさん、補足ありがとうございます。予感的中でした。調べてみたら、標準入出力と混ぜるな危険って書いてありました。解決法を簡単に言うなら、getch関数を使って同じ機能を自作する、ってとこでしょうか。 参考URL: https://www.kushiro-ct.ac.jp/yanagawa/ex/2-game/01.html 私がgetch関数の使い方を覚えたQuick C 2.0では混ぜても大丈夫だったのだが…環境依存って、怖いね。
yumetodo

2017/07/08 05:03

C標準関数を呼び出す前にnocbreak()とnoecho()して、呼び出したあとにcbreak(), noecho()を呼び出せば多分いけるとおもうのですがだめかなぁ
退会済みユーザー

退会済みユーザー

2017/07/08 05:20

ありがとうございます。コードのどこをどのようにするのでしょうか? "getputch.h" のなかをいじるのでしょうか。C標準関数を呼び出す前nocbreak()とnoecho()して、というのはコードのどの部分でしょうか?実際には具体的にどうするのでしょうか? nocbreak()、noecho()、cbreak(), noecho()についてはあとで教科書を読み直します。
yumetodo

2017/07/08 05:32 編集

>"getputch.h" のなかをいじるのでしょうか 違う >C標準関数を呼び出す前nocbreak()とnoecho()して、というのはコードのどの部分でしょうか? これ以上何を説明しろと・・・C標準関数を呼び出す前ですよ。どれがC標準関数かわからないなら全部の関数のmanを読みましょう。 ex. https://linux.die.net/man/3/noecho https://linuxjm.osdn.jp/html/LDP_man-pages/man3/printf.3.html >実際には具体的にどうするのでしょうか? nocbreak(); noecho(); C標準関数呼び出し cbreak(); noecho();
guest

0

scanfの安全性の回答とか出ててそういうのに注意する必要はあると思いますが、とりあえず質問の回答としてはscanfに"\n"を追加してみてはいかがでしょうか。

c

1scanf("%d", &ch); 23scanf("%d\n", &ch);

投稿2017/07/03 00:23

ttyp03

総合スコア16996

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

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

退会済みユーザー

退会済みユーザー

2017/07/03 06:48

アドバイスありがとうございます \nを追加しても状況はかわりませんんでした。 scanfの使い方に問題があるようですが、勉強不足でわかりませんが 何回か復讐しているうちわかるのではと思っています。
guest

0

ベストアンサー

scanf系関数で数値を読み込んではいけません。

C言語で安全に標準入力から数値を取得 - Qiita

ところで

c

1Menu SelectMenu(void) 2{ 3 int ch; 4 5 do { 6 printf("\n練習を選択してください。\n"); 7 printf("(1) 単純ポジション (2) 複合ポジション\n"); 8 printf("(3) C言語の単語 (4) 英会話 (0) 終了 :"); 9 scanf("%d", &ch); 10 } while (ch < Term || ch >= InValid); 11 12 13 return ((Menu)ch); 14 printf("line番号は%d\n",(Menu)ch); 15}

だけど、なんでreturn文のあとにまだコードがあるのかな・・・?コンパイラは警告を出してくれると思うんだけど。

投稿2017/07/02 07:13

編集2017/07/02 08:15
yumetodo

総合スコア5850

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

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

退会済みユーザー

退会済みユーザー

2017/07/02 11:03

ありがとうございます (Menu)chが表示されないのでそれを知るためにコードを入力しました。 return文の前に入れるといいのでしょうか?後で訂正します
yumetodo

2017/07/02 11:04

デバッガ使いましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問