如何在调用gnuplot后继续执行C++代码?
我使用gcc作为编译器,gnuplot-iostream.h作为流来结合C++代码和gnuplot特性。如何在调用gnuplot后继续执行C++代码?
我在做什么:
我尽量让通过gnuplot的一个合适的数据,并从中提取用于进一步处理产生fit.log文件最终拟合参数。
什么问题:
当执行这样
std::cout << "Starting to fit" << std::endl;
if (bStartFit == true)
{
// gp << doing stuf here;
std::cout << "Test end" << std::endl;
}
std::cout << "Fit is done" << std::endl;
代码的输出将是:
Starting to fit
Fit is done
Test end
//gnuplot stuff
我的问题是:如何强制代码完全执行gnuplot的东西当需要时,以及继续使用C++代码之后。例如:
- 写入介绍消息;
- 绘制sin(x)函数(作为快速示例);
- 等到gnuplot关闭;
- 写出退出消息或做gnuplot完成之后的任何事情。
谢谢你, P
编辑:
std::string filename = "fit.log";
if (bStartFit == true)
{
// Using Gnuplot for the data fit (command are parsed as the strings):
// 1. define the fit function.
gp << "f(x) = imfpZP * x**(-b) + c * x**(d) + g * x**(h) \n";
// 2. fit parameters first assumption.
gp << "b = 1.1; c = 0.5; d = 1.0; g = 2.0; h = 0.1 \n";
// 3. fit range.
gp << "fit [50:10000] f(x) 'agn.iimfp' via b,c,d,g,h \n";
// 4. set the logarithmic scale.
gp << "set logscale \n";
// 5. plot the fitted data.
gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' \n";
std::cout << "Fit was successful" << std::endl;
}
// Opening the generated fit.log file to store the fit parameters:
std::ifstream inFIT(filename.c_str());
if (inFIT.is_open())
{
std::cout << "FIT log is opened" << std::endl;
std::string line;
int lineCounter = 0;
while (std::getline(inFIT, line))
{
lineCounter++;
}
std::cout << "Total lines: " << lineCounter << std::endl;
// Getting the five lines with fit parameters from the fit.log:
std::fstream& GoToLine(std::fstream& file, unsigned int lineNumber);
std::fstream file(filename.c_str());
GoToLine(file, lineCounter - 15);
std::string b_Line;
std::getline(file, b_Line);
std::cout << b_Line << std::endl;
std::istringstream sb(b_Line);
std::string tempStr;
char tempChar;
sb >> tempStr >> tempChar >> b
// similar code to get another 4 lines
;
它是操作系统特定的。我猜你在Linux上(或者至少在某些操作系统上)。那你真的应该读Advanced Linux Programming。并且使用strace(1)可能有助于理解正在发生的事情。
你可以使用popen(3),但你应该明确地使用system calls(他们在syscalls(2)上市)一样pipe(2),fork(2),dup2(2),execve(2),waitpid(2)等,并很可能有一些event loop(例如,大约poll(2))。
BTW,你应该知道,输入输出为buffered,你可能想确保您gnuplot的流是定期冲洗(所以使用std::endl
或std::flush
适当就可以了)。写一个\n
是不够的!你或许应该在代码至少
gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' "
<< std::endl;
(我已经更换了一些\n
在字符串中有明确使用std::endl
)
我不知道很多关于gnuplot stream(我猜这是有点像一些专门的popen
,但使用C++流),但我想你应该使用gnuplot print
或printerr
命令与您的调用程序通信给定的曲线已被绘制的事实。 (但是你需要一个真正的事件循环,并且你正在定义一个gnuplot
和你的程序之间的双向协议)。
或许Qt或POCO可能是相关的,因为它们提供了一些事件循环和过程的概念。也许你可能有几个线程(其中一个管理gnuplot
,另一个管理其他线程),但是你有同步问题。
(我不明白就够了你的程序是应该做的,你是如何编码的,所以它是一个盲目的猜测,我觉得你的问题很不清楚)
嘿,我在Linux机器上工作,这是真的,但我想尽可能不使用系统特定的调用。我对这个gnuplot-iostream很陌生,遇到了这样一个问题,我可以通过编写两个单独的程序来解决这个问题,但首先我想弄清楚也许有一种方法可以在一个代码中解决它。 –
但是你的问题没有显示足够的代码,目前还不清楚。我相信你误解了一些重要的东西。也许这些问题不在你所相信的地方。 –
通过使用Qt,我需要自己编写一个拟合函数。在我的工作中,我需要使用gnuplot来获得拟合参数,并在之后的C++代码和gnuplot中使用它们。所以,这对我来说不是一个好的选择 –
你是什么意思_“gnuplot的东西”_ ??你怎么称呼gnuplot? –
我不确定使用* gnuplot iostream *是否符合您的需求。 –
作者:gnuplot stuff我的意思是gnuplot标题,如果我使用“fit”命令,我也会在这里得到一个合适的迭代,并且情节本身将是最后一件事情。 –