gpt4 book ai didi

c++ - 执行控制台程序,写入标准输入并使用管道读取结果

转载 作者:太空宇宙 更新时间:2023-11-04 05:28:13 25 4
gpt4 key购买 nike

我需要执行控制台程序,将一些值写入标准输入并使用管道读取结果。我尝试去实现它。这段代码完美运行。但我认为还有其他更简单的方法来实现它。你有什么想法吗?

pid_t pid = fork();
std::string output_data;
if(pid < 0)
{
printf("Error\n");
}
else if(!pid)
{
FILE* process = popen(program.c_str(), "r");
char temp_data[128];
if(process)
{
while(fgets(temp_data, sizeof(temp_data), process))
{
output_data.append(temp_data);
}
}
pclose(process);
exit(1);
}
else
{
FILE* process = popen(program.c_str(), "w");
std::string output_data;
char temp_data[128];
if(process)
{
fwrite("5", 1, sizeof(int), process);
}
pclose(process);
}

最佳答案

看起来您的代码将运行 4 个进程:一个进程 fork 为 2 个进程,然后每个进程都使用 popen() 进行 fork 。 popen() 不仅会创建一个管道,还会创建一个通过该管道连接的子进程,因此调用 popen() 的 2 个进程中的每一个都会创建一个子进程。

您应该决定如何进行:要么让 popen() 完成所有工作,但不要使用 fork(),要么让 pipe()自己创建管道并使用 fork() - 这就是我下面的代码所做的。

仍然有一个很大的区别:popen() 不仅会 fork,而且还会在子进程中执行另一个程序。我的示例保留在同一个可执行文件中。如果你想在子进程中执行另一个程序,那么 popen() 会非常有用,但是你不应该使用 fork()。

int fsd[2]; // write to fds[1], read from fds[0]
pipe(fds); // creates the pipe with read+write file descriptors in fds
id_t pid = fork();
std::string output_data;
if(pid < 0)
{
printf("Error\n");
}
else if(!pid)
{
close(fds[1]); // else we'll never detect end of input
FILE* process = fdopen(fds[0], "r");
char temp_data[128];
if(process)
{
while(fgets(temp_data, sizeof(temp_data), process))
{
output_data.append(temp_data);
}
}
pclose(process);
exit(1);
}
else
{
close(fds[0]); // just to clean up
FILE* process = fdopen(fds[1], "w");
std::string output_data;
char temp_data[128];
if(process)
{
fprintf(process, "5\n"); // your fwrite("5",...) worked by luck only
}
pclose(process);
}

最后,如果您希望进程启动另一个可执行文件,写入该可执行文件,然后从中读取,您需要执行以下操作:

创建 2 个管道,一个用于从父级向子级写入,另一个用于从子级向父级写回,然后执行一些操作来重新分配文件描述符:

int p2c[2]; pipe(p2c); // parent to child
int c2p[2]; pipe(c2p); // child to parent
if(fork()) { // parent - I ignore error checks here
close(p2c[0]); // the child reads from that
close(c2p[1]); // the child writes to that
FILE * f_w = fdopen(p2c[1],"w");
... write some data to the child using f_w ...
fclose(f_w);
FILE * f_r = fdopen(c2p[0],"r");
... read some data from the child using f_r ...
fclose(f_r);
wait(0); // just to avoid a zombie
} else { // in the child, change stdin and stdout
close(p2c[1]); close(0); dup(p2c[0]); close(p2c[0]);
close(c2p[0]); close(1); dup(c2p[1]); close(c2p[1]);
... now use execv or something similar to run the other executable
}

关于c++ - 执行控制台程序,写入标准输入并使用管道读取结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27675298/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com