在调用GNUPLOT之后,如何继续执行C 代码

How to continue to execute the C++ code after gnuplot was called?

本文关键字:继续 执行 代码 何继续 GNUPLOT 调用 之后      更新时间:2023-10-16

我正在使用GCC作为编译器,而gnuplot-iostream.h作为流以组合C 代码和GNUPLOT功能的流。

我在做什么:

我尝试通过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上(或至少在某些POSIX OS上)。然后,您确实应该阅读高级Linux编程。并且使用strace(1)可能有助于了解正在发生的事情。

您可以使用Popen(3),但是您可能应该明确使用系统调用(它们在Syscalls(2)中列出),例如Pipe(2),Fork(2),DUP2(2),Execve(2),waitpid(2)等。很可能有一些事件循环(例如,围绕民意调查(2))。

顺便说一句,您应该知道输入输出已被缓冲,并且您可能要确保您的 gnuplot stream 定期刷新(因此,请使用std::endlstd::flush适当地使用在上面)。编写n是不够的!您可能至少应该编码

gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' " 
   << std::endl;

(我用std::endl的明确使用替换了字符串中的一些n

我对 gnuplot stream (我猜这有点像一些专业的popen,但使用C 流),但是我想您应该GNUPLOT printprinterr命令要与您的通话程序交流,绘制了给定曲线的事实。(但是然后您需要一个真正的事件循环,并且您正在定义gnuplot和您的程序之间的双向协议。)。

也许QT或POCO可能是相关的,因为它们提供了事件循环和过程的一些概念。也许您可能有几个线程(一个线程(一个管理gnuplot,另一个用于其余的),但随后您有同步问题。

(我不够理解您的程序应该做什么以及您如何编码,所以这是一个盲目的猜测;我觉得您的问题非常不清楚)

阅读有关过程间通信的更多信息。