2016-11-27 1 views
0

Ich benutze gcc als Compiler und gnuplot-iostream.h als Stream, um C++ - Code und die Gnuplot-Funktionen zu kombinieren.Wie wird der C++ - Code nach dem Aufruf von gnuplot weiter ausgeführt?

Was ich tue:

ich versuche, eine Anpassung der Daten über gnuplot zu machen und die endgültigen Fitparameter aus der erzeugten fit.log Datei zur weiteren Verarbeitung extrahieren.

Was ist das Problem:

, wenn Sie den Code wie dieser

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; 
Ausführung

der Ausgang sein:

Starting to fit 
Fit is done 
Test end 
//gnuplot stuff 

Meine Frage ist: wie Sie den Code erzwingen ausführen genau gnuplot Zeug bei Bedarf und nach dem C++ - Code fortfahren. Zum Beispiel:

  • Intro-Nachricht schreiben;
  • die sin (x) -Funktion zeichnen (als schnelles Beispiel);
  • warten bis der gnuplot geschlossen ist;
  • Schreiben Sie die Nachricht oder machen Sie was immer NACH dem gnuplot getan wird.

danke, P

EDIT:

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

Was meinst du _ "gnuplot stuff" _ ?? Wie nennst du gnuplot? –

+0

Ich bin mir nicht sicher, ob die Verwendung von * gnuplot iostream * Ihren Anforderungen entspricht. –

+0

von "gnuplot stuff" Ich meine die Gnuplot-Header, wenn ich "fit" -Befehl verwende, werde ich auch hier eine passende Iterationen bekommen, und die Handlung selbst wird das letzte sein, was produziert wird. –

Antwort

0

Es ist betriebssystemspezifisch. Ich vermute, Sie sind auf Linux (oder zumindest auf einigen POSIX OS). Dann sollten Sie wirklich Advanced Linux Programming lesen. Und mit strace(1) könnte hilfreich sein zu verstehen, was passiert.

könnten Sie popen(3) verwenden, aber Sie sollten wahrscheinlich system calls explizit verwenden (sie in syscalls(2) aufgeführt sind) wie pipe(2), fork(2), dup2(2), execve(2), waitpid(2), etc. Und sehr wahrscheinlich einige event loop (z um poll(2)) haben.

BTW, sollten Sie sich bewusst sein, dass Input-Output-buffered ist, und Sie wollen wahrscheinlich sicher sein, dass Ihr gnuplot Strom gespült wird regelmäßig (so verwenden std::endl oder std::flush auf sie entsprechend). Ein \n schreiben ist nicht genug!Sie sollten wahrscheinlich mindestens

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

Code (ich habe einige \n in einem String mit einer expliziten Verwendung von std::endl ersetzt) ​​

Ich weiß nicht viel über gnuplot stream (Ich vermute, es ist ein bisschen wie einige spezialisierte popen, aber mit C++ - Streams), aber ich denke, dass Sie die Gnuplot print oder printerr Befehl, um mit Ihrem aufrufenden Programm die Tatsache, dass eine bestimmte Kurve geplottet wurde kommunizieren sollte. (Aber dann brauchen Sie eine echte Ereignisschleife, und Sie definieren ein bidirektionales Protokoll zwischen gnuplot und Ihrem Programm.).

Vielleicht Qt oder POCO möglicherweise relevant, weil sie einige Vorstellung von Ereignisschleife und Prozesse bieten. Vielleicht haben Sie vielleicht mehrere Threads (eine, die gnuplot verwaltet und die andere für den Rest), aber dann haben Sie Synchronisationsprobleme.

(Ich verstehe nicht genug, was Ihr Programm tun soll, und wie Sie es codiert haben, so dass es eine blinde Vermutung ist, ich fühle mich Ihre Frage sehr unklar ist)

Lesen Sie mehr Inter-Process Communications.

+0

Hey, ich arbeite auf Linux-Rechner, das stimmt, aber ich möchte nicht systemspezifische Aufrufe verwenden, wenn möglich. Ich bin neu in diesem gnuplot-iostream und habe mich einem solchen Problem gestellt, das ich lösen kann, indem ich zwei separate Programme schreibe, aber zuerst möchte ich herausfinden, ob es vielleicht einen Weg gibt, es innerhalb des einen Codes zu lösen. –

+0

Aber Ihre Frage zeigt nicht genug Code und ist immer noch unklar. Ich glaube, Sie verstehen etwas Wesentliches falsch. Vielleicht sind die Probleme nicht dort, wo du sie glaubst. –

+0

Mit Qt muss ich selbst eine Anpassungsfunktion schreiben. In meiner Arbeit muss ich das gnuplot verwenden, um die passenden Parameter zu erhalten und sie später im C++ - Code und im gnuplot zu verwenden. Also, es ist keine gute Alternative für mich –

Verwandte Themen