einen char an einen char* hängen



  • Wie gesagt, der Zielstring braucht genug Speicher um das Ergebnis zu halten.
    z.B:

    char str[64]; // reservier 64 Chars auf dem Stack
    strcpy(str, "test"); // kopiert "test" nach str, das 5. Zeichen ist 0 und markiert
    damit das Stringende
    
    char tmp[2] = {'x', 0};
    strcat(str, tmp); // 64 Bytes langen dicke um auch noch das 'x' unterzubringen..
    

    (Solche Sachen sind aber genau die Dinge, die Bufferoverflows oder Exploits ermoeglichen... in C++ gibt es Strings die den Delphistrings etwas aehnlicher sind)



  • was haltet ihr eigentlich davon:

    char* charcat(char* str, char c)
    {
      size_t pos=strlen(str);
      str[pos]=c;
      str[pos+1]=0;
      return str;
    }
    


  • THX an alle!!!!!
    😃



  • @Shade Of Mine
    das sieht zwar gut aus 😉 geht aber net.
    er sagt dann:

    Program received signal SIGBUS, Bus error.
    0x080488fd in charcat(char*, char) (str=0x804930b " ", c=60 '<') at rsssucker.C:46
    


  • newuserxx424 schrieb:

    @Shade Of Mine
    das sieht zwar gut aus 😉 geht aber net.

    geht sehr wohl, allerdings muss der char* ein string sein (0 terminiert) und genug speicher haben



  • #include <iostream>
    
    int main(void)
    {
    char* test;
    char test2='X';
    test="xxx\0";          //habe auch ohne \0 probiert.
    size_t pos=strlen(test);
      test[pos]=test2;
      test[pos+1]=0;
    std::cout<<test;
    return 0;
    }
    

    dieses prog gibt bei mir nen core dump!
    warum? was mach ich falsch? (frage ist ernstgemeint! und wenn ihr tutorials über string und c kennt her damit!)

    thx



  • mit char *test legst du nur einen Pointer auf einen String ohne jeglichen Platz für den Inhalt an.

    mit char *test="bla"; legst du einen Pionter auf eine String mit exact vier Zeichen an. nähmloch b,l,a,\0;

    somit ist deine Zuweisung test="xxx\0" unzulässig und verursacht den core dump, außerdem kennt c diese Art der Initialisierung nur bei der Deklaration eines Strings, an allen anderen Stellen mußt dur dies mit Funktionen wis sprintf, strcst, strcpy,... zuweisen

    Damit es funktioniert mußt du entweder

    char test[Irgend_Eine_Sinnvolle_Länge]={"xxx"}; 
    // mindestlänge ist die Länge deines Textes + das anzuhängende Zeichen + die schließende \0
    

    oder

    char *test;
    if (NULL == (test=calloc(Irgend_Eine_Sinnvolle_Länge,siozeof(char)))) //sinnvolle Länge siehe oben
         printf("ERROR konnte keinen Speicher allokieren");
    

    benutzen. Damit funktioniert dann jeder Vorschlag aus diesem Thread :p



  • ein fettes THX



  • PAD schrieb:

    mit char *test="bla"; legst du einen Pionter auf eine String mit exact vier Zeichen an. nähmloch b,l,a,\0;

    somit ist deine Zuweisung test="xxx\0" unzulässig und verursacht den core dump, außerdem kennt c diese Art der Initialisierung nur bei der Deklaration eines Strings, an allen anderen Stellen mußt dur dies mit Funktionen wis sprintf, strcst, strcpy,... zuweisen

    Leider falsch. Die Zuweisung test = "xxx\0" ist nicht unzulässig. Sie hat den gleichen Effekt wie die entsprechende Initialisierung mit demselben Wert. Das Stringliteral "xxx\0" (warum eigentlich das NUL-Zeichen an der Stelle? Doppelt terminiert hält besser? Na von mir aus 🤡 ) steht statisch im Speicher, und da darf natürlich jeder char-Zeiger drauf zeigen, der grad Lust hat. Verändern des Stringliterals ist dagegen nicht erlaubt.

    Du denkst vielleicht, da würde irgendwie intern strcpy oder so aufgerufen werden. Nope. Es wird nur die Adresse zugewiesen.

    Der Core Dump passiert an der Stelle:

    test[pos]=test2;
    

    Weil dort versucht wird, das Stringliteral, auf das test zeigt, zu verändern.



  • @Bashar Danke für die Korrektur

    Hatte meist Fehlerfälle dieser Art.

    {
      char test[20]="Peter";
    ....
    ....
      test="Mist";
    }
    
    d:\work\sourcemain.cpp(1124) : error C2440: '=' : 'char [5]' kann nicht in 'char [20]' konvertiert werden
            Es gibt keinen Kontext, in dem diese Konvertierung moeglich ist
    

    Und das ist etwas anderes als dieses Konstrukt (welches ich bisher noch nicht benötigt habe)

    {
      char *test="Peter";
    ....
    ....
      test="Mist";
    }
    

Anmelden zum Antworten