早上好; 现在,我正在编写一个程序,该程序对物理过程进行蒙特卡洛模拟,然后将生成的数据通过管道传输到gnuplot以绘制图形表示。模拟和绘图工作正常。但我有兴趣打印一条错误消息,该错误消息通知用户未安装gnuplot。为了解决这个问题,我尝试了以下代码:
#include <stdio.h>
#include <stdlib.h>
FILE *pipe_gnuplot;
int main()
{
pipe_gnuplot = _popen("gnuplot -persist", "w");
if (pipe_gnuplot==NULL)
{
printf("ERROR. INSTALL gnuplot FIRST!\n");
exit (1);
}
return 0;
}
但是,没有打印我的错误消息,而是出现了“ gnuplot无法识别为内部或外部命令,可操作程序或批处理文件”(该程序在Windows上运行)。我不明白我在做什么错。根据_popen文档,如果管道打开失败,则应返回NULL。您能帮我解决这个问题吗?在此先感谢,如果问题很基本,请谅解。
答案 0 :(得分:2)
难以处理popen
(或_popen
)的错误。
popen
创建一个管道和一个进程。如果失败,您将得到NULL
结果,但这仅在极少数情况下发生。 (没有更多的系统资源来创建管道或进程或错误的第二个参数)
popen
将您的命令行传递到Shell(UNIX)或命令处理器(Windows)。如果系统无法分别执行Shell或命令处理器,我不确定是否会得到NULL
的结果。
命令行将由外壳程序或命令处理器解析,并且错误的处理方式就像您手动输入命令一样,例如导致错误消息和/或非零退出代码。
成功的popen
意味着系统可以成功启动Shell或命令处理器。没有直接的方法可以检查执行命令的错误或获取命令的退出代码。
通常,我会尽可能避免使用popen
。
如果要专门为Windows编程,请检查是否可以从CreateProcess
之类的Windows API函数获得更好的错误处理。
否则,您可以将命令包装在脚本中,该脚本检查结果并打印特定的消息,您可以阅读和解析这些消息以区分成功与错误。 (我不推荐这种方法。)
答案 1 :(得分:1)
在@Bodo的答案上piggy带,在兼容POSIX的系统上,您可以使用wait()
等待单个子进程返回,并获取其退出状态(如果返回的退出状态通常为127,找不到命令。)
由于您在Windows上,因此拥有_cwait()
,但这似乎与实现_popen
的方式不兼容,因为它需要处理子进程_popen
不会返回或提供任何明显的访问权限。
因此,最好的方法似乎是通过手动创建管道并使用popen()
函数之一生成该过程来基本上手动重新实现spawn[lv][p][e]
。实际上,_pipe()
的文档给出了一个示例说明如何执行此操作的示例(尽管您希望将子进程的stdin
重定向到管道的写端)。
我还没有尝试写一个例子。