Emacs端末上で、Cプログラムが適切に動作しない

このQ&Aのポイント
  • EmacsのシェルモードでCygwinのgccを使用してCプログラムをコンパイルしようとすると、プログラムが正常に動作しない問題が発生しています。
  • 作成したプログラムがEmacsのシェルモードで実行されると、出力操作が全ての入力操作の後に行われるため、正しい結果が表示されません。
  • 同様の問題は、Emacsのシェルモードを使用してCプログラムを実行するだけでなく、他の端末上でも発生します。解決策を求めています。
回答を見る
  • ベストアンサー

Emacs端末上で、Cプログラムが適切に動作しない

こんにちは。 OSは現在、64bit版のWindows7を使っており、Emacsは、Gnu Emacs for Windows 23.4 を使っています。 Emacsのシェルモード(「M-x shell」で起動するモード)では、シェルとしてCygwinに付属しているbashを使い、C言語のソースをコンパイル(あるいはビルド)する場合は、Cygwinのgccを使おうと考えています。 ところが、ビルドしたプログラムをEmacsのシェルモードで実行すると、上手く起動しないので困っています。 具体的には、以下の通りです。 まず、テスト用のCソースファイルとして、以下のような、test.cを作成しました。 ------------------------------------------------------------ #include <stdio.h> int main(void) { int num=2; printf"Enter integer: "); scanf("%d", &num); printf("Number enterd: %d", num); } ------------------------------------------------------------ これをシェルモードで、gccを使ってビルドし、作成されたa.exeを実行すると、以下のようになりました。 [TERM=emacs] ------------------------------------------------------------ Kei-Lavie@Kei:~/C_Programs $ gcc test2.c Kei-Lavie@Kei:~/C_Programs $ ./a.exe 20 Enter integer: Number enterd: 20 ------------------------------------------------------------ 作成された実行ファイルのa.exeを実行すると、まず Enter integer: と表示されるはずなのですが、それが表示されず、止まります。 そこで、整数として適当に20を入力してみると、 Enter integer: Number enterd: 20 と出力されました。 どうやら、必要な入力操作が終わってから、全ての出力操作が行われるようです。 その事を確認するために、先ほどのtest.cのmain関数を、以下のように変更し、数値を入力する場面を2箇所設けました。 ------------------------------------------------------------ int main(void) { int i=2; double d=0.1; printf("Enter integer: "); scanf("%d", &i); printf("Integer enterd: %d", i); printf("\n"); printf("Enter number: "); scanf("%lf", &d); printf("Number enterd: %f", d); } ------------------------------------------------------------ これをシェルモードで、gccを使ってビルドし、作成されたa.exeを実行すると、以下のようになりました。 [TERM=emacs] ------------------------------------------------------------ Kei-Lavie@Kei:~/C_Programs $ gcc test.c Kei-Lavie@Kei:~/C_Programs $ ./a.exe 20 0.123456789 Enter integer: Integer entered: 20 Enter number: Number entered: 0.123457 ------------------------------------------------------------ 作成された実行ファイルのa.exeを実行すると、まず Enter integer: と表示されるはずなのですが、それが表示されず、止まります。 そこで、整数として20を入力してみても止まったままです。 そして浮動小数点数として0.123456789を入力すると、 Enter integer: Integer entered: 20 Enter number: Number entered: 0.123457 と出力されました。 やはり、必要な全ての入力操作が終わってから、最後に全ての出力操作が行われるようです。 しかし、作成されたa.exeを、ktermといった端末上で実行すると、プログラムは以下のように適切に動作します。 [TERM=kterm] ------------------------------------------------------------ Kei@Kei-Lavie /cygdrive/c/Emacs_for_Windows/C_Programs $ ./a.exe Enter integer: 20 Integer entered: 20 Enter number: 0.123456789 Number entered: 0.123457 ------------------------------------------------------------ つまり、上記のように、作成されたプログラムが適切に動作しない問題は、Emacs端末に固有のもののようです。 上記のような問題を解決しようといろいろ試していると、kterm上で、a.exeの出力を、catやnkfといった出力コマンドにパイプすると、上記のような問題と同じ動作をしました。 具体的には以下の通りです。 [TERM=kterm] ------------------------------------------------------------ Kei@Kei-Lavie /cygdrive/c/Emacs_for_Windows/C_Programs $ ./a.exe |nkf 20 0.123456789 Enter integer: Integer entered: 20 Enter number: Number entered: 0.123457 ------------------------------------------------------------ 以上のような事から、どうやらEmacsのシェルモードでは、プログラムの出力を、catなどの出力コマンドにパイプしているのだと予想されます。 そこで、シェルモードの動作を決めると思われる、shell.el(あるいはshell.elc)やcomint.el(あるいはcomint.el)の内容を見てみたのですが、複雑すぎて、どの部分がEmacs端末上での出力に関与しているのかが分かりませんでした。 どうしてもEmacsのシェルモードを使って、C言語での開発を行いたいと思っていますので、 以上の件について、同じような経験をされた方、あるいは、何か解決策としてのご提案がある方は、是非、投稿をお願い致します。 自力では解決できそうにないので、どうか力をお貸しください。 よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.1

