※ ChatGPTを利用し、要約された質問です(原文:Emacs端末上で、Cプログラムが適切に動作しない)
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言語での開発を行いたいと思っていますので、
以上の件について、同じような経験をされた方、あるいは、何か解決策としてのご提案がある方は、是非、投稿をお願い致します。
自力では解決できそうにないので、どうか力をお貸しください。
よろしくお願い致します。
お礼
御回答ありがとうございます。 setbuf()やsetvbuf()といった関数があるなんて知りませんでした。 これらの関数をググって、使ってみると、プログラムが適切に動作するようになりました。 wormholeさん、プログラミングの熟練者さんですね。 すごいと思います。 僕はソフトウェア開発の仕事に携わることになったので、 プログラミングについて必死に勉強しています。 これからも、自分で解決できない問題がありましたら、OK Waveで質問させて頂きたいと思います。 恐縮ですが、その時は是非、よろしくお願い致します。 本当にありがとうございました。