2016-11-27 106 views
0

我使用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」命令,我也會在這裏得到一個合適的迭代,並且情節本身將是最後一件事情。 –

回答

0

它是操作系統特定的。我猜你在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中使用它們。所以,這對我來說不是一個好的選擇 –

相關問題