Strings



  • Hallo,

    wenn ich das richtig verstehe gibt es im reinen Ansi C strings nur im Sinne von Vektoren auf Char..
    ich habe weiterhin das Problem, dass ich mit dem compiler (mit dem ich arbeiten MUSS) diese vektoren nicht dynamisch aufbauen kann..

    (ist das eigentlich normal?)

    meine Überlegung dazu wäre vor der zuweisung nachzusehen, wie groß mein string ist (wie viele zeichen) und dann genauso viel im Speicher zu allocieren:

    typedef char* mystring;
    
    mystring create(size_t count){
    return malloc(count * sizeof(char));
    }
    

    was ist an dieser Lösung falsch?



  • hand-of-fate schrieb:

    wenn ich das richtig verstehe gibt es im reinen Ansi C strings nur im Sinne von Vektoren auf Char..

    ⚠ das wichtigste Detail hast du vergessen! Ohne dieses Detail kannst du so viele chars aneinanderhängen ohne einen String zu erhalten. Die 0-Terminierung. Ein String in C sind einfach beliebige Bytes hinter denen ein 0-Byte folgt! ⚠

    ich habe weiterhin das Problem, dass ich mit dem compiler (mit dem ich arbeiten MUSS) diese vektoren nicht dynamisch aufbauen kann..

    (ist das eigentlich normal?)

    Nein ist nicht normal. Da wirst du was falsch machen. (zB kein 0-Byte anhängen)

    meine Überlegung dazu wäre vor der zuweisung nachzusehen, wie groß mein string ist (wie viele zeichen) und dann genauso viel im Speicher zu allocieren:

    typedef char* mystring;
    
    mystring create(size_t count){
    return malloc(count * sizeof(char));
    }
    

    was ist an dieser Lösung falsch?

    was soll daran falsch sein? (btw. sizeof(char) kannst du dir sparen, das ist per Definition immer und überall 1)



  • ja das 0byte ist mir klar --habe ich jetzt nur nicht mehr explizit erwähnt

    rüdiger schrieb:

    Nein ist nicht normal. Da wirst du was falsch machen. (zB kein 0-Byte anhängen)

    Was meinst du damit dass ich da was falsch machen werde?

    rüdiger schrieb:

    was soll daran falsch sein?

    ich habe zum beispiel das problem:

    mystring t;
      int i;
      t= create(100);
      for (i=0;i<99;i++){
          strcat(t,"1");
          }
      printf(t);
    

    ich bekomme als erstes Zeichen immer etwas was nicht richtig dargestellt werden kann (zb ein umgedrehtes Fragezeichen gefolgt von einer raute und einem 🙂
    desweiteren kann ich manchmal auch mehr zeichen in des string packen als ich beim create angegeben habe..



  • rüdiger schrieb:

    ⚠ das wichtigste Detail hast du vergessen! Ohne dieses Detail kannst du so viele chars aneinanderhängen ohne einen String zu erhalten. Die 0-Terminierung. Ein String in C sind einfach beliebige Bytes hinter denen ein 0-Byte folgt! ⚠

    Klingt so, als sei auch ein String eine wirre Folge von Steuer- oder nicht darstellbaren Zeichen (Bytes) die Null terminiert ist. 😮 🙄 😕



  • hand-of-fate schrieb:

    mystring create(size_t count){
    return malloc( count + 1 );        // PLUS EINS !!!
    }
    

    Ein Byte mehr für das Zeichenketten-Ende-Zeichen '\0' reservieren und dafür sorgen, das es in der neuen Zeichenkette ans Ende kommt.

    strcpy z.B. macht das automatisch, in einer selbstgebauten Schleife musst du das selber reinpacken.



  • hand-of-fate schrieb:

    typedef char* mystring;
    
    mystring create(size_t count){
    return malloc(count * sizeof(char));
    }
    

    was ist an dieser Lösung falsch?

    typedef char* mystring;
    
    mystring create(size_t count)
    {
       mystring s = malloc (count+1);
       if (s)
         *s = 0;   // der string soll anfangs leer sein
       return s;
    }
    

    🙂



  • mystring create(size_t count)
    {
       mystring s = malloc (count+1);
       if (s)
         *s = 0;   // der string soll anfangs leer sein
       return s;
    }
    

    auch wenn ich mich als noob oute 😉
    was heißt if (s) oO
    und muss ich wirklich *s schreiben oder reicht nicht auch s=0 ?
    und wird s nicht als leer initialisiert???



  • strcat sucht zum Anhängen ein '\0' 🙂



  • if (s) testet, ob erfolgreich Speicher reserviert wurde, wenn nicht liefert malloc NULL und s ist NULL 🙂



  • Sonst würde *s = 0; einen Absturz verursachen.



  • *s = 0 sorgt für das '\0' welches von strcat gebraucht wird 🙂



  • wääää ihr überfordert mich ^^

    ich habe trotz allem immer noch das prob, dass das erste zeichen irgend was krummes ist..

    mystring t;
      int i;
      t= create(20);
      for (i=0;i<20;i++){
          strcat(t,"1");
          }
          strcat(t,"\0");
      printf("%s\n",t);
    

    wenn strcat nen \0 sucht, dann macht das dort ja überhaupt keinen sinn oda?



  • hand-of-fate schrieb:

    was heißt if (s) oO

    Wenn malloc erfolgreich war.

    hand-of-fate schrieb:

    und muss ich wirklich *s schreiben oder reicht nicht auch s=0 ?

    Ja wirklich. s = 0 würde die von malloc gelieferte Adresse wieder Null setzen.
    *s Zeigt auf das erste Zeichen im Puffer *(s + 1) auf das zweite usw.
    *s bedeutet das gleiche wie s[0], *(s + 1) bedeutet das gleiche wie s[1] usw.
    🙂

    hand-of-fate schrieb:

    und wird s nicht als leer initialisiert???

    Ne, das macht calloc.
    🙂 🙂 🙂
    🕶



  • hand-of-fate schrieb:

    wääää ihr überfordert mich ^^
    wenn strcat nen \0 sucht, dann macht das dort ja überhaupt keinen sinn oda?

    Doch macht Sinn, strcat entfernt es ja. Hängt den String oder das Zeichen dran
    und hängt auch ein neues '\0' ans Ende.
    🙂



  • bedeutet:
    *s=0;
    dass ich im ersten byte das Terminierungszeichen einfüge?
    also in dem fall 0 gleich \0 ?????



  • und nochmal zu
    if(s)..
    ist das gleichbedeutend mit:

    if (s!=NULL) ????



  • mystring t;
      int i;
      t= strcreate(4);
      for (i=0;i<5;i++){
          strcat(t,"1");
          }
      printf("%s\n",t);
    

    warum kracht das nicht?



  • hand-of-fate schrieb:

    mystring t;
      int i;
      t= strcreate(4);
      for (i=0;i<5;i++){
          strcat(t,"1");
          }
      printf("%s\n",t);
    

    warum kracht das nicht?

    warum sollte es?
    hinter der letzten, von dir reservierten speicherzelle, sind noch mehr, die sich nicht gegen schreibzugriffe wehren können.
    C hat keine eingebaute bereichsprüfung.
    vielleicht crasht es ja irgendwann später, oder nie 😉



  • hand-of-fate schrieb:

    bedeutet:
    *s=0;
    dass ich im ersten byte das Terminierungszeichen einfüge?
    also in dem fall 0 gleich \0 ?????

    Yes Sir. 🙂

    hand-of-fate schrieb:

    und nochmal zu
    if(s)..
    ist das gleichbedeutend mit:
    if (s!=NULL) ????

    Bingo, Sir. 🙂



  • hu hu schrieb:

    rüdiger schrieb:

    ⚠ das wichtigste Detail hast du vergessen! Ohne dieses Detail kannst du so viele chars aneinanderhängen ohne einen String zu erhalten. Die 0-Terminierung. Ein String in C sind einfach beliebige Bytes hinter denen ein 0-Byte folgt! ⚠

    Klingt so, als sei auch ein String eine wirre Folge von Steuer- oder nicht darstellbaren Zeichen (Bytes) die Null terminiert ist. 😮 🙄 😕

    Jop.

    @hand-of-fate
    das ist eben die problematische Sache. Nur weil du etwas falsch machst heißt das nicht, das es dir sofort um die Ohren fliegt (es gibt eben keine Bereichsüberprüfung). Es kann alles gut laufen, aber plötzlich änderst du woanders etwas und dir fliegt alles um die Ohren.

    Um solche Fehler zu finden ist übrigens DUMA oder Valgrind recht praktisch.



  • hand-of-fate schrieb:

    mystring t;
      int i;
      t= create(100);
      for (i=0;i<99;i++){
          strcat(t,"1");
          }
      printf(t);
    

    strcat erwartet ein 0-terminierendes String, t ist es aber nicht. Und die ganzen anderen Beispiele mit strcat, die hier im Thread sind, sind auch deswegen falsch

    mystring t;
      int i;
      t= create(100);
    
      /* SEHR WICHTIG */
    
      if(t == NULL) 
      {
          /* FEHLERBEHANDLUNG */
          return ...;
      }
    
      t[0] = 0;
    
      for (i=0;i<99;i++){
          strcat(t,"1");
          }
      printf(t);
    

Anmelden zum Antworten