creating a pipe and writing to gnuplot terminal from c++ - c++

I am trying to call the gnuplot from c++. I am using wgnuplot for Windows and VS2005 c++.
The following statement works because it opens the gnuplot terminal
FILE *p = _popen("wgnuplot -persist","w");
But I cannot write anything there. My terminal is still blank even after running the following code.
fprintf(p, "set terminal x11 enhanced\n"); //set appropriate output terminal for the plot
fprintf(p, "set xlabel 'N'\n");//set xlabel
fprintf(p, "set ylabel 'error'\n");//set ylabel
Could you please tell me what might be the problem, i.e. why the terminal is blank and fprintf() doesn't seem to work?
Thanks,
Boris

Check that FILE pointer is not NULL:
if(!p)
// _popen() has failed...

I do not know if that helps you, but this is my approach of executing gnuplot from my C programs:
I create a template file (usually I do not delete it, so that it is easier to troubleshoot), where all the gnuplot commands are are scripted in.
I run gnuplot with
system("gnuplot <TemplateFile>")
If you are only interested in creating a plot, that his would do the job. If you are explicitly interested in the approach you described above then just disregard this posting ;)
Cherio Woltan

Related

How can I find why system can not run my application?

I have a c++ program that run a command and pass some arguments to it. The code is as follow:
int RunApplication(fs::path applicationPathName,std::string arguments)
{
std::string applicationShortPath=GetShortFileName(applicationPathName);
std::string cmd="\""+applicationShortPath +"\" "+ arguments+" >>log.txt 2>&1 \"";
std::cout<<cmd<<std::endl;
int result=std::system(cmd.c_str());
return result;
}
When I run system command, the cmd window appears shortly and then closes, but the result is 1 and the cmd was not run (the command should generate output which is not generated).
To check that the cmd is correct, I stopped the application just before system line and copy/ paste cmd content to a cmd window and it worked.
I am wondering how can I find why application is not run in system()?
the cmd has this value just before running it:
"D:/DEVELO~3/x64/Debug/enfuse.exe" -w --hard-mask --exposure-weight=1 --saturation-weight=0.328 --contrast-weight=0.164 -o "C:/Users/m/AppData/Local/Temp/1.tif" "C:/Users/m/AppData/Local/Temp/1.jpg" "C:/Users/m/AppData/Local/Temp/2.jpg" >>log.txt 2>&1 "
How can I find why it is not working?
Is there any way that I set the system so it doesn't close cmd window so I can inspect it?
is there any better way to run a command on OS?
Does Boost has any solution for this?
Edit
After running it with cmd /k, I get this error message:
The input line is too long.
How can I fix it other than reducing cmd line?
There are two different things here: if you have to start a suprocess, "system" is not the best way of doing it (better to use the proper API, like CreateProcess, or a multiplatform wrapper, but avoid to go through the command interpreter, to avoid to open to potential malware injection).
But in this case system() is probably the right way to go since you in fact need the command interpreter (you cannot manage things like >>log.txt 2>&1 with only a process creation.)
The problem looks like a failure in the called program: may be the path is not correct or some of the files it has to work with are not existent or accessible with appropriate-permission and so on.
One of the firt thing to do: open a command prompt and paste the string you posted, in there. Does it run? Does it say something about any error?
Another thing to check is how escape sequence are used in C++ literals: to get a '\', you need '\\' since the first is the escape for the second (like \n, or \t etc.). Although it seems not the case, here, it is one of the most common mistakes.
Use cmd /k to keep the terminal: http://ss64.com/nt/cmd.html
Or just spawn cmd.exe instead and inspect the environment, permissions, etc. You can manually paste that command to see whether it would work from that shell. If it does, you know that paths, permssions and environment are ok, so you have some other issue on your hands (argument escaping, character encoding issues)
Check here How to execute a command and get output of command within C++ using POSIX?
Boost.Process is not official yet http://www.highscore.de/boost/process/

Executing a .bat file with a parameter and reading the console output in C++

I have a batch file I need to execute, it has one parameter, If I were to run this script myself I would open up cmd and write
lexparser.bat texfile.txt
and the output would then be printed to the console.
I have shopped around and I have found some code which seems to be executing the file but I can't seem to extract the data being output, but I am unsure if this is correct.
QString pathDocument = qApp->applicationDirPath()+ "/stanford/lexparser.bat";
long result = (long)ShellExecute(0, 0, reinterpret_cast<const WCHAR*>(pathDocument.utf16()), 0, 0, SW_NORMAL);
I am using C++ as my language and I am also using the Qt Library to help me.
I have limited programming ability so any help would be greatly appreciated
I would recommend using QProcess for doing that.
See this question and its accepted answer for an example on how to do so.

Octave plot from Qt C++ application

