在C中使用popen()不成功?
我可以运行以下命令在C中使用popen()不成功?,c,screenshot,popen,piping,x11,C,Screenshot,Popen,Piping,X11,我可以运行以下命令 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];
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);
}
#包括
#包括
int main()
{
文件*fpipe;
char*command=“xwd-root | xwdtopnm | pnmtojpeg”;
字符行[256];
if(!(fpipe=(FILE*)popen(命令,“r”))
{//如果fpipe为NULL
perror(“管道问题”);
出口(1);
}
而(fgets(管线、管线尺寸、管道))
{
//printf(“%s”,第行);
放(线);
}
pclose(fpipe);
}
然后我编译并运行程序
/popen>screen.jpg
,但生成的文件screen.jpg是不可重组的。如何才能正确地通过管道传输程序?在不测试代码的情况下,我怀疑“xwd-root | xwdtopnm | pnmtojpeg”是否可以用作C-pipe的参数
对于这样的问题,我无论如何都不会使用C程序。使用简单的Bash脚本。处理二进制数据时不应使用
fgets
和put
fgets
将在看到换行符时停止。更糟糕的是,put
将输出额外的换行符,并且每当它运行到\0时,它也将停止。改用fread
和fwrite
。函数fgets
和put
不用于图像文件等二进制数据。它们只能与文本字符串一起使用。在C语言中,字符串以空字节结尾('\0'
)。因为这实际上只是一个零,所以它可能出现在二进制文件中的任何位置。假设行[]
中填充了256个字符的数据。调用put
时,函数读取数组,直到遇到空字节,然后假设它已到达字符串末尾并停止。由于在二进制文件中,空字节可能出现在任何地方(而不仅仅是在数组末尾),因此put
函数很容易无法打印出数据的各个部分
如果我是你,我会研究
fread
和fwrite
函数并使用它们。在Linux机器上,您只需键入man 3 fread
即可阅读这两个函数的文档。对于存在相同问题的用户,我最终通过使用Unix读/写系统调用使其正常工作:
#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);
}
#包括
#包括
#包括
#包括
#包括
//直接写入输出文件test.jpg
int main()
{
文件*fpipe;
char*command=“xset b off&&xwd-root | xwdtopnm 2>/dev/null | pnmtojpeg”;
字符buff[256];
大小\u t结果\u写入;
读取结果的大小;
if(!(fpipe=(FILE*)popen(命令,“r”))
{//如果fpipe为NULL
perror(“管道问题”);
出口(1);
}
int dest_fd=open(“test.jpg”,O|RDWR | O|TRUNC | O|u CREAT,S|IRUSR | S|IWUSR);
int fd=文件编号(fpipe);
而((result_read=read(fd,buff,sizeof(char)*256))>0{
如果(结果读数<0){
perror(“读取时出现问题。\n”);
出口(1);
}
结果写入=写入(dest\u fd,buff,sizeof(char)*256);
如果(结果写入<0){
perror(“写入输出文件的问题。\n”);
出口(1);
}
}
关闭(目的地fd);
pclose(fpipe);
}
我不能使用Bash脚本,这只是一个测试。我需要一种编程的方式在X11中截图,这是我在不阅读所有X11源代码的情况下能想到的最好的方法。对不起,我指的是fread和fwrite,而不是读写。(刚刚编辑了我的答案)只要确保不在同一个文件上执行缓冲IO(fread、fscanf、fwrite、fprintf…)和非缓冲IO(读取、写入…),就可以了。但我不明白你为什么不使用fread和fwrite。