In my C++ program (in linux), I can open a pipe for writing and set values for Gnuplot program.
FILE *pipe = NULL;
#ifdef WIN32
pipe = _popen("pgnuplot -persist", "w");
#else
pipe = popen("gnuplot", "w");
#endif
if(pipe == NULL)
error("Could not open pipe for write!");
// set title name
fprintf(pipe, "set title 'Sample Points' \n");
Now I need to get the Gnuplot version. The show version
command does this but how I can send this command and then read the value. Opening a pipe for reading seems to not work for me and the code stuck in the while loop without getting any data.
FILE* pipe = popen(command, "r");
if (!pipe)
{
std::cout << "failed! (can not open pipe)" << endl;
return;
}
char buffer[128];
std::string result = "";
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
Since on my Debian/Linux/Sid/x86-64 the command gnuplot --version
is outputting to stdout
the following line:
gnuplot 5.0 patchlevel 1
I would simply recommend
FILE* pipversion = popen("gnuplot --version", "r");
if (!pipversion) { perror("popen gnuplot"); exit(EXIT_FAILURE); };
char lineversion[128];
memset (lineversion, 0, sizeof(lineversion));
if (!fgets(lineversion, sizeof(lineversion), pipversion) {
perror("fgets"); exit(EXIT_FAILURE);
}
/// lineversion is like: gnuplot 5.0 patchlevel 1
int majvers=0, minvers=0, pos= -1;
char* restvers = NULL;
if (sscanf(lineversion, "gnuplot %d.%d %n", &majvers, &minvers, &pos) >= 2) {
assert (pos>=0);
restvers = lineversion+pos;
};
pclose(pipversion);
pipversion = NULL;
After that, majvers
contains the major version of gnuplot
(eg 5 in my case) and minvers
contains the minor version (eg 0), with restvers
being a suffix string (eg "patchlevel 1"
without the quotes).
There might be a potential race condition in the unusual and unlikely case that gnuplot
is updated between this popen
and the next one pipe = popen("gnuplot", "w");
. BTW, naming a variable pipe
is poor taste, since POSIX and Linux have the pipe(2) system call. But I don't think it is worth caring about that race condition.
BTW, you very probably want to replace your second pipe = popen("gnuplot", "w");
with an explicit double invocation of pipe(2) (followed by appropriate fork(2) & execvp(3) ...) to have both input and output pipes to gnuplot
, and manage them in your own event loop (probably around poll(2) ... see this & that answers).
(if you application has or uses its own event loop, in particular if it is a GUI application above Qt or GTK, you want to use the same event loop for the pipes; details are specific to the library providing that event loop: g_spawn_async_with_pipes & g_source_add_unix_fd for GTK, QProcess for Qt ... )
I don't have time to explain how to do that (double piping into command + event loop) in details, but the Advanced Linux Programming book (available online) has several chapters on that. Be aware that you need some event loop.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.