I have a QT C++ application that runs the Octave program using QProcess. I am able to communicate with it by reading the standard output/error and writing to it's standard input using write method (for example: octave->write("5 + 5\n");).
As I told you I get response from octave (from the above example I get "ans = 10").
However, when the command I write to Octave standard input has a "plot" (for example, a simple plot([1 2 3 4 5]);), the actual graphic is never shown. I know Octave runs gnuplot, I have it installed, and gnuplot_x11 too. I even change the gnuplot binary path in my Octave process by executing gnuplot_binary("/usr/bin/gnuplot"); from MY APPLICATION. I know it runs good because if I retrieve the new value I get it right. But I don't know why Octave doesn't show the graphic.
Here I start octave:
QStringList arguments;
arguments << "--persist";
octave->setProcessChannelMode(QProcess::MergedChannels);
octave->start("/usr/bin/octave", arguments);
Here I write commands to octave process:
if (octave->state() == QProcess::Running) {
QString command = widget.txtInput->toPlainText();
if (command.isEmpty()) {
return;
}
command += "\n";
octave->write(command.toAscii());
}
With this I print the octave response to a text edit:
widget.txtOutput->append(octave->readAll() + "\n");
And finally, I use this when the octave process starts:
QString gnuplot_path(tr("\"/usr/bin/gnuplot\""));
QString gnuplot_cmd(tr("gnuplot_binary(%1)\n").arg(gnuplot_path));
octave->write(gnuplot_cmd.toAscii());
I will appreciate any help you could give me.
Thanks in advance.
Octave, like Matlab, can be run in batch mode to perform computations without graphical UI. I assume that Octave detects that it is not run from an interactive session, and therefore automatically goes into batch mode. You would expect Octave to suppress graphical output (e.g. gnuplot output) when being in batch mode.
Try to force Octave into interactive mode by using the --interactive command line option:
http://www.gnu.org/software/octave/doc/interpreter/Command-Line-Options.html
I know you probably already solved your problem but this might be helpful for other...
You can try to add a command to save your plot in a temporary folder in your octave request.
Then display the graph in your ap

Linux console commands in C++ (gcc compiler)

How can I give commands to Linux console (Ubuntu) from my c++ program, and assign a value, which my command tells, to string variable? Please, give me an example, in which program gives simple command "uname -a" to console and writes result.
Sorry for my bad English, I know it very little. I would be very happy, if someone will write his answer in Russian (if it allowed) . I was looking for the answer to my question in Russian resources, but found nothing, you're my last hope.
The command you need is popen. You can get information about it by typing man popen into your shell; if your Linux distribution runs its Russian translation, it should display the information about it in Russian.
Basically, popen just opens a "file" (stream), with which you can work just like with a regular file. Here's an example of how it could be used:
#include <stdio.h>
int main()
{
FILE *f;
char stuff[100];
f = popen("uname -a", "r");
fgets(stuff, 100, f);
printf("%s", stuff);
pclose(f);
}
The code above doesn't have any error handling; you should insert the appropriate checks after you read and understand the complete manual page (rus).
Look for Russian language resources that explain the popen(3) library routine. You will need to use popen to launch the command, then read the pipe to obtain the output.

C++ and gnuplot

This is my first post and I'm quite a novice on C++ and compiling in general.
I'm compiling a program which requires some graphs to be drawn. The program create a .dat file and then i should open gnuplot and write plot '.dat'. That's fine.
Is there a way to make gnuplot automatically open and show me the plot I need? I should use some system() function in the code to call gnuplot but how can I make him plot what I need?
Sorry for my non-perfect English :s
Thanks for the attention anyway!
Depending on your OS, you might be able to use popen(). This would let you spawn a gnuplot process and just just write to it like any other FILE*.
If you have datapoints to plot, you can pass them inline with the plot "-" ... option. Similarly, you may want to explore set data style points/lines/linespoints/etc options.
Without pause or persist, gnuplot will terminate upon end-of-input-stream. In your example case, that would be when the end of the file is reached.
To produce (write) an output file (graph), use:
set terminal png small
set output "filename.png"
There's lots of options to set terminal. Png is usually there. If not, perhaps gif, tiff, or jpeg?
Watch out for overwriting the file!
You may want to use set size 2,2 to make a larger graph. Some set terminal variants also allow you to specify the size.
I'm learning this today too. Here is a small example I cooked up.
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char **argv) {
ofstream file("data.dat");
file << "#x y" << endl;
for(int i=0; i<10; i++){
file << i << ' ' << i*i << endl;
}
file.close();
return 0;
}
Save that as plot.cpp and compile that with g++:
g++ plot.cpp -o plot
Run the program to create the .dat file:
./plot
Save the following gnuplot script as plot.plt:
set terminal svg enhanced size 1000 1000 fname "Times" fsize 36
set output "plot.svg"
set title "A simple plot of x^2 vs. x"
set xlabel "x"
set ylabel "y"
plot "./data.dat" using 1:2 title ""
Run the script with gnuplot to generate your .svg file:
gnuplot plot.plt
The resulting plot will be in plot.svg. If you leave out the first couple lines that specify the output, it will render in a window. Have fun!
Sometimes it is as easy as one may think
gnuplot file
where file is neither your data nor your result file, but a file with the command you would type in the commandline. Just enter there your commands you need (either constant file you have or generate it).
After executing all commands in that file gnuplot exits.
Yes you can. You can make a file that has the commands you would otherwise type in to set up the plot and open gnuplot running from that file. This link has an article that explains how to do it. You can also output to an EPS or other graphical output formats and display the plot using another widget that reads in the file.
You may need to use the '-persist' flag to the command. I know that on *nix systems, this flag is required if you want the plot window to remain after the gnuplot process has completed and exited.
gnuplot -persist commands.gp
Also, you can put as many gnuplot commands as you like in the file. The file acts sort of like a batch script in this regard.
You might need to add a line
pause -1
This will show the plot until return has been pressed.
What you are probably seeing is that gnuplot runs and exits before the plot has time to be displayed.
You might need to set a terminal type. Read the gnuplot documentation about that.