CStringW zu std:string



  • Das ist keine option. Das ganze wird auf mehreren tausend Rechner installiert die teilweise nur 1gb ram haben. Das Programm selber braucht im Idle 4mb Ram. Wenn dann die Prozedur startet geht es bis auf 120mb hoch. es kommen immer Datenblocke von ca. 10-200mb rein. Das ganze kommt als const char* an.

    Das muss dann gefiltert werden. Das ganze ist wie eine XML aufgebaut wobei jeder Tag nur einmal vorkommt und es keine Baumstruktur ist. Vor dem Datenstrom steht ein Schlusselwort "<DataStream>" Danach muss dann erst mal gesucht werden. Das Ende ist mit </DataStream>" markiert. Deswegen wird das ganze erstmal in einen CString konvertiert und dann unbenötigte teile "deleted". Anschließend bekomme ich diesen Stream zum Base64 decodieren. Hierzu benutze ich eine Funktion die einen std::String erwartet.

    Hmm wie kann ich denn im const char* nach "DataStream" suchen? Da müsste ich eine Funktion schreiben die nach "D" sucht und dann das nächste zeichen mit dem "Eingabestring" vergleicht. Das an das ende würde ich dann vermutlich einen Pointer zeigen lassen um danach die zeichen zählen bis ich das ende gefunden habe.. das wird alles sehr abenteuerlich^^

    BTW eine weitere Frage. Ich schreibe den decodierten Stream in eine Datei mit CFile. Mir ist jetzt aufgefallen, das ich auf C:\\ keine Datei anlegen kann (vermutlich rechte aufm Firmenrechner). Allerdings spuckt mir CFile keinen Fehler aus. Das tut so als ob nix wäre. Aber es wird keine Datei angelegt. Hab ich hier was vergessen?



  • 🙄 oje.



  • lulu32_0 schrieb:

    Das ist keine option. Das ganze wird auf mehreren tausend Rechner installiert die teilweise nur 1gb ram haben.

    OK, dann ist RAM Upgrade wohl wirklich keine (gute) Option.

    lulu32_0 schrieb:

    Hmm wie kann ich denn im const char* nach "DataStream" suchen? Da müsste ich eine Funktion schreiben die nach "D" sucht und dann das nächste zeichen mit dem "Eingabestring" vergleicht. Das an das ende würde ich dann vermutlich einen Pointer zeigen lassen um danach die zeichen zählen bis ich das ende gefunden habe.. das wird alles sehr abenteuerlich^^

    Naja es gibt die fertige Funktion strstr die man verwenden könnte.

    lulu32_0 schrieb:

    BTW eine weitere Frage. Ich schreibe den decodierten Stream in eine Datei mit CFile. Mir ist jetzt aufgefallen, das ich auf C:\\ keine Datei anlegen kann (vermutlich rechte aufm Firmenrechner).

    Im Rootverzeichnis eines Volumes haben normale Benutzer normalerweise nicht das Recht Dateien zu erzeugen.

    lulu32_0 schrieb:

    Allerdings spuckt mir CFile keinen Fehler aus. Das tut so als ob nix wäre. Aber es wird keine Datei angelegt. Hab ich hier was vergessen?

    Möglicherweise werden die Files von Windows "umgeleitet". Bei Root-Verzeichnissen wäre mir diesbezüglich zwar nix bekannt, aber du kannst ja mal unter %LocalAppData%\VirtualStore nachgucken, ob dein File vielleicht da zu finden ist.

    Die Lösung ist aber auf jeden Fall einen anderen Pfad zu verwenden. Mach einfach ein eigenes Verzeichnis irgendwo, da darfst du dann reinschreiben.



  • ps:

    lulu32_0 schrieb:

    Vor dem Datenstrom steht ein Schlusselwort "<DataStream>" Danach muss dann erst mal gesucht werden. Das Ende ist mit </DataStream>" markiert. Deswegen wird das ganze erstmal in einen CString konvertiert und dann unbenötigte teile "deleted".

    Du musst gar nix löschen.
    Es reicht z.B. wenn du das "<" von "</DataStream>" mit einer binären Null ("\0") überschreibst.
    Dann kannst du den Zeiger auf das Zeichen hinter dem ">" von "<DataStream>" an jede Funktion übergeben die einen C-String (= const char* ) erwartet, und es wird funktionieren.

    lulu32_0 schrieb:

    Anschließend bekomme ich diesen Stream zum Base64 decodieren. Hierzu benutze ich eine Funktion die einen std::String erwartet.

    Mach die Base64 Dekodierung selbst, direkt mit dem const char* . Ist ja nicht so schwer.
    Dann kannst du an die Funktion auch gleich die Länge des (kodierten) Base64 Strings übergeben, und kannst dir das Überschreiben des "<" mit "\0" sparen.

    So kannst du das alles machen ohne jemals irgendwo grössere Speichermengen anzufordern. Abgesehen von dem einen grossen Puffer in dem die ganze Nachricht inklusive der pseudo-XML Tags drinsteht. Den auch noch zu eliminieren wäre dann aber einigermassen viel Aufwand, und wird vermutlich auch nicht nötig sein.



  • lulu32_0 schrieb:

    Hmm wie kann ich denn im const char* nach "DataStream" suchen? Da müsste ich eine Funktion schreiben die nach "D" sucht und dann das nächste zeichen mit dem "Eingabestring" vergleicht. Das an das ende würde ich dann vermutlich einen Pointer zeigen lassen um danach die zeichen zählen bis ich das ende gefunden habe.. das wird alles sehr abenteuerlich^^

    Du hast nie mit reinen C-Strings programmiert, oder? Die Funktion gibt es natürlich in der Standard-Bibliothek 😃

    Schau Dir mal die** strstr() **Funktion an:

    const char * strstr ( const char * str1, const char * str2 );

    Locate substring
    Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
    The matching process does not include the terminating null-characters, but it stops there.

    Beachte, dass der Rückgabewert den Dir diese Funktion liefert ein Zeiger in den Eingabe-Puffer ist, es wir hier also nichts kopiert!

    Um Deinen Zeiger dann auf das erste Zeichen nach der gesuchten Zeichenkette zu verschieben, kannst Du einfach Zeiger-Arithmetik verwenden:

    static const char *const MARKER = "<DataStream>";
    
    void my_function(const char *const input)
    {
        const char *data = strstr(input, MARKER);
        if(data == NULL)
        {
            return; /*not found*/
        }
    
        data += strlen(MARKER); /*move pointer *behind* "<DataStream>" tag*/
        now_decode(data);
    }
    


  • Es wird immer kurioser.

    Eigentlich war der thread über CStringW zu std:string. Jetzt sind wir bei strstr gelandet.

    Für mich hört sich die ganze Geschichte inzwischen nach "hab nicht wirklich einen Plan" an. Sowohl von strings und deren Darstellungsformen über base64 (no rocket science) bis zu ich-weiß-nicht-was-noch-alles.



  • Ja ich habe bisher nur Java programmiert da habe ich solche Probleme nicht.

    Aber vielen Dank für eure Antworten. Durch den Hinweis der Standardbiobliothek habe ich mir das nötige Wissen angeignet und es gleich direkt auch const char* umgebaut. Einzige kopie die ich noch mache ist von const char* zu std:string weil ich keine Zeit mehr habe die Base64 funktion selber zu schreiben. Ich möchte hier lieber die Library verwenden um Fehler zu vermeiden.

    Vielen Dank an die anderen, Ihr habt mir sehr geholfen. Auch wenn es ein wenig weg vom Thema ging.

    Zu meinen CFile Problem:
    Hmm der Benutzer kann jeden beliebigen Ordner angeben. Ich prüfe jetzt nach dem Schreiben ob das File existiert. Wenn nicht gebe ich aus keine Schreibrechte. Das ist jetzt erst mal eine Notlösung.



  • lulu32_o schrieb:

    Zu meinen CFile Problem:
    Hmm der Benutzer kann jeden beliebigen Ordner angeben. Ich prüfe jetzt nach dem Schreiben ob das File existiert. Wenn nicht gebe ich aus keine Schreibrechte. Das ist jetzt erst mal eine Notlösung.

    Hat es einen speziellen Grund wieso Du mit der** CFile Klasse aus der MFC-Bibilothek und nicht einfach mit einem Standard C++ std::ofstream **arbeitest?

    Außerdem: Wie geanu öffnest Du denn die Datei? Wenn Du es wie folgt machst (Beispiel aus der MFC-Doku übernommen), sollte doch eine Exception fliegen, sofern etwas schief geht beim Öffnen...

    CFile f;
    CFileException e;
    TCHAR* pszFileName = _T("Open_File.dat");
    if(!f.Open(pszFileName, CFile::modeCreate | CFile::modeWrite, &e))
    {
       TRACE(_T("File could not be opened %d\n"), e.m_cause);
    }
    

    Oder als** std::ofstream **Variante:

    std::ofstream ofs;
    ofs.open ("test.txt", std::ofstream::out | std::ofstream::trunc);
    if(!ofs.good())
    {
        fprintf(stderr, "ERROR: Failed to open the file!\n");
        abort();
    }
    

    Und falls die Datei in einem "geschützten" Ordner angelegt wird, denk an die Hinweise zum VirtulaStore 😉



  • Wenn man ein CFile mit dem Konstruktor aufmacht fliegt eine Exception.
    Wenn man es über .Open aufmacht kommt bloss false zurück.
    Beim Versuch in das nicht-offene CFile zu schreiben sollte dann aber wieder ne Exception fliegen.



  • lulu32_o schrieb:

    Ja ich habe bisher nur Java programmiert da habe ich solche Probleme nicht.

    Du meinst weil Du bei Java keine Wahl hast und das Umkopieren nicht zu sehen ist ?


Anmelden zum Antworten