• ベストアンサー

stderrとstdout

次のようなプログラムを、./a.outと./a.out>out.txtのように実行したところ、前者は output1 後者は output1 output2 output3 のようになりましたが、なぜこうなるか理由がわかりません。 自分では、stderrとstdoutが関係してるのだと思うのですが、初心者なのでこれらがどういうプログラムなのかもよくわかっていません。どなかなぜこうなるのか教えていただけないでしょうか。 #include<stdio.h> int main(int argc,char **argv){ fprintf(stderr,"output1\n"); fprintf(stdout,"output2\n"); printf("output3\n") }

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

  • ベストアンサー
  • auty
  • ベストアンサー率58% (284/486)
回答No.2

・ C言語の初心者にとって、stderrとstdoutを理解することは基本的であり重要なことです。 1. fprintf(stderr,"output1\n"); 2. fprintf(stdout,"output2\n"); 3. printf("output3\n") ここで、3.は、2.の省略形であると考えてください。 そこで、1.と2.について簡単に述べてみます。 おそらくなんとなくでも理解できていると思われますが、両者とも直接に「コンソール」やファイルに書き込んでいるわけではありません。あくまでも出力先はstderrでありstdoutであるわけです。このことを再確認することがポイントです。Cのプログラミングで指定してるのがこの「抽象的」とも言えるstderrとstdoutです。 こうすることによって、実行するときに実際の出力先を指定できることになります。つまり、実行開始時に たとえばstdoutを「ファイル」と結びつけて走らせます。この例が ./a.out>out.txtです。 この場合、リダイレクトと言いますがstdoutとout.txtを結び付けているわけです。その結果「コンソール」には表示されません。つまり、2.と3.は何も表示されません。 そして、この結びつきを指定せずに実行するのをデフォルトといいますが、このとき使われるのが「コンソール」であるわけです。この実行方法が ./a.out のみです。この場合、2.と3.は「コンソール」に表示します。 (*)もうお気づきかと思いますが、前者・後者が実行結果が間違っていますね。 最後に、stderrについてですが、これはstdoutと違い、普通のリダイレクト(>)では結びつきを替えません。つまり、「コンソール」のままです。その結果 stderrは常に「コンソール」に出力します。したがって ./a.out>out.txt を実行した場合も stderrだけは、1.の文により「コンソール」への出力となりこれだけが表示されます。 プログラムで直接に具体的なものにしておくと実行時に変更できないわけですが、このように「抽象的」な物を入れてワンクッション置いておくと柔軟性が増すわけです。なおこれは、LinuxやMS-DOS(コマンドプロンプト)等のOSの機能と密接なつながりがあります。

ytmohimohi
質問者

お礼

とても詳しくありがとうございました。

その他の回答 (2)

  • bushclean
  • ベストアンサー率26% (6/23)
回答No.3

stdout = スタンダードアウト stderr = スタンダードエラー 因みに、 stdio = スタンダードI/O、 stdlib = スタンダードライブラリ エラー表示が見えなくなったらデバッグが面倒です。 因みに昔ディスプレイが無い時代はプリンタで”表示” されていましたが、stdoutやstderr はプリンタがデフォルト だったんでしょうね。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

>のようになりましたが、なぜこうなるか理由がわかりません。 逆じゃないの? まずはシェルのマニュアルで、リダイレクトの項目を読みましょう。

ytmohimohi
質問者

補足

すいません逆かもしれなかったです。家のパソコンでは確認できないのですが・・・

