vimコマンドモードでのプログラム実行の違いとは?

このQ&Aのポイント
  • c言語で書いたプログラムをvimのコマンドモードからmakefileを使って実行すると、予期していない動作が発生します。
  • vimのコマンドモードでプログラムを実行すると、標準入出力の動作が異なります。
  • プログラムをTerminalから実行すると正常に動作する一方、vimのコマンドモードでは出力が遅れたり一括して表示されたりします。
回答を見る
  • ベストアンサー

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がおかしいのか他のなにかなのかよく分からないのでアドバイスをお願いできればと思います。その他プログラムの書き方に変なことがあればどんな指摘も歓迎です。

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

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

バッファリング関連だと思いますのでsetbuf等を使ってバッファリングを無効にするか、printfなどの出力毎にfflushでフラッシュしてみてください。

nasanaut
質問者

お礼

回答ありがとうございます.今回はfflushを使うことにしたので,ベストアンサーにさせて頂きました.

その他の回答 (1)

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.2

> :make run これだと errorfille に出力させた後で vim が読み直すか tee 絡ませて表示してるはずなので、普通のコマンド実行の方がいいと思います :!./a.out みたいに

nasanaut
質問者

お礼

返信ありがとうございます.指摘してもらったことについて調べてみて理解が深まったと思いますありがとうございます.

