调用gnuplot后如何继续执行C++代码?

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

我使用 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++ 代码。例如:

谢谢, 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). Then you really should read Advanced Linux Programming. And using strace(1) 上可能有助于理解正在发生的事情。

你可以使用 popen(3), but you probably should explicitly use system calls (they are listed in syscalls(2)) like pipe(2), fork(2), dup2(2), execve(2), waitpid(2), etc. And very probably have some event loop (e.g. around poll(2)).

顺便说一句,您应该知道输入输出是 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;

(我已经用显式使用 std::endl 替换了字符串中的一些 \n

我不太了解 gnuplot stream(我猜它有点像一些专门的 popen 但使用 C++ 流),但我想你应该 gnuplot printprinterr 命令向您的调用程序传达给定曲线已绘制的事实。 (但是你需要一个真正的事件循环,并且你正在 gnuplot 和你的程序之间定义一个双向协议。)

也许 Qt or POCO 可能是相关的,因为它们提供了一些事件循环和过程的概念。也许您可能有多个线程(一个管理 gnuplot,另一个管理其余线程),但是您会遇到同步问题。

(我不太了解你的程序应该做什么,你是如何编码的,所以是盲目猜测;我觉得你的问题很不清楚)

详细了解 Inter-Process Communications