関連するQ&A

  • ポインタのポインタ

    #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv){ int i; if(argc != 2) { fprintf(stderr, "Usage: %s vector\n\tEx: %s 11110000\n", argv[0], argv[0]); return 1; } for(i=0;i<8;i++){ if(**argv == '0'){ printf("%d\n",i); } else{ printf("A%d\n",i); } argv++; } return 0; } コンパイルして./a.exe 10010011などと入力しても A0 A1 Segmentation Faultとなります。 どうすれば、 A1 0 ・・・省略 for文で回した8回分、出力が可能になるのか教えてください。 初歩的な質問ですいません。

  • C言語の質問です

    #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fpi, *fpo; unsigned char idat; /* 引数のチェック */ if (argc != 3) { fprintf(stderr, "Usage: %s [input] [output]\n", argv[0]); exit(1); } /* 入力画像のオープン */ if((fpi=fopen(argv[1], "rb")) == NULL){ fprintf(stderr, "input file open error\n"); exit(1); } /* 出力画像のオープン */ if((fpo=fopen(argv[2], "wb")) == NULL){ fprintf(stderr, "output file open error\n"); exit(1); } /* 入力画像の読込み */ while (fread(&idat, sizeof(unsigned char), 1, fpi) == 1){ /* 2倍の変換 */ if (idat * 2 > 255) { idat = 255; } else { idat = idat * 2; } /* 変換データの書出し */ if(fwrite(&idat, sizeof(unsigned char), 1, fpo) != 1){ fprintf(stderr, "data write error\n"); exit(1); } } fclose(fpi); fclose(fpo); return (0); } このプログラムをグレースケール化のプログラムに修正してください お願いします

  • 二行目の*の意味を教えてください。

    #include <stdio.h> int main(int argc, char *argv[]) { int i; for ( i = 0; i < argc; i++ ){ printf("argv[%d]=%s\n", i, argv[i]); } return argc; }  以上プログラムで、二行目の*の意味を教えてくさい。  6行目のargvには*が付いていません!?  よろしくお願いします。

  • sys/types.hの必要性について

    #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> int main (int argc,char *argv[]) { struct stat buf[2],*p;     if(argc!=3) { fprintf(stderr,"Usage:newer file1 file2\n"); exit(EXIT_FAILURE); } p=buf; if(stat(argv[1],p)<0) { perror("stat"); exit(EXIT_FAILURE); } p++; if(stat(argv[2],p)<0) { perror("stat"); exit(EXIT_FAILURE); } if(buf[0].st_mtime>buf[1].st_mtime) { printf("%s\n",argv[1]); } else { printf("%s\n",argv[2]); } return EXIT_SUCCESS; } 上記のプログラムでは<sys/types.h>を使っていますが、 どこの部分で必要になるのでしょうか? プログラム貼り付けて非常に見づらくてすいません

  • pgm画像入出力(C言語)

    画像入出力のプログラムを書いた(とあるサイトからパクった)のですが、出力画像のテキストデータが文字化けしてしまいます。原因究明お願いします。このプログラムでは2倍に変換していますが、そこは重要ではなく、入出力さえできればいいです。 OS:windows 文字コード:色々試したけどダメ。試してないものもあるかも。 プログラム #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fpi, *fpo; unsigned char idat; /* 引数のチェック */ if (argc != 3) { fprintf(stderr, "Usage: %s [input] [output]\n", argv[0]); exit(1); } /* 入力画像のオープン */ if((fpi=fopen(argv[1], "rb")) == NULL){ fprintf(stderr, "input file open error\n"); exit(1); } /* 出力画像のオープン */ if((fpo=fopen(argv[2], "wb")) == NULL){ fprintf(stderr, "output file open error\n"); exit(1); } /* 入力画像の読込み */ while (fread(&idat, sizeof(unsigned char), 1, fpi) == 1){ /* 2倍の変換 */ if (idat * 2 > 255) { idat = 255; } else { idat = idat * 2; } /* 変換データの書出し */ if(fwrite(&idat, sizeof(unsigned char), 1, fpo) != 1){ fprintf(stderr, "data write error\n"); exit(1); } } fclose(fpi); fclose(fpo); return (0); } コンパイル方法(cygwin) ./a 入力画像.pgm 出力画像.pgm

  • 計算が合わない

    下のプログラムを実行したところ、1/3の計算結果が0.33333333333333331483になってしまいます。これはどこかプログラムが間違っているのでしょうか? #include<stdio.h> int main(int argc,char **argv){ double d; d=1.0/3.0; printf("%.20f\n",d); }

  • c言語で任意のファイルから読み込んだ単語の数をカウントする

    c言語で任意のファイルから読み込んだ単語の数をカウントする 任意のファイルを読み込んだプログラムに、読み込んだ単語の数をカウントするプログラムを追加する課題が出ました。 条件は単語は空白で区切って1単語とする。改行も考慮に入れる。 関数を定義してポインタを使うらしいのですが検討がつきません。 下のプログラムでファイルを読み込むところまでは出来ています。 どうかご教授おねがいします;; #include <stdio.h> int main(int argc, char *argv[]) { FILE *myFile; int i=0,c; if(argc < 2) { fprintf(stderr,"alice.txt is required\n"); return 1; } myFile=fopen(argv[1],"r"); if(myFile==NULL) { fprintf(stderr,"Cannot open; %s\n",argv[1]); } while ((c=fgetc(myFile)) !=EOF) { fprintf(stderr,"%c",c); } fclose(myFile); return 0; }

  • ファイル操作

    コマンドライン引数から、データを入力し、入力データ中の数字を'*'文字で置き換え、それ以外の文字をそのまま出力させるプログラムを作るため #include<stdio.h> int main(int argc, char *argv[]){ FILE *fpi,fpo; char ch; if(argc!=3) { fprintf(stderr, "Illegal number of argument.\n"); return(-1); } if((fpi=fopen(argv[1],"r"))==NULL) { fprintf(stderr, "Can't open input file <%s>.\n", argv[1]); return(-1); } if((fpo=fopen(argv[2],"w"))==NULL){ fprintf(stderr, "Can't open output file <%s>.\n", argv[2]); return(-1); } while((ch=fgetc(fpi))!=EOF){ if(ch>=0 && ch<=9){ ch='*'; } } fclose(fpi); fclose(fpo); return 0; } のようなプログラムを書いたのですが、 if((fpo=fopen(argv[2],"w"))==NULL)がimcompitable types in assigment fclose(fpo);がimcompitable types for arguments1 of 'fclose' というようなエラーが出ます。 なぜか教えていただけませんか? また、その他、足りないところがあれば教えていただけませんか?

  • C言語でコマンドラインの引数について。

    コマンドラインで引数をわたす基本的なプログラムは main(int argc,char *argv[]){....] ですよね。 今回実行時に、 >実行ファイル名 123 + 233 といれたら、123+233を計算してくれるプログラムを作ろうとしています。 その場合、main(int argc,int *argv[]){} としたら、argv[1]に123が入って、argv[2]に+が入って、argv[3]に233が、入るというわけではないんでしょうか? とりあえず、確認で #include<stdio.h> main(int argc,int *argv[]) { printf("%d\n%d\n",argv[1],argv[3]); } としてみたんですが、実行結果は、とても長い数字がでてきてきました。 なにがいけないのか教えてください。 お願いします。 あとWindows MEでVC++6を使ってます。

  • プログラミング(argcとargv)

    入力された数の合計とその計算式を表示するプログラムをつくっています。惜しい(?)ところまでいったのですがその先がなかなか進みません。以下のプログラムのどこを修正したらよいでしょうか?教えてください。 #include <stdio.h> #include <stdlib.h> #define nMAX 10 int main(int argc, char **argv){ int sum = 0; if(argc < 2){ printf("Too few option!\n"); return 1; } int i, n; for(i = 1; i < argc; i++){ n = atoi(argv[i]); sum = sum + n; } printf("%d\n", sum); }

専門家に質問してみよう