-
        

Ergebnis 1 bis 9 von 9

Thema: String initialisieren ohne 0 ?

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526

    String initialisieren ohne 0 ?

    Anzeige

    Da bin ich schon wieder,
    eine, nein eigentlich 2 Fragen zu Strings:

    char s1[ ] = "Hallo";
    char s2[5] = "Hallo";


    Wenn ich schreibe: char s1[] = "Hallo";
    werden 5+1 Byte belegt wegen dem Nullterminator.
    Was ich durch den Versuch mit sizeof(s1) bestätigt bekommen habe.
    Alles klar,

    was passiert aber mit folgender initialisierung ?
    char s2[5] = "Hallo";
    Die Buchstaben passen ja noch rein, läst der Compiler den Nullterminator einfach weg, oder könnte es passieren, daß er das nächst liegende Byte hinter dem Array mit einer 0 beschreibt. Eine Warnung tritt zumindest nicht auf beim IAR Compiler. sizeof(s2)liefert auch logischerweise 5 zurück.

    Dann käme als nächstes die Frage, was passiert beim Sring Compare der beident. Hier findert die function strcmp doch keine 0 am Ende von s2.
    zumindest, vermutlich, nicht unmittelbar hinter dem Array s2, sondern zufällig irgendwann....

    Ist diese Initialisierung von s2 also rechtens oder eher nicht ?

    Siro

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    34
    Beiträge
    1.780
    Die zweite Variante ist gefährlich...

    Ich bin nicht sicher ob für diesen speziellen Fall etwas im C-Standard spezifiziert ist, würde aber erstmal vom worst-case Fall ausgehen, nämlich daß der Compiler durchaus eine \0 hinter s2 schreiben könnte.

    Aber selbst wenn er das nicht tut wird, wie du das bereits richtig erkannt hast, weder strcmp noch irgendeine andere Funktion korrekt arbeiten, die auf die \0 angewiesen ist (und das sind nahezu alle String-verarbeitenden Funktionen aus der Standardbibliothek).

    Was du machen könntest, falls du das eine Byte wirklich zwingend einsparen musst und keine der Standardfunktionen nutzen möchtest, wäre folgende Initialisierung:

    Code:
    char s3[5] = {'H','a','l','l','o'};
    So viele Treppen und so wenig Zeit!

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526
    Hallo Felix G,

    Das "eine" Byte mehr im Array wäre mir im Prinzip egal, ich habe nur eine festgelegte Struktur, in der es ein ein 8 Byte großes Character Array gibt, weches ich initialisieren möchte, aber es später auch vergleichen möchte.

    Also die Initialisierung könnte ich nach deiner Vorlage tätigen, dann bleibt jedoch noch das Problem der strcmp funktion offen.

    Sinn und Zweck meines Vorhabens:
    Ich habe in den letzten 8 Speicherstellen meines EEPROMs 8 Character, welche einen bestimmten String beinhalten müssen. Dies werden bei Programmstart einmal mit einem vorgegebenen String verglichen.

    Dann werde ich mal aus Sicherheitsgründen nur einen 7 Zeichen langen String dort platzieren und eine Null anhängen, damit keine unerwarteten Ergebnisse auftauchen. Oder ich müste anstelle der strcmp funktion alle 8 Character separat vergleichen, ginge natürlich auch.

    Mit der Array-Initialisierung nach deinem Prinzip kannte ich noch nicht
    (bin ich nicht drauf gekommen) und danke Dir für die Info.
    Siro

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.383
    wenn du s2 so wie oben initialisierst, würden die 5 bytes mit "hallo" beschrieben werden UND das nachfolgende byte mit einer 0, egal ob da ne variable kommt oder nicht ... es wäre in jedem falle ein "illegaler" zugriff den du vermeiden solltest ... wenn du irgendeine methode aufrufst die mit strings arbeitet, erwartet sie in er regel IMMER einen pointer und eine längenangabe, weil ein pointer nie weis wie groß der string ist auf den er zeigt

    wenn du jetzt NACH s2 zum beispiel eine byte variable hast und diese VOR dem strcmp veränderst, erkennt er das ende des strings nicht mehr automatisch und es kann mörderisch krachen ^^
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  5. #5
    Erfahrener Benutzer Roboter Experte Avatar von BurningWave
    Registriert seit
    22.12.2007
    Ort
    nahe Stuttgart
    Alter
    23
    Beiträge
    656
    char s3[5] = {'H','a','l','l','o'}; ist doch bis auf die Schreibweise genau das gleiche, wie

    char s2[5] = "Hallo";

    und beides ist nicht empfehlenswert. Alle stringverarbeitenden Funktionen erwarten eine Nullterminierung. Falls du so eine Funktion benutzt, kann das in unerwartetem/unvorhersehbarem Verhaten enden, was auf einem µC besonders schlimm ist, da er entweder einen Reset macht oder du ihn evtl. zerschießen könntest.

    EDIT: Erster Post im neuen Forum
    meine Homepage: http://www.jbtechnologies.de
    Hauptprojekte: Breakanoid 2 - Sound Maker

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    34
    Beiträge
    1.780
    Zitat Zitat von _R2D2 Beitrag anzeigen
    char s3[5] = {'H','a','l','l','o'}; ist doch bis auf die Schreibweise genau das gleiche, wie

    char s2[5] = "Hallo";
    Nein.
    Bei meiner Variante wird keine \0 angehängt, bei der anderen schon.

    {'H','a','l','l','o'} sind für den Compiler einfach nur 5 einzelne Zeichen, "Hallo" hingegen ist ein nullterminierter String.
    So viele Treppen und so wenig Zeit!

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.383
    Zitat Zitat von Felix G Beitrag anzeigen
    Nein.
    Bei meiner Variante wird keine \0 angehängt, bei der anderen schon.

    {'H','a','l','l','o'} sind für den Compiler einfach nur 5 einzelne Zeichen, "Hallo" hingegen ist ein nullterminierter String.
    exakt, denn char s[n] ist nur ein array und kein string im eigentlichen sinn, bei der variante mit den anführungszeichen jedoch interpretiert er nur den anfang des arrays und wird VERMUTLICH das nachfolgende byte mit einer 0 versehen ... die problematik die ich angesprochen habe bezog sich auch eher auf die spätere verwendung, wobei die terminierende 0 zufällig erhalten werden KÖNNTE aber auch durch eine andere variable verändert werden KÖNNTE ... und das wie oben schon gesagt zum controller absturz füren kann
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    18.03.2011
    Beiträge
    8
    naja.... ob er jetzt Strings nutzt oder nicht, ist ihm überlassen - wenn er weiß, dass es x Zeichen sind, kommt er auch ohne \0 aus...
    statt vergleiche solange bis \0 in einem String erreicht kann man auch irgendwie sowas machen...

    //a sei die Eingabe, b sei das fest gespeicherte, x sei die bekannte Länge von b
    for (i = 0; i < x; i++) {if (a[i] != b[i]) || (a[i] == '\0') return false;}
    if (a[x] != '\0') return false;
    return true;

    AAAAABäääääär für die Eingabe der Daten:
    pass bei C-Code auf, man weiß nie, ob alle Compiler (Windows/Linux/..., offiziell/alternative/...) die Spezifikationen perfekt einhalten...
    nicht dass ein Compiler meckert, weil es für ihn 6 Zeichen sind, einer das einfach richtig abarbeitet (\0 wegschmeißen) und ein anderer es verbockt es (hängt \0 an und verschiebt alles)
    (letztens erst nen Compiler geschrieben, man glaubt nicht was eine Umstellung an der Spezifikation bewirken kann)

    also lieber statt "Hallo", was zurechtgeschnitten werden müsste,
    ein sauberes {'H',...,'o'}, das Char[] einfach als Byte[] interpretiert...

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    29
    Beiträge
    1.221
    Naja, dann kann man das Programmieren auch gleich sein lassen, wenn man sich nicht auf die Sprachspezifikation stützen (kann). Der Standard sagt klar aus, dass nur der Speicher des Arrays beschrieben wird, alles andere ist ein Fehler im Compiler.

    mfG
    Markus

    PS: http://www.dclc-faq.de/kap5.htm#5.20

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •