在C中不成功使用popen()?

我可以运行以下命令

xwd -root | xwdtopnm | pnmtojpeg > screen.jpg

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

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

 #include  #include  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无法识别。 我怎么能这样做才能正确地管理我的程序?

您不应该使用fgetsputs来处理二进制数据。 只要看到换行符, fgets就会停止。 更糟糕的是, puts会输出额外的换行符,并且每当它遇到\ 0时它也会停止。 请改用freadfwrite

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

如果我是你,我会研究freadfwrite函数并改用它们。 在Linux机器上,你应该能够键入man 3 fread来读取这两个函数的文档。

对于那些有同样问题的人,我最终通过使用Unix读/写系统调用来实现它:

 #include  #include  #include  #include  #include  //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); } 

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

对于这样的问题,我不会使用C程序。 请改用简单的Bash脚本。