string to char*



  • TTS schrieb:

    int  iJahr, iMonat, iTag, iStunde, iMinute, iSekunde;
    	string  jahr, monat, tag, stunde, minute, sekunde, datum;
    

    Definiere Deine Variablen so spät wie möglich.

    time_t sekunden = time(NULL); 
    	tm *uhr = localtime(&sekunden); 
    
    	iJahr    = uhr->tm_year +1900;
    	iMonat   = uhr->tm_mon +1;
    	iTag     = uhr->tm_mday;
    	iStunde  = uhr->tm_hour;
    	iMinute  = uhr->tm_min;
    	iSekunde = uhr->tm_sec;
    
    	IntToString( iJahr,    jahr   );
    	IntToString( iMonat,   monat  );
    	IntToString( iTag,     tag    );
    	IntToString( iStunde,  stunde );
    	IntToString( iMinute,  minute );
    	IntToString( iSekunde, sekunde);
    
    	datum = jahr + "_" += monat + "_" += tag + "_" += stunde + "h_" += minute + "m_" += sekunde + "s.CSV";
    
    	string fileName;
    	strcpy(fileName, datum); // Error 1
    

    Warum Du hier += und + abwechselst, ist mir ein Rätsel.
    Und das, was Du da mit strcopy versuchst, geht so:

    string fileName = datum;
    

    Die ganzen anderen Stringvariablen kannst Du Dir auch sparen:

    std::stringstream ss;
      ss << iJahr << '_' << iMonat << ..... "s.CSV";
      string datum = ss.str();
      ofstream outputFile( datum.c_str() );
    
    ofstream outputFile( datum); // Error2
    

    Das muss

    fostream outputFile( datum.c_str() );
    

    heißen. Ich hätte hier übrigens fileName statt datum erwartet.

    Du solltest verstehen, wo genau der Unterschied zwischen std::string und char* ist. Dieses Verständnis ist scheinbar im Moment nicht vorhanden. Hole das bitte nach.



  • lk schrieb:

    Ja, aber bitte nur den Code den man auch braucht.

    Dann find wenigstens raus, welche Codestellen relevant sind.

    Also, wenn du das Programm kompillieren willst, sind alle stellen relevant, wenn du mir aus dem code heraus sagen kannst was falsch ist, wirst du nur diese Funktion benötigen.

    /////////////////////////////////////////////////////////////////////////////
    // CFluke45_ComPort message handlers
    // Range:	1: 300mV
    // Range:	2: 3V
    // Range:	3: 30V
    // Range:	4: 300V
    
    BOOL CFlukeReader::GetDCVoltage(double * DCVoltage, WORD Range, ofstream outputFile)
    {
    
    	char MessageToFluke[80]={0};
    	char RecDataArray[80]={1};
    	CString CMessageToFluke, CReceiveData;
    	int length_of_txmsg, NumberOfRxChar;
    	NumberOfRxChar = 80;
    	unsigned long bytesRead;
    	unsigned long bytesSent;
    
    	switch(Range)
    	{
    		case 1:
    			strcpy(MessageToFluke, "VDC; FIXED; RANGE 1; RATE M;\x0d\x0a");
    			break;
    		case 2:
    			strcpy(MessageToFluke, "VDC; FIXED; RANGE 2; RATE M;\x0d\x0a");
    			break;
    		case 3:
    			strcpy(MessageToFluke, "VDC; FIXED; RANGE 3; RATE M;\x0d\x0a");
    			break;
    		case 4:
    			strcat(MessageToFluke, "VDC; FIXED; RANGE 4; RATE M;\x0d\x0a");
    			break;
    		default:
    			strcpy(MessageToFluke, "VDC; AUTO; RATEM;\x0d\x0a");
    			break;
    	}
    	length_of_txmsg = strlen(MessageToFluke);
    	m_serialPort->SendData(length_of_txmsg, MessageToFluke, &bytesSent);
        Sleep(1000); // wait until measurement was performed (Einschwingverzögerung)
    	m_serialPort->ReceiveData(NumberOfRxChar, RecDataArray, &bytesRead);
    
    	strcpy(MessageToFluke, "MEAS1?\x0d\x0a");
    	length_of_txmsg = strlen(MessageToFluke);
    	m_serialPort->SendData(length_of_txmsg, MessageToFluke, &bytesSent);
    	m_serialPort->ReceiveData(NumberOfRxChar, RecDataArray, &bytesRead);
    	CReceiveData = RecDataArray;
    	if(CReceiveData.Find( "=>" ) > 0 )
    	{
    		*DCVoltage = atof(RecDataArray);
    
    		stringstream parser;
    		parser.write(RecDataArray,80);  // Stream mit deinen Daten füllen
    		string line;
    		getline(parser, line);   // line enthält nun die erste Zeile
    		getline(parser, line);   // line enthält nun die zweite Zeile
    		line += '\n';
    
    		outputFile << line << "\n";
    		strcpy(MessageToFluke, "VDC; AUTO; RATE M;\x0d\x0a");
    		length_of_txmsg = strlen(MessageToFluke);
    		m_serialPort->SendData(length_of_txmsg, MessageToFluke, &bytesSent);
    		m_serialPort->ReceiveData(NumberOfRxChar, RecDataArray, &bytesRead);
    		return(TRUE);
    	}
    	if(CReceiveData.Find( "?>" ) > 0 )
    	{
    		// Command syntax error
    		*DCVoltage = 0;
    		strcpy(MessageToFluke, "VDC; AUTO; RATE M;\x0d\x0a");
    		length_of_txmsg = strlen(MessageToFluke);
    		m_serialPort->SendData(length_of_txmsg, MessageToFluke, &bytesSent);
    		m_serialPort->ReceiveData(NumberOfRxChar, RecDataArray, &bytesRead);
    		return(FALSE);
    	}
    	if(CReceiveData.Find( "!>" ) > 0 )
    	{
    		// Command Failure
    		*DCVoltage = 0;
    		strcpy(MessageToFluke, "VDC; AUTO; RATE M;\x0d\x0a");
    		length_of_txmsg = strlen(MessageToFluke);
    		m_serialPort->SendData(length_of_txmsg, MessageToFluke, &bytesSent);
    		m_serialPort->ReceiveData(NumberOfRxChar, RecDataArray, &bytesRead);
    		return(FALSE);
    	}
    	*DCVoltage = 0;
    	strcpy(MessageToFluke, "VDC; AUTO; RATEM;\x0d\x0a");
    	length_of_txmsg = strlen(MessageToFluke);
    	m_serialPort->SendData(length_of_txmsg, MessageToFluke, &bytesSent);
    	m_serialPort->ReceiveData(NumberOfRxChar, RecDataArray, &bytesRead);
    
    	return(FALSE);
    }
    

    lk schrieb:

    Was man jetzt schon sehen kann: Kann es sein, dass der Code nicht von dir "geschrieben" sondern zusammenkopiert wurde?

    Nun, ich habe für einige Teile eine Vorlage bekommen aus der ich einige Stellen ableiten konnte, jedoch musste ich den grössten Teil selbst entwickeln. Bin nun auch schon mehr als ein Monat an dieser Aufgabe.



  • Habe alles schon geändert was du gesagt hast, war wohl noch alter code.

    seufz schrieb:

    ofstream outputFile( datum); // Error2
    

    Das muss

    fostream outputFile( datum.c_str() );
    

    heißen. Ich hätte hier übrigens fileName statt datum erwartet.

    Das habe ich vergessen zu ändern. Habs jetzt korrigiert, stürzt trotzdem immer noch ab.

    seufz schrieb:

    Du solltest verstehen, wo genau der Unterschied zwischen std::string und char* ist. Dieses Verständnis ist scheinbar im Moment nicht vorhanden. Hole das bitte nach.

    Ja, das mit diesen char* und char[] und string ist noch ziemlich verwirrend für mich.. Werde mich mal etwas schlau machen.



  • BOOL GetDCVoltage(double *DCVoltage, WORD Range, ofstream outputFile);
    

    streams sind nicht kopierbar...
    Für was BOOL wenn C++ auch bool kennt?
    Und dein GANZES Projekt will niemand kompilieren, sondern von dir ein möglichst am Original gehaltenes Beispiel, das deinen Fehler (beim Kompilieren oder zur Laufzeit) reproduzieren lässt, damit man auch gezielt helfen kann. Hat den wunderbaren Nebeneffekt, dass du dich selber noch mal ausgiebig mit dem Code beschäfitgen musst und einiges dabei lernen kannst.



  • l'abra d'or schrieb:

    BOOL GetDCVoltage(double *DCVoltage, WORD Range, ofstream outputFile);
    

    streams sind nicht kopierbar...

    Danke, das wars. Wusste nicht, dass man streams nicht kopieren kann, hab nun einen Pointer darauf gemacht jetzt stürzt es nicht mehr ab.



  • TTS schrieb:

    Danke, das wars. Wusste nicht, dass man streams nicht kopieren kann, hab nun einen Pointer darauf gemacht jetzt stürzt es nicht mehr ab.

    Hier wäre statt nem Pointer eine Referenz besser (Bedeutung, Sicherheit und Handling). Und wenn das tatsächlich einen Laufzeitfehler (Absturz) produziert hat, würde ich sofort den Compiler wechseln, denn das dürfte nicht mal kompilieren!



  • Moment..

    zwar stürzt es nicht mehr ab, jedoch wird nichts mehr in das File geschrieben.. hier die Definition der Funktion:

    BOOL GetDCVoltage(double *DCVoltage, WORD Range, ofstream *outputFile); //Funktionsdefinition im Headefile
    
    BOOL CFlukeReader::GetDCVoltage(double * DCVoltage, WORD Range, ofstream *outputFile)    // Implementation der Funktion (gekürzt)
    {        stringstream parser;
            parser.write(RecDataArray,80);  // Stream mit deinen Daten füllen
            string line;
            getline(parser, line);   // line enthält nun die erste Zeile
            getline(parser, line);   // line enthält nun die zweite Zeile
            line += '\n';
    
            *outputFile << line << "\n";    //Hier sollte line in über den Pointer in das File geschrieben werden
    }
    
    //Main
    ofstream outputFile( fileName.c_str(), ios::app);    //Hier wird der Stream generiert
    flukeReader.GetDCVoltage(&DCVoltage, Range, &outputFile);   // Funktionsaufruf
    


  • l'abra d'or schrieb:

    Hier wäre statt nem Pointer eine Referenz besser (Bedeutung, Sicherheit und Handling). Und wenn das tatsächlich einen Laufzeitfehler (Absturz) produziert hat, würde ich sofort den Compiler wechseln, denn das dürfte nicht mal kompilieren!

    Wie würde man das denn mit einer Referenz statt einem Pointer lösen?

    Compiler wechseln geht nicht.. das Geschäft besteht auf vc++ 6.. mit standardcompiler



  • TTS schrieb:

    Wie würde man das denn mit einer Referenz statt einem Pointer lösen

    BOOL CFlukeReader::GetDCVoltage(double * DCVoltage, WORD Range, ofstream &outputFile)    // Implementation der Funktion (gekürzt) 
    {        stringstream parser; 
            parser.write(RecDataArray,80);  // Stream mit deinen Daten füllen 
            string line; 
            getline(parser, line);   // line enthält nun die erste Zeile 
            getline(parser, line);   // line enthält nun die zweite Zeile 
            line += '\n'; 
    
            outputFile << line << "\n";
    }
    

    Geht also nur über Änderung der Signatur deiner Funktion. Und das "double* DCVoltage" könntest du im selben Schritt auch noch als Referenz übergeben. Damit verhinderst du, dass irgendjemand ein "NULL" übergibt - und damit nen SegFault provoziert - ein Zeiger als Parameter erlaubt dies und legt es sogar nahe, worauf du aber gar nicht eingerichtet bist.

    Und jetzt poste doch mal bitte ein minimales (!!!) kompilierbares Beispiel, das bei dir zu dem Problem führt. Hier hat niemand große Lust, den gewaltigen Quelltext, der sich nichtmal übersetzen lässt, nach möglichen Problemen und Nebeneffekten zu durchsuchen.



  • Danke. Habs geschnallt mit der Referenz, es läuft nun alles i.o. Jeoch wenn ich hinter dem string der ins CSV File geschrieben werden soll ein << endl; anfüge fügt es mir eine leere Zeile ein. Wenn ich hingegen ein \n anfüge wird gar nichts mehr ins File geschrieben.

    outputFile << line << endl; // Ergibt 1 leere Zeile zwischen den Einträgen
    
    outputFile << line << "\n"; // Gibt nichts aus
    

    Sowohl die Ausgabe des Zeichens "\n" als auch die Verwendung des Manipulators "::std::endl" bewirken die Ausgabe eines Neuzeilenzeichens. Das "::std::endl" (end line ) bewirkt zusätzlich danach eine Synchronisation : Alle vorübergehend noch zwischengespeicherten Daten werden dabei tatsächlich ausgegeben.

    Ich vermute es hat etwas mit dem zu tun, jedoch komme ich einfach nicht auf die Lösung, wenn ich eine normale Textdatei nehme statt ein CSV File, fügt es mir nicht noch leere Zeilen dazwischen.

    Weis jemand genauer an was es liegt?



  • TTS schrieb:

    wenn ich eine normale Textdatei nehme statt ein CSV File, fügt es mir nicht noch leere Zeilen dazwischen.

    std::fstream kennt kein csv. Die Formatierung deines csv nimmst du selber vor. Wenn also mit csv gegenüber einer normalen Textdatei Probleme auftauchen, liegt es an deinem Code.
    Einen Unterschied im Ergebnis zwischen std::endl und "\n" sehe ich hier nicht - jedenfalls bei deinem Beispielcode aus dem anderen Thread. Kann es vllt. sein dass du zu viel reinschreibst? In regelmäßigen Abständen ein std::flush(stream) wäre ein guter Versuch.



  • Nun, ich weis auch nicht was das Problem war, auf jeden Fall bein "\n" gab es nichts aus bei << endl; gab es mir eine leere Zeile dazwischen aus.

    Bin auch gerade auf das flush gestossen. Das war die richtige lösung 🙂


Anmelden zum Antworten