Textmeldungen sehr schnell speichern und später auslesen - wie?



  • Ich stehe gerade aufm Schlauch.

    Ich schreibe ein MFC Programm, das auf ein USB Gerät Daten schreibt und dabei Textausgaben macht. Da die Performance extrem in den Keller sinkt, wenn ich die Textausgaben bei jedem Schreibvorgang mache, will ich alle Meldungen sammeln und später ausgeben.

    Dazu hab ich mir gedacht, ich mache sowas:

    char** LogText[1000];			// Array, das 1000 Fehlermeldungen hält
    
    (...)
    
    // Hier die Speicherung 
    
    for(;;) // also hier läuft irgend eine Schleife
    {
           (...)
    	if ((FoundErrors > 0) && (FoundErrors < sizeof(LogText)))
    	{
    		char* Text = new char [32];		
    
    		strcpy(Text, "Geschrieben: " + IntToHexCString(SendBuffer[i]) + " Gelesen: " + IntToHexCString(ReceiveBuffer[i]) + ".\r\n");
    
    		LogText[FoundErrors] = &Text;
    	}
    	FoundErrors ++;
    }
    
    (...)
    
    // Wenn alles vorbei ist, soll eine log-Datei geschrieben werden:
    
    if (FoundErrors > 0)	// Wenn Fehler gefunden wurden
    {		
    	m_TextUpdate += "\r\nSchreibe Log-Datei...\r\n";
    	DoEvents();
    
    	char* Text = new char [32];
    	for (i=0 ; i <= FoundErrors ; i++)
    	{
    		&Text = LogText[i];		// hier kommt der Compiler-Fehler: error C2106: '=' : Linker Operand muss ein L-Wert sein
    		LogFile << &LogText[i];	
    		//delete &LogText[i];
    	}
    	// Log-File öffnen
    	ShellExecute(0, "open", "log.txt", NULL, NULL, SW_SHOWNORMAL);
    }
    

    Ich weiß das das, was ich geschrieben hab, so nicht geht. Ich wollte damit nur zeigen was ich machen will.

    Fragen dazu:

    - Ist die Variante so intelligent? Während des schreibvorgangs muss das Sichern der Error-Texte so schnell wie möglich gehen, daher will ich da mit den zeigern rumhantieren
    - Wenn das so intelligent ist, wie muss man es abändern damit es funktioniert? Er schreibt mir nur Müll in die Textdatei!



  • versuch's mal so:

    #include <iostream>
    #include <fstream>  // ifstream
    #include <sstream>  // i/ostringstream
    
        using namespace std;
        stringstream logText;   // Stream; Raum bis der Speicher platzt
        for(;;)
        {
            // ...
            // -- Schreibe in's Logbuch
            logText << "Geschrieben: " << SendBuffer[i] << " Gelesen: " << ReceiveBuffer[i] << endl;
        }
    
        // später
        if (FoundErrors > 0)    // Wenn Fehler gefunden wurden
        {
            ofstream file( "log.txt" ); // Log-File öffnen
            file << logText.rdbuf(); // alles rein
        }
        return 0;
    

    wenn das immer noch nicht schnell genug ist (warum habt Ihr es immer so eilig), dann speichere die beiden Integerwerte SendBuffer[i] und ReceiveBuffer[i] in einer struct Info und packe die in einen STL-Container (z.B. vector). Am Ende kannst Du das dann in Ruhe ausgeben.

    Gruß
    Werner



  • Sehr gut, das funktioiert!!

    Allerdings gibts ein Problem:

    LogText << "Geschrieben: " << IntToHexCString(SendBuffer[i]) << " Gelesen: " << IntToHexCString(ReceiveBuffer[i]) << endl;
    

    Das erzeugt mir die falschen Werte für die Receive- und Sendebuffer. Da drin steht ein Byte, das ich gern hexdezimal ausgeben will. Das mach ich mit der Funktion InttoHexCString gemacht, die so aussieht:

    CString MyWriter::IntToHexCString(int Zahl)
    { 
    	CString mystring;
    	mystring.Format("%X", Zahl);
    	if (Zahl < 15)
    		return "0" + mystring;
    	else
    		return mystring;
    }
    

    Dann spuckte er mir sowas aus: "Geschrieben: 00 Gelesen: FA". so will ichs haben.

    Jetzt, mit deiner Version, macht er sowas: "Geschrieben: 00336DDC Gelesen: 0033711C". Das will ich nicht 🙂

    Warum das denn? Ist mir unklar. Wie mache ich das so, das er mit nur das Byte als Hex-Wert anzeigt, also so wies vorher war?

    Edit: Bei großen datenmengen stürzt dasProgramm ab - "der vrogang read() konnte nicht auf dem Speicher ausgeführt werden"...



  • Querdenker schrieb:

    Jetzt, mit deiner Version, macht er sowas: "Geschrieben: 00336DDC Gelesen: 0033711C". Das will ich nicht 🙂

    Nee - nicht mit meiner Version. Du schreibst

    Querdenker schrieb:

    LogText << "Geschrieben: " << IntToHexCString(SendBuffer[i]) << " Gelesen: " << IntToHexCString(ReceiveBuffer[i]) << endl;
    

    IntToHexCString kam in meiner Version nicht vor.

    Dort wird versucht einen CString auf einem ostream auszugeben. Der Compiler frisst das, weil MS eine implizite Konvertierung von CString nach TCHAR* vorgesehen hat. Und der ostream kann jeden Pointer ausgeben. Vor impliziten Konvertierungen sollte man sich hüten.

    Das Formatieren von Bytes in Hex schön mit 0'en aufgefüllt ist ein wenig lästig. Der C++-Weg wäre in etwa dieser:

    // erfordert zusätzlich #include <iomanip>
    struct WriteByte
    {
        explicit WriteByte( char c )  // oder BYTE c
            : m_c( c ) {}
        friend std::ostream& operator<<( std::ostream& out, WriteByte b )
        {
            // Byte formatiert in hex ausgeben
            const char fillOld = out.fill('0');
            const std::ios_base::fmtflags flagsOld = out.flags();
            out << std::hex << std::setw(2) << std::uppercase << unsigned( b.m_c );
            out.flags( flagsOld );
            out.fill( fillOld );
            return out;
        }
    private:
        unsigned char m_c;
    };
    

    und beim Aufruf dann

    LogText << "Geschrieben: " << WriteByte(SendBuffer[i]) << " Gelesen: " << WriteByte(ReceiveBuffer[i]) << endl;
    

    Gruß
    Werner



  • Klappt so nicht:

    error C2440: 'type cast' : 'unsigned char' kann nicht in 'struct MyWriter::WriteByte' konvertiert werden



  • dann mach doch einfach aus dem

    explicit WriteByte( char c )  // oder Byte c
    

    ein

    explicit WriteByte( unsigned char c )  // oder WriteByte( BYTE c )
    

    (siehe Kommentar hinter der Zeile)

    Gruß
    Werner



  • Querdenker schrieb:

    error C2440: 'type cast' : 'unsigned char' kann nicht in 'struct MyWriter::WriteByte' konvertiert werden

    .. das sollte trotzdem gehen. In welcher Code-Zeile erscheint der Fehler?



  • LogText << FoundErrors << ": Geschrieben: " << WriteByte(SendBuffer[i]) << " Gelesen: " << WriteByte(ReceiveBuffer[i]) << endl;
    

    Für beide Aufrufe jeweils:

    error C2440: 'type cast' : 'unsigned char' kann nicht in 'struct MyWriter::WriteByte' konvertiert werden
    Quelle oder Ziel hat einen unvollstaendigen Typ



  • Quelle oder Ziel hat einen unvollstaendigen Typ

    kann es sein, dass du da irgendwo ne vorwärtsdeklaration gemacht hast?



  • otze schrieb:

    kann es sein, dass du da irgendwo ne vorwärtsdeklaration gemacht hast?

    wahrscheinlich ...

    Schreibe die struct WriteByte, so wie ich sie gepostet habe, vor die Methode oder Funktion, wo sie benutzt wird; in das cpp-File hinein.
    Das sollte funktionieren.

    Gruß
    Werner



  • Sorry das ich mich so lange nich gemeldet habe 🙂

    Ich hab alle eure Tipps befolgt, es hilft nur nichts:

    C:\USBIO\USBTest\MyWriter.cpp(650) : error C2440: 'type cast' : 'unsigned char' kann nicht in 'struct MyWriter::WriteByte' konvertiert werden
            Quelle oder Ziel hat einen unvollstaendigen Typ
    

    Und das für beide Aufrufe der struct, die struct steht vor ihrem Aufruf in der cpp Datei.



  • Dann solltest du den Ctor von WriteByte so anpassen, daß er einen unsigned char entgegennehmen kann (anstelle des platten 'char').



  • Querdenker schrieb:

    Ich hab alle eure Tipps befolgt, es hilft nur nichts:

    C:\USBIO\USBTest\MyWriter.cpp(650) : error C2440: 'type cast' : 'unsigned char' kann nicht in 'struct MyWriter::WriteByte' konvertiert werden
            Quelle oder Ziel hat einen unvollstaendigen Typ
    

    Und das für beide Aufrufe der struct, die struct steht vor ihrem Aufruf in der cpp Datei.

    Nein - nach der Fehlermeldung hast Du sie zur nested struct Deiner Klasse MyWriter gemacht und sie ist nicht vollständig definiert. Poste doch mal das Codesegment von struct WriteByte bis zum Ende der Methode wo Du die struct anwendest.
    Vielleicht hast Du auch bloß den Konstruktor vergessen, oder so was.

    Ist die Klasse MyWriter in einem H-File definiert oder im cpp-File?

    Gruß
    Werner


Anmelden zum Antworten