症状からするとstdoutのバッファリングの問題だと思いますのでprintf()の後にfflush(stdout)するなり、(printf()より前に)setbuf()やsetvbuf()でstdoutのバッファリングモードをバッファリングなしに変更するなどしてみてください。

MetalLover
質問者

お礼

御回答ありがとうございます。 setbuf()やsetvbuf()といった関数があるなんて知りませんでした。 これらの関数をググって、使ってみると、プログラムが適切に動作するようになりました。 wormholeさん、プログラミングの熟練者さんですね。 すごいと思います。 僕はソフトウェア開発の仕事に携わることになったので、 プログラミングについて必死に勉強しています。 これからも、自分で解決できない問題がありましたら、OK Waveで質問させて頂きたいと思います。 恐縮ですが、その時は是非、よろしくお願い致します。 本当にありがとうございました。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

解決策は #1 で終わってます (というか, これ以上は手の出しようがない) が, 念のため補足しておくと stdout では「改行が出力されない場合」に表示されることは保証されていません.

関連するQ&A

  • Emacsを「既定のプログラム」として設定できない

    こんにちは。 OSは現在、32bit版のWindowsVista(SP2)を使っています。 拡張子をtxtやdatなどに設定しているテキストファイルを開くときに、 ファイルを右クリックして「プログラムから開く」を選択して現れるウィンドウで、 「参照」ボタンをクリックすると、エクスプローラが開き、ローカルコンピュータ上にあるプログラム(exe)を選択できます。 この時、選択したプログラム(例えばWordやExcelなど)が、「他のプログラム」の一覧に追加されるはずです。 ところが、現在僕が使用しているエディタの「Gnu Emacs for Windows 23.4」の実行ファイルである「emacs.exe」を選択しても、先程の「他のプログラム」の一覧に現れないのです。 (以前、Perlを既定のプログラムに設定しようとした時にも、同じ現象が起こりました。) もしかすると、コンピュータにインストールされていないソフトは、既定のプログラムとして使えないのかと思ったのですが、そうでもないようなのです。 一体どうすれば、「Gnu Emacs for Windows 23.4」の実行ファイルである「emacs.exe」を、テキストファイルを開くときの既定のプログラムとして、設定する事ができるのでしょうか? 何か御存じの方がいらっしゃれば、是非、情報を提供して頂きたく思います。 では、よろしくお願い致します。

  • Emacsでのgccのインクルードパスの設定方法

    こんにちは。 Emacsは、Gnu Emacs for Windows 23.4 を使っています。 gccのインクルードパスの問題により、Emcasのcompileコマンドで、Cのソースファイルをコンパイルするができなくて困っています。 具体的には、CのソースファイルをEmacsで開き、「M-x compile」と入力した後、ミニバッファで「gcc -c test.c」と入力すると、以下のようなコンパイルエラーが表示されます。 ------------------------------------------------------------ gcc -c test.c test.c:1:19: no include path in which to search for stdio.h Compilation exited abnormally with code 1 at Sun Jul 08 18:24:05 ------------------------------------------------------------ どうやら、インクルードパスが設定されていないようです。 ちなみに、test.cは以下のような非常に単純なCプログラムです。 ------------------------------------------------------------ include <stdio.h> int main(void) { printf("Hello!\n"); return 0; } ------------------------------------------------------------ コマンドプロンプトや、ktermといった端末から、同じように gcc -c test.c というコマンドを実行すると、エラーが出る事はなく上手くコンパイルできますので、 適切なインクルードパスが設定されているはずです。 どうすれば、Emacsのcompileコマンドから、gccでコンパイルを行う時に使われる、インクルードパスを設定する事ができるのでしょうか? (gccの-Iオプションで、毎回インクルードパスを設定する必要をなくす方法が知りたいです。) では、よろしくお願い致します。

  • Emacsのシェルでpythonの対話モード…

    windows10上でEmacs26.3を使っています。 Emacsのシェル上でpythonの対話環境を開こうとしてもできません。 Emacs上でM-x shellなりM-x eshellなりM-x powershellなりでシェルを開いて、 画面が C:\Users\Username> 等となっている状態で、 C:\User\Username>python と打ってエンターを押しても、ただ改行されるだけで起動しません。 python以外でも、juliaやstack ghci(haskellの対話モード起動する)でも変な挙動になります。 普通のコマンド類(cdやdirなど)は問題なく使えます。 Emacs上ではなく普通にコマンドプロンプトやpowershellでなら普通にpython対話モードを起動できます。 どうすれば上手く起動するでしょうか。

  • Windows 用 Emacs で、shell で困ってます

    perl のプログラムを、Emacs の shell で実行すると,打ったコマンドが、次の行に現れて、プログラムがうまく動いてくれません。たとえば、 print "Enter a first number: "; chomp($one = <STDIN>); の部分が、プリントされないのです。何も表示されてないところへ、数を入力すると、最後にまとめてプリントされます。  Emacs をカスタマイズすれば直るものでしたら、嬉しいんですが。  ちなみに、perl は、Active Perl です。 どなたか、わかる方がおられましたら、ご教示願います。

  • C言語の四則演算プログラムについて

    こんにちは。hayato2192といいます。 今回は、C言語についてのことを質問したいとおもいます。 MSN相談箱の質問の中で数ある四則演算プログラムに対する質問をみたのですが、僕がつくろうとしているプログラムとはまったくちがいました。 プログラムコードは以下です。 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #include <stdio.h> main() { int d1, d2; char op; printf("START PROGRAM : Arithmetic operation\n"); printf("ENTER THE NUMBER\n"); scanf(" %d", &d1); printf("ENTER THE OPERATOR\n"); scanf(" %c", &op); switch (op) { case '+': printf("ENTER THE NUMBER\n"); scanf(" &d", &d2); printf("ANSWER IS %d\n", d1+d2); break; case '-': printf("ENTER THE NUMBER\n"); scanf(" &d", &d2); printf("ANSWER IS %d\n", d1-d2); break; case '*': printf("ENTER THE NUMBER\n"); scanf(" &d", &d2); printf("ANSWER IS %d\n", d1*d2); break; case '/': printf("ENTER THE NUMBER\n"); scanf(" &d", &d2); printf("ANSWER IS %d\n", d1/d2); break; default: printf("NO ANSWER\n"); break; } return 0; } \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 使っている関数はscanf printf switchだけというとてもシンプルなプログラムなのです。 じっさい、このプログラムをBorlandのコンパイラでコンパイルすると、switch関数がまったく使われずに、演算子(このプログラムでいうOPERATORです)を入力するところで終了してしまいます。 どのように直せばよいのでしょうか。教えてください

  • Emacsのshellモードに関する質問

    Emacsのshellモードにに関する質問 こんにちは。 Emacsは、Gnu Emacs for Windows 23.4 を使っています。 shellモードについて、2つ質問させて下さい。 ・cdといった、bashの組み込みコマンドが、日本語を対処できない。 shellモードのシェルとして、bashを使った場合、cdコマンドの引数に、 日本語を含むディレクトリを指定すると、 No such file or directoryと表示されて、目的のディレクトリに移動できません。 具体的には、以下のような感じです。 ------------------------------------------------------------ Kei-Valuestar@Kei:~/Make_Tests_for_C_Files $ls 2つの関数、1つのヘッダ make_01 make_02 make_03 make_04 make_05 make_06 make_07 make_08 make_09 デフォルトシンボル、組み込み関数一覧.url トリビアなmakefile入門.url Kei-Valuestar@Kei:~/Make_Tests_for_C_Files $cd 2つの関数、1つのヘッダ/ bash: cd: 2つの関数、1つのヘッダ/: No such file or directory ------------------------------------------------------------ 日本語環境は整えてあるので、lsコマンドでは、日本語ファイルがきちんと表示されていますし、日本語ファイル名の補完も上手く行くので、bashの組み込みコマンドである、 cdだけが、日本語を適切に扱えないのだと思います。 日本語も扱える、cdコマンド(exeファイル)は、どこかで配布されてないのでしょうか? ・moreやlessといったコマンドが、きちんと動作しない。 shellモードでは、コマンドプロンプトや、cygwinのbashを使うのですが、 どちらを使った場合でも、moreやlessといった、ファイルの内容をページごとに表示する コマンドを実行した時に1ページづつ表示されず、catコマンドを実行した場合と同じように、ファイルの内容が全て表示されてしまいます。 何か対処法は無いでしょうか? 以上の件で、何か御存じの方がいらっしゃれば、是非、情報を提供して頂きたく思います。 では、よろしくお願い致します。

  • C言語の勉強

    学校でLinuxのPCを使って、emacsと言うアプリケーションでc言語のプログラムを書いて、コンパイラでコンパイルして、ktermと言うアプリケーションで実行結果を出力しています。 これを自宅でも復習などでしたいのですが、自分のPCはWindows Vistaなのでいまいちやり方がwかりません。。。なにか変わりになるようなソフトを紹介してください。よろしくお願いします。 ちなみにプログラムは  #include<stdio.h> int main(void) { --- return(0)} みたいな感じです。よろしくお願いします。

  • Emacsのシェルモードでワイルドカードが使えない

    こんにちは。 Emacsは、Gnu Emacs for Windows 23.4 を使っています。 シェルモードのシェルには、cygwinのbashを使っているのですが、 bashで使えるはずのワイルドカードが、いくつか使えなくて、困っています。 bashのワイルドカードで、使えないものは、以下の通りです。 ?(pattern) 与えられたパターンが 0 回または 1 回現われるとマッチします。 *(pattern) 与えられたパターンが 0 回以上現われるとマッチします。 +(pattern) 与えられたパターンが 1 回以上現われるとマッチします。 !(pattern) 与えられたパターンいずれにも含まれないもの全てにマッチします。 これらのワイルドカードは、ktermなどの上では、きちんと使えます。 例えばkterm上で、 echo !(*.c) と打てば、.cで終わらないファイル名を持つ、ファイルの一覧が表示されます。 ところが、Emacsのシェルモードで、同じように echo !(*.c) と打つと、 emacs "bash: !: event not found" と表示されます。 同様に、 echo *(.c) と打った場合、 bash: 期待してない token `(' のあたりにシンタックスエラー と表示されます。 どうすれば、こういったワイルドカードを、シェルモードで使う事ができるのでしょうか? 何か御存じの方がいらっしゃれば、是非、情報を提供して頂きたく思います。 では、よろしくお願い致します。

  • ソースプログラムでの日本語使用について

    Windows10のパワーシェルでソースプログラムをコンパイルしていますが、そのソースプログラムの出力部で日本語を用いると文字化けてしまいます。出力部とは、C言語だったらprintf, Fortranだったらwrite文です。ここで文字化けを解消するにはどうしたらいいのでしょうか。 パワーシェルは日本語ファイル、フォルダに対応しており、ファイル名が日本語でも問題ないようです。また、ソース内のコメントは日本語でもOKです。ただ、ソースプログラムを実行するとその結果の出力が文字化けてしまうのですが。コンパイラオプションでしょうか。 Rubyはコメントでさえも日本語がUTF8でないとダメとか、いろいろ事情がありそうです。 あるC言語の解説本は冒頭部から思いっきり日本語出力となっており、それが対応できないのです。 使用しているコンパイラはGNU系のもので、gccなどです。よろしくお願いします。

  • vimのコマンドモードから実行すると違う動作

    こんにちは。 c言語で書いたプログラムをvimのコマンドモードからmakefileを使って実行すると,Terminalから実行した場合と違う,予期していない動作をします。以下がソースコードとmakefileです。 main.c #include <stdio.h> int main(int argc, char **argv) { char buf[32]; int number = 0; while(number != -1){ printf("Type any number: "); fgets(buf, sizeof(buf), stdin); sscanf(buf, "%d", &number); printf("You typed %d\n", number); } return 0; } makefile build: <tab>gcc main.c run: <tab>./a.out プログラムの内容は,-1が入力されるまでひたすら数字を読み取り,それを出力するだけの簡単なものです。これをTerminalで ./a.out と実行すると毎回"Type any number: "と出て数字を入力しては出力される、といった動作をします。しかしvimのコマンドモードで :make run と実行すると何を入力しても反応が無く、-1を入力(while loopから抜ける)した際にまとめて全部出力されます。以下のような感じです。 0 1 1 2 3 4 5 5 -1 Type any number: You typed 0 Type any number: You typed 1 Type any number: You typed 1 Type any number: You typed 2 Type any number: You typed 3 Type any number: You typed 4 Type any number: You typed 5 Type any number: You typed 5 Type any number: You typed -1 今のところ標準入出力を使わないプログラムで変な動作は確認していないですが、僕のvimの使い方が変なのか、makefileがおかしいのか他のなにかなのかよく分からないのでアドバイスをお願いできればと思います。その他プログラムの書き方に変なことがあればどんな指摘も歓迎です。

専門家に質問してみよう