CString verliert Daten in einer Schleife



  • Bestmmt sehe ich den Wald vor lauter Bäumen nicht, aber ich probiere jetzt schon 2 Tage an diesem Problem.

    CString	Daten2[160];
    status = fopen("status.txt","r");
    for (int i=0;i<160;i++)
    {
    	fscanf(status,"%s", Daten2[i]);
    }
    fclose(status);
    
    fprintf(Protokoll, "***%s\n",Daten2[0]);
    fprintf(Protokoll, "***%s\n",Daten2[1]);
    fprintf(Protokoll, "***%s\n",Daten2[2]);
    

    gibt mir in der Protokoll-Datei immer nur eine 0 pro Eintrag aus.

    Wenn ich aber

    CString	Daten2[160];
    status = fopen("status.txt","r");
    fscanf(status,"%s", Daten2[0]);
    fscanf(status,"%s", Daten2[1]);
    fscanf(status,"%s", Daten2[2]);
    .....
    fscanf(status,"%s", Daten2[159]);
    fclose(status);
    
    fprintf(Protokoll, "***%s\n",Daten2[0]);
    fprintf(Protokoll, "***%s\n",Daten2[1]);
    fprintf(Protokoll, "***%s\n",Daten2[2]);
    

    mache, sind die Daten aus der Datei vorhanden.

    Warum ?



  • Du musst auf jeden Fall ein *cast* vor das "Daten[..]" machen!!!
    Das xprintf will ein "void*"! Deshalb wird einfach nur der Objekt-Pointer übergeben und *nicht+ der String!!!
    Also:

    fprintf(Protokoll, "***%s\n", (LPCTSTR) Daten2[0]);
    


  • Also wenn ich

    CString    Daten2[160];
    status = fopen("status.txt","r");
    for (int i=0;i<160;i++)
    {
        fscanf(status,"%s", Daten2[i]);
    }
    fclose(status);
    
    fprintf(Protokoll, "***%s\n",(LPCTSTR) Daten2[0]);
    fprintf(Protokoll, "***%s\n",(LPCTSTR) Daten2[1]);
    fprintf(Protokoll, "***%s\n",(LPCTSTR) Daten2[2]);
    

    mache, müsste es funktionieren ?
    Bei mir nicht, immer noch das selbe Ergebnis.

    In der Datei status.txt steht z.b.

    blablabla: 0
    blublublu: 0
    usw.

    Wenn ich das ganze ohne Schleife mache steht in
    Daten[0] = blablabla
    Daten[1] = 0
    Daten[2] = blublublu
    usw.

    aber wenn ich das ganze in der Schleife mache steht überall 0 drin.
    Habe herausgefunden das Daten[0] bis Daten[159] den letzten Wert in status.txt bekommen. wiso denn das ?



  • Du kannst keine Referenz in einen Pointer casten da fehlt noch ein & vor Daten2[..].
    Edit1: Hab gerade mal nachgeschaut, CString definiert tatsächlich einen Operator LPCTSTR, also sollte es doch funktionieren...

    Edit2: Du musst das LPCTSTR auch in die fscanf Zeile einfügen!!!



  • Nein, in der "fscan" Zeile kann das ja nicht gehen, da hier ja was *geschrieben* wird und nicht gelesen!!! Hier bitte "GetBuffer" verwenden!!!



  • Macht denn der operator LPCTSTR nicht genau das selbe? Und sollte man nicht besser GetBufferSetLength() verwenden?



  • Der zurückgegebene Zeiger ist *const* somit darf dieser nicht verändert werden!!! Ganz unabhängig davon wie CString implementiert ist!!! Und die Implementierung kann sich auch ändern!


  • Mod

    GetBufferSetLength wäre in diesem Fall überflüssig. In jedem Fall müsstest Du aber ReleaseBuffer später aufrufen.



  • Martin Richter schrieb:

    In jedem Fall müsstest Du aber ReleaseBuffer später aufrufen.

    bei nur-lesezugriffen braucht man's aber nicht...
    🙂



  • Ist der fcanf()-Aufruf ein Nur-Lese-Zugriff?



  • CStoll schrieb:

    Ist der fcanf()-Aufruf ein Nur-Lese-Zugriff?

    ach es geht um 'fscanf'? naja, das sieht sowieso verdächtig aus.
    wieviel speicherplatz hat denn ein frischer CString, wenn man da einfach was 'reinscanfen' will?



  • Würde mich auch interessieren, deshalb auch der Vorschlag mit GetBufferSetLength().


  • Mod

    Ein frischer String hat 0 Zeicen platz. Und der interne Zeiger verweist auf einen const Speicherbereich.

    Ohne GetBuffer/GetBufferSetLength wird kein Speicher allokiert!



  • Martin Richter schrieb:

    Ohne GetBuffer/GetBufferSetLength wird kein Speicher allokiert!

    man muss also GetBuffer einen wert mitgeben, damit der CString speicher bekommt. wo ist dann der unterschied zu GetBufferSetLength()?



  • Heißt, daß GetBuffer auf einen Speicherbereich mit der Länge 0 verweisst wenn vorher nichts im String stand?


  • Mod

    Nein!
    GetBuffer(0) liefert Speicher mit einem Byte auf das man schreiben kann!
    Dieses eine Byte ist das terminierende 0 Zeichen!



  • Martin Richter schrieb:

    Nein!
    GetBuffer(0) liefert Speicher mit einem Byte auf das man schreiben kann!
    Dieses eine Byte ist das terminierende 0 Zeichen!

    ich habe zwar herzlich wenig ahnung von C++, aber ich werde das gefühl nicht los, dass 'CString' im hinblick auf gutes C++ design ziemlicher mist ist...
    🙂


  • Mod

    pale dog schrieb:

    ich habe zwar herzlich wenig ahnung von C++, aber ich werde das gefühl nicht los, dass 'CString' im hinblick auf gutes C++ design ziemlicher mist ist...
    🙂

    Begründung?
    CString verhält sich wie dokumentiert und wrapped null terminiert Strings perfekt. Und sogar mit Doppelnull-Strings kann das Ding umgehen.



  • Martin Richter schrieb:

    pale dog schrieb:

    ich habe zwar herzlich wenig ahnung von C++, aber ich werde das gefühl nicht los, dass 'CString' im hinblick auf gutes C++ design ziemlicher mist ist...
    🙂

    Begründung?

    na, du siehst doch selbst an den letzten beiträgen. ich finde es nicht gut, wenn man in den daten eines objekts direkt herumwurschteln kann. meiner meinung nach dürfte ein 'GetBuffer()' bestenfalls einen 'const char*' zurückgeben. wer strings über char* verändern will, kann ja arrays benutzen...



  • Eigentlich ist die ganze Diskussion nur für die Theorie.
    Warum sollte man MFC verwenden wenn man dann erst funktionen wie fopen, fscanf, etc. verwendet.
    Da hat die MFC auch ganz gute Klassen um in Dateien zu schreiben und das ohne herum zu casten oder Zeiger zu übergeben.


  • Mod

    pale dog schrieb:

    na, du siehst doch selbst an den letzten beiträgen. ich finde es nicht gut, wenn man in den daten eines objekts direkt herumwurschteln kann. meiner meinung nach dürfte ein 'GetBuffer()' bestenfalls einen 'const char*' zurückgeben. wer strings über char* verändern will, kann ja arrays benutzen...

    Wieso? Gerade das ist eine der Stärken von CString. Man kann Speicher allokieren und ihn durch eine API Funktion füllen lassen. Das hierbei Vorsicht geboten ist versteht sich. std::string hat hier einfach den Nachteil das immer kopiert werden muss und Stack-/Heapspeicher zwischenverwendet werden muss.


Anmelden zum Antworten