2009-05-08 18 views
4

私は、Linuxの下で、次のコマンドをターミナルでCでのpopen()の使用がうまくいかない?

xwd -root | xwdtopnm | pnmtojpeg > screen.jpg

を実行することができますし、それは私の現在の画面のスクリーンショットを生成します。

私は、コードで次の操作を実行しよう:

#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ 
    FILE *fpipe; 
    char *command="xwd -root | xwdtopnm | pnmtojpeg"; 
    char line[256]; 

    if (!(fpipe = (FILE*)popen(command,"r"))) 
    { // If fpipe is NULL 
     perror("Problems with pipe"); 
     exit(1); 
    } 

    while (fgets(line, sizeof line, fpipe)) 
    { 
     //printf("%s", line); 
     puts(line); 
    } 
    pclose(fpipe); 
} 

その後、私はプログラム./popen > screen.jpgが、結果のファイルscreen.jpgがunrecongizableでコンパイルして実行します。プログラムを正しくパイプ処理できるようにするには、どうしたらいいですか?

答えて

0

あなたのコードをテストしないと、 "xwd -root | xwdtopnm | pnmtojpeg"がCパイプの引数として機能するのではないかと疑問に思う。

とにかくこのような問題に対してCプログラムは使用しません。代わりに単純なBashスクリプトを使用してください。

+0

を私はbashスクリプトを使用することはできません、これは単なるテストです。 X11でスクリーンショットを撮るためのプログラム的な方法が必要です。これはすべてのX11ソースコードを調べなければならない最高のものです。 –

7

バイナリデータの処理にはfgetsputsを使用しないでください。 fgetsは、改行が見つかるたびに停止します。さらに悪いことに、putsは余分な改行を出力し、\ 0になるたびに停止します。代わりにfreadfwriteを使用してください。

+0

ありがとう!有用なコメントは、見ていきます。 –

+0

申し訳ありませんが、私はfreadとfwriteを意味し、読み書きはできません。 –

+0

私はとにかく読み書きをしました:P –

2

機能fgetsputsは、画像ファイルのようなバイナリデータでは使用できません。テキストの文字列でのみ使用する必要があります。 Cでは、文字列はヌルバイト('\0')で終了します。これは実際にはゼロにすぎないため、バイナリファイルのどこにでも表示される可能性があります。 line[]が256文字のデータで満たされているとします。 putsを呼び出すと、nullバイトが検出されて文字列の最後に到達したとみなされ、停止するまで関数が配列を読み取ります。バイナリファイルでは、ヌルバイトはどこにでも(配列の終わりではなく)現れることがあるので、puts関数はデータのセクションを簡単に出力できません。

私があなただったら、freadfwriteの関数を調べて代わりに使用します。 Linuxマシンでは、man 3 freadと入力するだけで、両方の機能のドキュメントを読むことができます。これと同じ問題を有するものについては

+0

洞察のおかげで –

2

、私は最終的にそれがUnixのを使って作業なってしまった/ writeシステムコールを読む:

#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 

//writes to an output file test.jpg directly 
int main() 
{ 
    FILE *fpipe; 
    char *command="xset b off && xwd -root | xwdtopnm 2> /dev/null | pnmtojpeg"; 
    char buff[256]; 
    size_t result_write; 
    size_t result_read; 

    if (!(fpipe = (FILE*)popen(command,"r"))) 
    { // If fpipe is NULL 
     perror("Problems with pipe"); 
     exit(1); 
    } 

    int dest_fd = open("test.jpg", O_RDWR|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR); 
    int fd = fileno(fpipe); 
    while((result_read = read(fd, buff, sizeof(char)*256))>0){ 
     if(result_read < 0){ 
      perror("Problem while reading.\n"); 
      exit(1); 
     } 
     result_write = write(dest_fd, buff, sizeof(char)*256); 
     if(result_write < 0){ 
      perror("Probelms writing to outputfile.\n"); 
      exit(1); 
     } 
    } 
    close(dest_fd);  
    pclose(fpipe); 
} 
+1

バッファリングされたIO(fread、fscanf、fwrite、fprintf、...)とバッファリングされていないIO読み込み、書き込み、...)、これはうまくいくはずです。あなたがなぜfreadとfwriteを使わなかったのか理解できない。 – ephemient

関連する問題