Zeichenkette und Variable verknüpfen



  • Hallo zusammen,
    aller Anfang ist schwer. Am Ende soll folgender Aufruf rauskommen:

    system("digitemp -o"%.2C" -t3 -l/home/bernd/digitemp-1.3/temperatur");
    

    Der Aufruf ist in einer Funktion eingebettet und von aussen wird die Nummer des Sensors (-t3) übergeben.

    int sensor = 3;		
    string s;
    ostringstream outStream;
    outStream << sensor;
    s = outStream.str();
    string vor = "\"digitemp -o\"%.2C\" -t";
    string nach = " -l/home/bernd/digitemp-1.3/temperatur\"";
    string all = vor + s + nach;
    std::cout << all;
    //system(all);
    

    Die Ausgabe am Bildschirm sieht wie gewünscht aus. Wenn ich die Auskommentierung von system(all); wegnehmen, erhalte ich beim Kompilieren folgenden Fehler:

    Fehler: »std::string« kann nicht nach »const char*« für Argument »1« nach »int system(const char*)« umgewandelt werden
    

    Wenn ich das richtig verstehe, muß ich den string all in const char umwandeln?
    Habe aber nichts wirklich passendes gefunden und bitte daher um eure Hilfe.

    Gruß
    Bernd


  • Mod

    bernd_h_schulz schrieb:

    Habe aber nichts wirklich passendes gefunden und bitte daher um eure Hilfe.

    Wie suchst du denn, dass du das nicht findest?

    http://www.cplusplus.com/reference/string/string/c_str/



  • Danke SeppJ,
    das hat geholfen, so klappt es jetzt.

    double digitemp(int sensor)
    	{
    		std::remove("/home/bernd/digitemp-1.3/temperatur.txt");
    		string s;
    		ostringstream outStream;
    		outStream << sensor;
    		s = outStream.str();
    		string vor = "digitemp -o\"%.2C\" -t";
    		string nach = " -l/home/bernd/digitemp-1.3/temperatur.txt";
    		string all = vor + s + nach;
    		cstr = new char [all.size()+1];
    		strcpy (cstr, all.c_str());
    		system(cstr);
    
    		std::ifstream iff("/home/bernd/digitemp-1.3/temperatur.txt");
    		iff >> temp;
    		return d2i(temp);
    	}
    


  • das geht so gar ganz ohne memory-leak (zu jedem new[] gehört auch ein delete[]).
    die signatur ist ja auch system(const char*) - da brauchst du den const char* nicht erst in nen char* umwandeln...

    bernd_h_schulz schrieb:

    std::string inttostr(int x)
    {
    	std::string R;
    	stringstream ss;
    	ss << sensor;
    	ss >> R;
    	return R;
    }
    
    double digitemp(int sensor)
    {
    	std::remove("/home/bernd/digitemp-1.3/temperatur.txt");
    	string s = inttostr(sensor);
    	string vor = "digitemp -o\"%.2C\" -t";
    	string nach = " -l/home/bernd/digitemp-1.3/temperatur.txt";
    	string all = vor + s + nach;
    	system(all.c_str());
    
    	std::ifstream iff("/home/bernd/digitemp-1.3/temperatur.txt");
    	iff >> temp;
    	return d2i(temp);
    }
    


  • Gerade hat mir der stringstream eine mail geschickt und drum gebeten, die ganze Aneinanderkleberei der strings übernehmen zu dürfen. Er sagt, das sei dann ganz übersichtlich und auch noch schneller als zuvor.

    double digitemp(int sensor)
    	{
    		std::remove("/home/bernd/digitemp-1.3/temperatur.txt");
    		ostringstream cmd;
    		cmd << "digitemp -o\"%.2C\" -t" << sensor << " -l/home/bernd/digitemp-1.3/temperatur.txt";
    		system(cstr.str().c_str());
    
    		std::ifstream iff("/home/bernd/digitemp-1.3/temperatur.txt");
    		iff >> temp;
    		return d2i(temp);
    	}
    


  • volkard schrieb:

    Gerade hat mir der stringstream eine mail geschickt und drum gebeten, die ganze Aneinanderkleberei der strings übernehmen zu dürfen. Er sagt, das sei dann ganz übersichtlich und auch noch schneller als zuvor.

    hab ich zwar überlegt(weils hübscher aussieht), aber mir ist kein einziger grund eingefallen, wieso es so schneller sein sollte - link oder so? will ja nicht ganz dumm sterben 😉

    bb



  • unskilled schrieb:

    hab ich zwar überlegt(weils hübscher aussieht), aber mir ist kein einziger grund eingefallen, wieso es so schneller sein sollte - link oder so? will ja nicht ganz dumm sterben 😉

    bb

    Wenn du Strings so zusammenfügst (vor + s + nach), werden jede Menge temporäre Strings erzeugt und für diese jeweils Speicher alloziiert und wieder freigegen, was teuer ist/sein kann. stringstreams müssen nur neuen Speicher anfordern, wenn ihre Kapazität erschöpft ist.



  • Nanyuki schrieb:

    unskilled schrieb:

    hab ich zwar überlegt(weils hübscher aussieht), aber mir ist kein einziger grund eingefallen, wieso es so schneller sein sollte - link oder so? will ja nicht ganz dumm sterben 😉

    bb

    Wenn du Strings so zusammenfügst (vor + s + nach), werden jede Menge temporäre Strings erzeugt und für diese jeweils Speicher alloziiert und wieder freigegen, was teuer ist/sein kann. stringstreams müssen nur neuen Speicher anfordern, wenn ihre Kapazität erschöpft ist.

    Hmmm - ich war davon ausgegangen, dass der Compiler da so ziemlich alles wegoptimieren kann(weil ja alles schon zur compile-zeit bekannt ist). aber wenn ich das jz richtig gesehen hab, kann zumindest msvc da nicht all zu viel machen... gut, dann ists klar, wieso es langsamer ist...
    ich hatte nur bisher immer gehört, dass der +=op vom string um ein vielfaches schneller ist als der <<op aller streams, deshalb hab ich mich gewundert, dass volkard so sehr überzeugt davon war, obwohl der großteil der arbeit mit strings schneller geht...

    Und wenn man es schon vergleichen möchte, dann sollte man es hiermit vergleichen:

    #include <string>
    #include <sstream>
    #include <cstdlib>
    
    std::string inttostr(int x) 
    { 
        std::string R; 
        std::stringstream ss; 
        ss << x;
        ss >> R; 
        return R; 
    } 
    
    int main()
    {
        std::string cmd = "digitemp -o\"%.2C\" -t"; 
        cmd += inttostr(1);
        cmd += " -l/home/bernd/digitemp-1.3/temperatur.txt"; 
    
        system(cmd.c_str());
    }
    

    hier ist die string-variante bestimmt wieder schneller...

    wobei

    int main()
    {
        std::string cmd = "digitemp -o\"%.2C\" -t" + inttostr(1) + " -l/home/bernd/digitemp-1.3/temperatur.txt";
    
    	system(cmd.c_str());
    }
    

    sieht aber auch nicht gerade langsamer aus - zumindest, wenn ich den asm-code überfliege...

    bb



  • unskilled schrieb:

    Hmmm - ich war davon ausgegangen, dass der Compiler da so ziemlich alles wegoptimieren kann(weil ja alles schon zur compile-zeit bekannt ist).

    Es sind meistens sehr viele Informationen zur Compilezeit bekannt, und trotzdem hat der Compiler Mühe mit Optimieren. Vielleicht sind bei std::string die Chancen etwas höher, weil der Compiler die Implementierung kennt, aber bei eigenen Klassen glaube ich kaum, dass da viel gemacht werden kann. Temporäre Objekte werden meistens im Zusammenhang mit Funktionsaufrufen oder -rückgabewerten optimiert (unnötige Kopien); in den anderen Fällen bräuchte es recht viel Aufwand von Seiten des Compilers, um gleiches Verhalten ohne temporäre Objekte zu reproduzieren.

    Ausserdem finde ich es immer etwas heikel, leichtsinnig von grösseren Optimierungen auszugehen, wenn eine Alternative bessere Aussichten auf Erfolg bietet.

    unskilled schrieb:

    hier ist die string-variante bestimmt wieder schneller...

    Hmm, ich weiss nicht. Von Stringstreams erwarte ich eigentlich eher, dass sie flexibel mit unterschiedlichen Datengrössen umgehen können und effiziente Puffer haben, schliesslich sind sie Streams. Das sind zumindest meine Vermutungen. Du könntest jedoch std::string mit reserve() etwas nachhelfen.


Anmelden zum Antworten