関連するQ&A

  • このプログラムの動作について教えてください

    #include<stdio.h> #include<unistd.h> #define SIZE 10 int main(int argc,char *argv[]){ int fd; char buf[SIZE]; fd=open("data",0); read(fd,buf,10) write(1,buf,10); close(fd); rerutn 0; } というプログラムで dataの中身が以下のテキストファイルとなっているようなのんですが dataの内容:abcdefghijklmnopqrstuvwxyz このプログラムの出力結果がabcabcabce となるとの事なのですが何故でしょうか? 普通に先頭から10バイト分読み込んで出力するならabcdefghijとなるのではないのでしょうか? どうぞご教授お願いします

  • vimのプラグインquickrunの使い方

    vimにquickrunをいれて使ってみたところ、 「/bin/bash: :コマンドが見つかりません 」 と実行結果の欄に表示されます。 一応プラグイン自体は動いているようなのですが… 試しに使ったのはこれです。 #include<stdio.h> int main(){ printf("Hello World!"); } OSはUbuntu 10.04です。 原因わかる方、お願いします。

  • 処理実行後、終了させないで最初に戻って何度も繰り返したいんですが

    例えば、 class exe{ public static void main(String args[])throws IOException{ BufferedReader Buf = new BufferedReader (new InputStreamReader(System.in)); System.out.println("整数を2つ入力して下さい"); String str1 = Buf.readLine(); String str2 = Buf.readLine(); int a = Integer.parseInt(str1); int b = Integer.parseInt(str2); System.out.println(a + "+" + b + "=" + (a + b)); } } というプログラム(要するにa+bの足し算)があると仮定します。 コマンドプロンプトでデバッグをしているのですが 結果を出力したあと、毎回java exeと入力して実行させてるので プログラムが終わらないで自動的?に また最初の「整数を2つ入力して下さい」に戻りたいのですが何か方法はありますか? forとかwhileとかを使うという意味ではなくて、プログラムを終わらせたくないっていう意味なんですが、 forやwhileを最初につけてcontinueもしくは条件を合わさないようにしてムリヤリ無限ループさせるしか方法はないでしょうか?

  • ■ ループ動作について ■

    以下のプログラムを実行したところ、下記の実行結果が出力されました。 入力:ABC 123 XYZ 567 ABC 123 XYZ 567 ここでの「%s」の書式では、空白文字は文字列として読み込まれません。 そのため変数「moji」には、「ABC\0」が入るかと思います。 実際の動作ではscanf関数が実行された後、for関数が初めに入力した空白で区切られた単語数分、再度繰り返され、putchar関数で改行を出力しています。 この動作がよく理解できませんでした。 一つしかない変数「moji」をどのように利用して出力しているのでしょうか? 細かな動作手順を教えていただける方、よろしくお願いいたします。 void main(void) { char moji[10]; int i; printf("入力:"); while(1) { scanf("%s", moji); for(i = 0; moji[i]; i++) { putchar(moji[i]); } putchar('\n'); } }

  • 実行結果の順番がおかしいんです・・・・・(。。;)

    現在C言語の勉強をしている初心者です。突然ですが 例えば、このようにプログラムしたら・・・ #include <stdio.h> int main(void) { int n; printf("何か数字を入力してください:"); scanf("%d",&n); printf("\n入力した数字は%dです。\n",n); return 0; } <<実行結果>>  何か数字を入力してください:2 [Enter]  入力した数字は2です。 って普通は出力されますよね??しかし、私の使っているBorland C++ Compiler 5.5 では <<実行結果>>  2 [Enter]  何か数字を入力してください:  入力した数字は2です。 っていう風に、まず、なにか入力しないとprintfの内容を出力してくれないんです。(汗)これって実行結果の順番がおかしいですよね・・・(。。;) どうかこの状態を直せるアドバイスをください。 よろしくお願い致します。m(__)m

  • scanfに文字が入力されたときにエラー表示させる

    こんばんは.C言語勉強中です. 以下にsizeofを用いて各データタイプのサイズを表示させるプログラムを作りました.プログラム全文は下に貼付けました.これは,1-7までのいずれかの数字を入力すると,それに対応したサイズが表示されます.1-7以外の数字が入力されると,Type 1 - 7, please,と表示され,再び数字を入力出来ます.このプログラムは数字を入力している間はうまく機能していると思います. ただ,文字を入力すると無限ループに陥ってしまいます.僕は以下の scanf("%d",&typed); で10進数で読み込んで, if(typed<1 || typed >7) とすれば,文字も含めて全ての入力に対して排除できるかと思ったのですが,これではダメなようです. こういう場合,どうやって文字の入力に対するエラーを表示させるのが一般的なのでしょうか? 素人質問ですみません.よろしくお願いします. #include <stdio.h> #include <stdint.h> #include <Windows.h> int8_t main() { int typed; while(1) { while(1) { printf("Type the data type you wanna know the size of\n"); printf("char 1, short 2, int 3, long 4, long long 5, float 6, double 7: "); scanf("%d",&typed); printf("What you typed is %d\n",typed); if(typed<1 || typed >7) { printf("Type 1 - 7, please\n"); Sleep(1000); continue; } else { break; } } printf("Data size is "); switch(typed){ case 1: printf("%d\n",sizeof(char)); break; case 2: printf("%d\n",sizeof(short)); break; case 3: printf("%d\n",sizeof(int)); break; case 4: printf("%d\n",sizeof(long int)); break; case 5: printf("%d\n",sizeof(long long)); break; case 6: printf("%d\n",sizeof(float)); break; case 7: printf("%d\n",sizeof(double)); break; default: printf("Unexpected Value!\n"); break; } Sleep(2000); } return(0); }

  • 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言語での開発を行いたいと思っていますので、 以上の件について、同じような経験をされた方、あるいは、何か解決策としてのご提案がある方は、是非、投稿をお願い致します。 自力では解決できそうにないので、どうか力をお貸しください。 よろしくお願い致します。

  • 実行

    こんにちは。私は昨日からC++を始めたのですがなかなかうまくいかないためこちらに質問させていただくことにしました。 #include <iostream.h> int main(void) { int x; int y; cout<<"xを入力: 10"; cin>>x; cout<<"yを入力: 2"; cin>>y; cout<<"x+yは"<<x+y<<"です。\n"; return(0); } このようなプログラムを作成したのですが実行してみたところ、 xを入力: 10 これ以降下までいきません。どうすればうまくいくのでしょうか?宜しくお願いします。

  • class Test_A {  main(){}}の実行順序は?

    public class Test_A { public static void main(){ int a = 0; int b = 1; } } 例えば上のようなサンプルで何故 main()がクラスTest_A の中に挟まっているのでしょうか?実行順序としては main()が終了したら、クラスTest_A の方はどうなるのでしょうか? main()からプログラムが始まるのは分かるのですが、その後の動作が分かりません。よろしくお願いします。 

    • ベストアンサー
    • Java
  • 選択により違う動作を実行する方法

    与えられた値により、下記のように貨幣の枚数を求めるソースを書きました。 /** * 与えられた金額を貨幣にした時の紙幣と硬貨の枚数を算出し、表示する。 * @author zhaohua.qiu * */ public class Ex1 { /** 貨幣タイプの定義 */ /* 紙幣の金種 */ private static final int[] NOTE_TYPES = {10000,5000,1000}; /* 硬貨の金種 */ private static final int[] COIN_TYPES = {500,100,50,10,5,1}; /** * 入力を確認し、結果を表示する * @param arg * @param i 入力したパラメータを格納する変数 */ public static void main(String[] args) { /* コマンドラインパラメータを指定したかのチェック */ if ( ! checkNyuryoku(args) ) { System.out.println("コマンドで金額を入力してください"); System.exit(1); //ここでプログラムは終了する } /* 入力した金額は半角数字かのチェック */ if ( ! isHalfNum(args[0]) ) { System.out.println("半角数値ではありません"); System.exit(2); //ここでプログラムは終了する } /* 入力した数値範囲のチェック */ int yen = 0; try { yen = Integer.parseInt(args[0]);//入力した値をint型に変換 }catch ( NumberFormatException e ) { System.out.println("数値が範囲外です"); System.exit(3); //ここでプログラムは終了する } int sumNote = getMoneyCountByType(yen, NOTE_TYPES); int sumCoin = getMoneyCountByType(yen - getAmountByType(yen, NOTE_TYPES), COIN_TYPES); System.out.println("紙幣:\t" + sumNote + "枚"); System.out.println("硬貨:\t" + sumCoin + "枚"); } /** * コマンドラインパラメータをチェックするメソッド * @param args 判定対象 * @return 結果(true:入力した/false:未入力) */ private static boolean checkNyuryoku(String[] args) { if ( args.length > 0 ) { return true; } return false; } /** * 半角数字正規表現のチェックするメソッド * @param str 判定対象 * @return 結果(true:正常/false:異常) */ public static boolean isHalfNum(String str) { if (str == null || !str.matches("^[0-9]+$")) { return false; } return true; } /** * タイプ別の総金額を取得するメソッド * @param yen 計算する値 * @param types 貨幣のタイプ * @return タイプ別の総金額 */ private static int getAmountByType(int yen, int[] types) { int amount = 0; for (int i : types) { amount += i * Math.floor(yen / i); yen = yen % i; } return amount; } /** * タイプ別の総枚数を取得するメソッド * @param yen 計算する値 * @param types 貨幣のタイプ * @return タイプ別の総枚数 */ private static int getMoneyCountByType(int yen, int[] types) { int countMoney = 0; for (int i : types) { countMoney += Math.floor(yen / i); yen = yen % i; } return countMoney; } } 実行して、枚数を表示した後、続いて「具体的紙幣と硬貨の枚数を表示しますか?_(Y/N)」のように使用者に聞いて、Nを選択した場合プログラムを終了させ、Yを選択した場合は下記のソースを実行し、結果を表示したいです。 public class Ex2 { public static final int[] YEN_TYPES = {10000,5000,1000,500,100,50,10,5,1}; public static int[] getYenCount(int yen) { int[] count = new int[YEN_TYPES.length]; for (int i = 0; i < YEN_TYPES.length; i++) { count[i] = yen / YEN_TYPES[i]; //商 yen = yen % YEN_TYPES[i]; //剰余 } return count; } public static void main(String args[]) { int yen = Integer.parseInt(args[0]); int[] count = getYenCount(yen); for (int i = 0; i < YEN_TYPES.length; i++) { if(count[i] != 0) { System.out.println(YEN_TYPES[i] + "円\t" + count[i] + "枚"); } } } } どうすれば、使用者に入力させ、その入力した値により上記の命令を実行させられますか? 教えてください。

専門家に質問してみよう