das kopieren von VOR-terminierten strings



  • Problem :
    Kopiere den folgenden string in einen Puffer "char *s"
    #define MYSTR "Hallo\0wie\0geht\0es?\0"
    #define MYSTRLEN 19

    char *s;
    
        s = new char[MYSTRLEN];
        strncpy(s,MYSTR,MYSTRLEN);
    
        cout << s;
    
        memcpy(s,MYSTR,MYSTRLEN);
    
        cout << s;
    
        cin >> s;
    

    beide ausgaben ergeben "Hallo".

    während das erste mal MYSTR mit strncpy kopiert wurde, wurden trotzdem nur 6 Zeichen ("hallo\0") kopiert.
    das sieht man, wenn man ein Breakpoint auf das
    erste "cout << s;" setzt und das 7 zeichen (s[6]) in der Überwachung ansieht. es ist ein undefiniertes zeichen.

    das zweite mal wurde MYSTR mit memcpy kopiert.
    das 7. zeichen s[6] beinhaltet nun auf wirklich das 7. zeichen (hier das w von wie).

    allerdings gibt cout und auch die Überwachung nur "Hallo" aus, weil immernoch ein Nullzeichen existiert.

    (das cin >> s dient nur zum offenhalten der Konsolenanwendung)

    Frage:
    wie kann man das noch anders lösen?



  • cout gibt bis zur ersten 0 aus.

    Du müsstest jedes Zeichen einzeln ausgeben und jedes vorher auf 0 prüfen.

    Oder direkt fwrite(s, 1, länge, stdout); Wobei hier die Null mit ausgegeben wird, was nicht so toll ist.



  • vielen dank für deine antwort
    vielleicht habe ich micht etwas verwirrend ausgedrückt.

    was ich meinte mit problem, war
    das kopieren eines nullterminierenden strings von a nach b.
    wobei nach strcpy s und MYSTR unterschieldich sind,
    und wie man das sonst noch auser mit memcpy lösen kann.



  • Hi

    Warum willst du es nict mit memcpy machen ?
    Naja du hast noch zwei weitere Möglichkeiten.

    1. Ne einfache Zuweisung an nen Zeiger
    2. Die Zeichen einzeln kopieren.

    bsp 1)

    #include <cstdio>
    #define MYSTR "das\0ist\0ein\0test"
    #define MYSTRLEN 16
    
    int main(void)
    {
      char *s=MYSTR; //fertig
      fwrite(s,1,MYSTRLEN,stdout);
      return 0;
    }
    

    bsp 2)

    #include<cstdio>
    #define MYSTR "das\0ist\0ein\0test"
    #define MYSTRLEN 16
    
    int main(void)
    {
       char *dest=new char[MYSTRLEN]; //kannst hier auch ein fixes array nehmen
       for(int i=0;i<MYSTRLEN;i++)
           dest[i]=MYSTR[i];
        fwrite(dest,1,MYSTRLEN,stdout);
        return 0;
    }
    

    [ Dieser Beitrag wurde am 27.06.2003 um 23:44 Uhr von prolog editiert. ]



  • Hi

    Wobei mich mal interressieren würde, warum das zweite funktioniert.
    Und das tut es, ich habs getestet.

    Nach preprocessing steht doch im prinzip in der Zeile:
    dest[i]="das\0ist\0ein\0test"[i];

    Ursprünglich hatte ich den string an nen Zeiger zugewiesen und dann mit dem Zeiger die Zuweisung geacht.



  • Ein String mit Anführungszeichen ist in C++ per definitionem ein (const char*).

    Also ist es ziemlich egal, ob links von den eckigen Klammern [i] ein String mit Anführungszeichen oder ein Zeiger steht. Es ist vom Typ her genau das gleiche.
    Warum sollte der Compiler da meckern?

    p.s.:
    Es gilt: a[i] == *(a+i) == i[a]
    Also könnte man genausogut schreiben: i[Dest] = i["Das\0Ist\0Ein\0String\0"];
    Nur am Rande... 🙂



  • Das is nicht ganz richtig, weil i ja als int und damit als 4 Byte gewertet wird. Der aufruf [i]i["nur\0ein\0test\0"][i] würde daher höchstwahrscheinlich eine Speicherzugriffsverletzung mit sich führen.



  • [i]i["nur\0ein\0test\0"][i]
    

    Was soll _das_ darstellen?

    Das lässt sich bei mir nicht kompilieren. 😉



  • lol... sorry das kursiv wurde wohl nicht umgesetzt ^^

    i["nur\0ein\0test\0"] funzt nicht...

    [ Dieser Beitrag wurde am 30.06.2003 um 20:23 Uhr von Cyphexx editiert. ]



  • Warum denn nicht?

    i["a"] ist äquivalent zu *(i + "a"). i ist kein pointer, aber "a" ist einer. Auf einen Integer darf wohl kein pointer addiert werden (wäre sinnlos), aber (nach dem Kommutativgesetz) auf einen Pointer ein Integer. Also wäre wieder alles beim alten.
    Hast du es ausprobiert?



  • Nö ich habs nicht ausprobiert 🙄. Aber natürlich kann es sein dass Du recht hast ^_~



  • Ich hab Recht. 🙂

    cout << ("abc"[0]) << (1["abc"]) << *(2+"abc");
    

    gibt abc aus, wie erwartet.


Anmelden zum Antworten