4

我可以运行以下命令

xwd -root | xwdtopnm | pnmtojpeg > screen.jpg

在 linux 下的终端中,它将生成我当前屏幕的屏幕截图。

我尝试使用代码执行以下操作:

#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 无法识别。我怎样才能做到这一点,以便我可以正确地通过我的程序?

4

4 回答 4

7

您不应该使用fgetsandputs来处理二进制数据。fgets只要看到换行符就会停止。更糟糕的是,puts将输出额外的换行符,并且在遇到 \0 时也会停止。使用freadandfwrite代替。

于 2009-05-08T10:46:25.787 回答
2

这些函数fgetsputs不打算与图像文件等二进制数据一起使用。它们只能与文本字符串一起使用。在 C 中,字符串以空字节 ( '\0') 结尾。由于这实际上只是一个零,它可能出现在二进制文件的任何位置。假设它line[]充满了 256 个字符的数据。当您调用 时puts,该函数会读取数组,直到遇到空字节,然后假定它已到达字符串的末尾并停止。由于在二进制文件中,空字节可能出现在任何地方(而不仅仅是在数组的末尾),因此该puts函数很容易无法打印出您的数据部分。

如果我是你,我会研究freadandfwrite函数并使用它们。在 Linux 机器上,您应该只能通过键入man 3 fread来阅读这两个函数的文档。

于 2009-05-08T11:02:30.960 回答
2

For those having this same problem, I ended up finally getting it working by using the Unix read/write system calls:

#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);
}
于 2009-05-08T20:34:27.270 回答
0

在没有测试您的代码的情况下,我怀疑“xwd -root | xwdtopnm | pnmtojpeg”是否可以作为 C 管道的参数。

无论如何,我不会使用 C 程序来解决这样的问题。请改用简单的 Bash 脚本。

于 2009-05-08T10:42:52.787 回答