如何在调用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 

;

+0

你是什么意思_“gnuplot的东西”_ ??你怎么称呼gnuplot? –

+0

我不确定使用* gnuplot iostream *是否符合您的需求。 –

+0

作者:gnuplot stuff我的意思是gnuplot标题,如果我使用“fit”命令,我也会在这里得到一个合适的迭代,并且情节本身将是最后一件事情。 –

它是操作系统特定的。我猜你在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::endlstd::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 printprinterr命令与您的调用程序通信给定的曲线已被绘制的事实。 (但是你需要一个真正的事件循环,并且你正在定义一个gnuplot和你的程序之间的双向协议)。

或许QtPOCO可能是相关的,因为它们提供了一些事件循环和过程的概念。也许你可能有几个线程(其中一个管理gnuplot,另一个管理其他线程),但是你有同步问题。

(我不明白就够了你的程序是应该做的,你是如何编码的,所以它是一个盲目的猜测,我觉得你的问题很不清楚)

了解更多Inter-Process Communications

+0

嘿,我在Linux机器上工作,这是真的,但我想尽可能不使用系统特定的调用。我对这个gnuplot-iostream很陌生,遇到了这样一个问题,我可以通过编写两个单独的程序来解决这个问题,但首先我想弄清楚也许有一种方法可以在一个代码中解决它。 –

+0

但是你的问题没有显示足够的代码,目前还不清楚。我相信你误解了一些重要的东西。也许这些问题不在你所相信的地方。 –

+0

通过使用Qt,我需要自己编写一个拟合函数。在我的工作中,我需要使用gnuplot来获得拟合参数,并在之后的C++代码和gnuplot中使用它们。所以,这对我来说不是一个好的选择 –