- 締切済み
C言語 共通ヘッダ作成の学習に関する事
共通ヘッダー作成の学習をしています。 共通ヘッダ <getputch.h> #ifndef __GETPUTCH #define __GETPUTCH #if defined(_MSC_VER) || (__TURBOC__) || (LSI_C) /* MS-Windows / MS-DOS系 */ #include <conio.h> #static void init_getputch(void) {} #static void term_getputch(void) {} #else /* Cursesライブラリが提供されるUNIX/Linux/macOS */ #include <curses.h> #include <stdio.h> #include <string.h> #undef getch #undef putchar #undef puts #undef printf #undef scanf static void init_getputch(void) { initscr(); refresh(); } static void term_getputch(void) { endwin(); } static int putch(int ch) { int result = addch(ch) == OK ? ch : EOF; refresh(); return result; } static int __putchar(int ch) { return putch(ch); } static int __printf(const char *format, ...) { int count; va_list ap; static char __buf[4096]; va_start(ap, format); vsprintf(__buf, format, ap); va_end(ap); count = printw("%s", __buf) == OK ? strlen(__buf) : EOF; refresh(); return count; } static int __puts(const char *s) { int count = printw("%s\n", s) == OK ? strlen(s) + 1 : EOF; refresh(); return count; } static int __getch(void) { int ch; cbreak(); noecho(); ch = getch(); nocbreak(); echo(); return ch; } #define getch __getch #define putchar __putchar #define printf __printf #define puts __puts #define scanf __scanw #endif #endif 私が使用しているOSはWindows10、 エディタ Visual Studio Code1.89.1 です。 コンパイルしたら<curses.h>のファイルが見つからない旨の エラーメッセージが出ます。 説明では、 _MSC_VER、__TURBOC__、LSI_Cは、それぞれVisualC++、 Borland C++(Turbo C++)、LSI Cの処理系で、処理系識別のために 独自に定義されているマクロです。 上記以外のMS-Windows用の処理系をお使いであれば、その処理系で 独自に定義されているマクロを追加する必要があります。 という事です。 もしかしたら、マクロを追加しないといけないのかもしれませんが 調べ方が分かりません。 どうしたら良いのでしょうか。ご指南を頂きたく投稿しました。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- superside0
- ベストアンサー率64% (461/711)
Windows上でgccでコンパイルしているから #if defined(_MSC_VER) || (__TURBOC__) || (LSI_C) のところで マッチしなくてcursesライブラリを使おうとしているが 原因なのはわかるとして 今度は gccでコンパイルことを判定させるように #defined (_MSC_VER) || (_TURBOC_) || (LSI_C) || (__GNUC__) なんてやってしまうと、gccはwindows専用じゃないから UNIX/Linux/MacOS やCygwinでgccコンパイルすると DOSコンソール以外では動かい実行ファイルになってしまって 別の問題がでますね。 案外 #ifdef _CONSOLE //DOSコンソール専用エスケープシーケンスで画面やカーソルの制御 #else //cursesを使う方(任意のターミナルタイプの制御ができるやつ) #endif にしたほうがシンプルかもですね。
- cametan_42
- ベストアンサー率62% (162/261)
何かから抜いてきたの? まず、curses.hなんだけど。 これはcursesってツールなんだけど、UNIX系のツールなのね。 Mac OS Xとか、LinuxだとOSに付いてくる付属ツールで、端末上での入出力を「自在に扱える」ライブラリなんだ。 curses: https://ja.wikipedia.org/wiki/Curses 一般に、プログラミング言語で扱える「標準入出力」ってのはどういう機能になってるか、と言うと、まぁ、端末がキーのアルファベット部分を入力として受け取って、「リターンキー」を叩くとその情報が読み込まれる、ってシステムじゃない?キーを叩いてEnterする。そうしないと処理がスタートせんわけだ。 一方、例えばローグってゲーム聞いた事があるかな?「不思議なダンジョン」「トルネコの大冒険」ってゲームの元ネタなんだけど。 ローグ: https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%82%B0 んでそのローグってゲームは端末(Windowsで言うとコマンドプロンプト/DOS窓)で遊ぶんだけど、自キャラはh 、j、 k、 l、 y、 u、 b、 nキーを叩いて移動させる。ここ注目。エンターキーを「叩いて」処理するわけじゃない。キー自体を叩く事で「移動」、つまりプログラミング上、「関数」が起動されて「自キャラ移動」が処理されている。 これは一般のプログラミング言語での「標準入出力」じゃあり得ない挙動だ。他にもコマンドとキーが「直接」結びついている。特定のキーを叩くと、プログラム的には「特定の関数」が起動して何らかを処理する。 つまり、cursesと言うライブラリはプログラミング言語が用意している「標準入出力」より下のレイヤーにアクセスしてるライブラリ、だと言う事なんだ。プログラミング言語の標準入出力では通常、特定のキーを「叩く」事がコマンドと直接結びつく事は「あり得ない」。そういうハードウェアに直接アクセスするような事を避けるデザインになってるのが「プログラミング言語」なんだけど、cursesはそういうハードウェアに直接アクセス出来るようなライブラリになっている。 他にも、「標準入出力」ってアイディアは、例えばカーソルキー(←↑↓→)は含まれない。こいつらは「プログラミング対象外」なんだ。と言うのも、「標準入出力」で言う「標準」ってのは、大昔、実は色んなタイプの総キー数が違うキーボードが山程あった時期に「どのキーボードでも備えてるキー」、と言う最大公約数的なキーを対象にしてます、って意味の「標準」なのね。その当時だとカーソルキーとかなかった、っつーかそんなん備えてるキーボードが少なかった。 他にもファンクションキーなんつのも「あったり」「なかったり」した。そういう時代だと「あるかどうか分からんキー」を対象にしてプログラムを書けないじゃない?だから「最大公約数」的な「どのキーボードでも最小限こういうキーはあるだろう」って言う前提で選定されてるのが、ここで言う「標準」なんだよ。 cursesってライブラリは、そういう「標準入出力」で定義されているキー以外も「操作対象」にしてるライブラリ、なんだ。それらにアクセスするには、やっぱりプログラミング言語が「想定」してる入出力機構の下のレイヤーにアクセスせなアカンわけ。ハードウェアを直接叩く。 また、そう考えるとUNIX上では、例えば「テキストエディタ」を作る際にもcursesってライブラリに頼らないとどーにもなんない、ってのが分かるでしょ?カーソルキーが「使えない」としたらカーソルがエディタ上で「動けない」って事になるわけじゃん(笑)。カーソルがないようなテキストエディタなんて「使い物にならない」じゃない(笑)。そういう「どうしてもプログラミング言語が扱う標準入出力を越えた入力を直接扱う」ためにはcursesってライブラリが無いとにっちもさっちも行かないわけだ。 それがUNIXに於けるcursesってライブラリの「役目」だ。そしてこれがWindowsにはない。 さて、個人的にはCは門外漢なんだけど。 > 私が使用しているOSはWindows10 > コンパイルしたら<curses.h>のファイルが見つからない旨の エラーメッセージが出ます。 と言う事を鑑みると、貴方が使ってるのがWindowsである以上、コンパイルしたら「通らなきゃならない」んだよね。 何故なら、 #if defined(_MSC_VER) || (__TURBOC__) || (LSI_C) ....... #else /* Cursesライブラリが提供されるUNIX/Linux/macOS */ #include <curses.h> とマクロが書かれている以上、#else以降が「実行されたら」ダメな筈なんだ。 コンパイルエラーが出てるのは、UNIX系「だったら」実行される部分が実行されてるから、に他ならない。 言い換えると、冒頭の #if defined(_MSC_VER) || (__TURBOC__) || (LSI_C) が、貴方が使ってる環境がWindowsのクセに無視されてる、って事だ。だから UNIX用の筈の#else節以降が実行されてコンパイルエラーが出てる。 もう一つ言うと、上の定義式は「OSがWindowsだった場合」を意図していない。あくまで_MSC_VER、__TURBOC__、LSI_Cってマクロが「存在した場合」って意味だ。存在してないから #else 以降が実行されてる、って見る事が出来る。 従って、 1. _MSC_VER、__TURBOC__、LSI_C、全部かあるいはその定義式(マクロ?)をどっかに書かなきゃならない。 あるいは、 2. どっかに_MSC_VER、__TURBOC__、LSI_C、を定義したファイルがあるんで、コンパイラにそれが書かれたファイルも合わせて指定してコンパイルせなアカン のどっちかが必要、って意味になるんじゃないか。 希望的観測から言うと2.だよな。貴方がどこからこのコードを引っ張ってきたか知らんけど、その「どこか」には_MSC_VER、__TURBOC__、LSI_Cの定義式が書かれたファイルも紹介されてんじゃないの?それを合わせてコンパイルせなどーにもならん、って可能性が結構高いと思うんだ。 あるいは、だ。・・・その本だかサイトだか知らんが、「かなり記述が古い」可能性があって、処理系備え付けのマクロを期待してるんだけど、それが現行のブツの記述と「違う」可能性もあるんだよな。 なんせ、Borland Turbo C使ってる人とか今は殆どいないだろ。LSI Cだって、僕の勘違いじゃなきゃ「かなり昔に流行った」処理系だ。ちょっと現代的な意味だと「候補に上がりづらい」処理系だと思う・・・って事は、言語処理系が何らかのマクロを提供してたとしても、もうその記述が変わってる可能性がある。 いずれにせよ、Windowsでの環境の筈なのに、UNIXでの部分が「実行されている」ってのがエラーの原因なんじゃないか。 【C】初めてのC言語(27. 定義済みマクロによるOS判定): https://qiita.com/nkojima/items/7698370cf4bd1d1f09d2
- _kappe_
- ベストアンサー率68% (1581/2304)
回答No.1の者です。 既に他の方の回答がついているように、Windowsでgccを使うにはいくつかの方法があり、cursesを使えるようにする方法も違ってきます。 ・MinGW ・Cygwin ・WSL など MinGWのgccを使っている場合を例にすると「MinGW curses.h」のようにネット検索すると情報が見つかります。
- luka3
- ベストアンサー率72% (424/583)
「curses.h windows」で検索してみるとか。 ただ、VCの情報が多いですね。 gcc利用ということで、cygwinをお使いなら「curses.h cygwin」で検索してみるとか。 https://vinarian.blogspot.com/2010/07/cygwincursestips.html >Cygwinのcurses.hは/usr/include/ncursesという変な場所にあります。 >「curses.hが見つからない」というエラーになるときは、gccの引数に >-I/usr/include/ncursesを加えてみましょう。 mingwなら、ncursesをインストールするようです。
- _kappe_
- ベストアンサー率68% (1581/2304)
>私が使用しているOSはWindows10、 >エディタ Visual Studio Code1.89.1 >です。 この場合に最も重要な情報である、コンパイラの種類について書かれていません。_MSC_VERが定義されていないようなのでVisual C++ではないのだろうという推測は可能ですが。
補足
コンパイラの種類は、gccです。 これでいいのでしょうか。