Anfaengerfrage



  • Hi, zwei kleine Fragen:
    1. Warum wird shit2 beim compilen angezeigt?
    2. Warum kann ich shit2 nicht mit 3 Variablen füllen?

    Danke!

    #include <iostream>
    
    using namespace std;
    
    int main () {
    
    	char shit2[3] = "ba";
        char shit[3];
        shit[0] = 'a';
        shit[1] = 'b';
        shit[2] = 'c';
    
    	cout << "Shit ohne Aenderung: " << endl << shit << endl;
    
    	cout << "Shit mit Aenderung: :" << endl << shit << endl;
    }
    

  • Mod

    1. Warum wird shit2 beim compilen angezeigt?

    Du meinst wohl, Intellisense wittert einen Fehler. Nun, da hab ich keine Ahnung, obiger Code sieht völlig in Ordnung aus.

    2. Warum kann ich shit2 nicht mit 3 Variablen füllen?

    Kannst du, und tust du.

    Wenn du ein char-Array mit einem String-Literal initialisierst, dann füllst du die ersten Zeichen mit den Zeichen aus dem Literal, aber das letzte Zeichen ist immer das Nullzeichen. Daher brauchst du in einem char-Array mindestens immer Platz für das Nullzeichen.

    Das heißt, das letzte Element deines Arrays ist nach einer solchen Initialisierung immer 0 und kann nicht für andere Zeichen verwendet werden, denn sonst ist das Array nicht nullterminiert (und das ist eine Grundvoraussetzung für viele Funktionen die einen C-String nehmen!).

    /// sizeof angewandt auf ein String-Literal gibt die Anzahl der Zeichen wieder:
    std::cout << sizeof("HA!"); // Nanu, das gibt ja Vier aus?!
    

    Merke: Ein String-Literal "a1a2..an" führt zu einem Array mit Inhalt {'a1', 'a2', ...., 'an', '\0'}.



  • Vielen Dank fuer deine Antwort!

    Nagut dann hat mein handycompiler wohl das erste mal hardcore abgefloppt, schade : (

    Wenn ich shit2 mit 3 werten fuellen will, sagt die fehlermeld, das der string zu lang ist, und wenn ich dann 2 werte eingebe und starte kommt nach der ausgabe von shit, noch in der selben zeile irgendein merkwuerdiges zeichen und dann shit2, obwohl ich shit2 zur ausgabe ja nicht eingetragen habe.

    Danke nochmal!



  • kopier mal die Fehlermeld hier rein.



  • /data/data/com.n0n3m4.droidc/files/temp.c: In function 'int main()':
    /data/data/com.n0n3m4.droidc/files/temp.c:7:18: error: initializer-string for array of chars is too long [-fpermissive]
    char bitch[3] = "xbc";
    ^
    compilation terminated due to -Wfatal-errors.

    Hab die variable in der zwischenzeit aus testzwecken unbenannt.



  • Du darfst die Antwort von Arcoth schon ruhig lesen. Da steht fast alles drin, was du wissen willst.

    Ums vielleicht klarer zu machen:

    char bitch[3] = "xbc";
    

    ist im Grunde (keine Korinthenkackerei von den üblichen Verdächtigen bitte) das selbe wie

    char bitch[3];
    bitch[0] = 'x';
    bitch[1] = 'b';
    bitch[2] = 'c';
    bitch[3] = '\0';
    

    Das sind nunmal vier Zeichen, und wie Arcoth gesagt hat brauchen viele Funktionen das eben, um richtig zu funktionieren. Deshalb kommt auch bei deiner Ausgabe von "shit" danach blödsinn raus, weil du das \0 eben nicht drinnen hast.



  • Also manchmal funktionieren 3 zeichen und manchmal nicht?

    Ich mein ich kenne die null termination, aber wie du geschrieben hast, stehen in dem array 4 plaetze zur verfuegung. Also müssten ja 3 buchstaben und eine null terminierung reinpassen. Ich habs grad mit int versucht und es klappt..



  • kamelkacke schrieb:

    Also manchmal funktionieren 3 zeichen und manchmal nicht?

    Ich mein ich kenne die null termination, aber wie du geschrieben hast, stehen in dem array 4 plaetze zur verfuegung. Also müssten ja 3 buchstaben und eine null terminierung reinpassen. Ich habs grad mit int versucht und es klappt..

    😕 Das einzige was ein Terminierungszeichen hat, ist ein "xyz" , also ein Zeichenkettenliteral. Keine Zeichen in Anführungszeichen = Keine Nullterminierung. Die Nullterminierung ist auch nur dafür da, dass die Funktionen, die mit deinem String arbeiten, wissen, wann der String zu Ende ist.



  • std::string



  • Also bei einer string definition eines arrays gehen jeweils 2 plaetze fuer die "" floeten und bei einzelner definition geht ein platz weg wegen der nullterminierung?



  • kamelkacke schrieb:

    .., aber wie du geschrieben hast, stehen in dem array 4 plaetze zur verfuegung. ...

    Nein, da sind nur 3 Plätze.
    char bitch[3]; bedeutet: Ein char-Array mit drei Elementen, dessen Index von 0 bis 2 geht. Da gibt es kein bitch[3] zum Zeichen ablegen.

    Die "" von einem Stringliteral werden nicht im Array abgelegt. Das einzige was dazu kommt ist der '\0'-Terminator.

    Und du darfst C-Strings nicht mit einem Zeichen verwechseln.
    "9" ist etwas anderes als '9' ist etwas anderes als 9



  • "xyz" ist vom Typ const char [4]. Der Inhalt ist {'x', 'y', 'z', '\0'}. Wenn du schreibst const char bla[3] = "xyz";, dann ist bla vom Typ const char [3] mit dem Inhalt {'x', 'y', 'z'}.

    cout ist ein Objekt was ungefähr so funktioniert:

    ostream &operator << (const char *s){
        while (*s != '\0'){
            gebeAus(*s);
            s++;
        }
        return *this;
    }
    

    Er gibt so lange die Zeichen aus bis er ein '\0'-Zeichen trifft. Da dein Array nicht mit einem '\0'-Zeichen endet gibt cout munter weiter irgendwelchen Speicher aus bis er zufällig eine '\0' findet oder das Betriebssystem dein Programm wegen einer Zugriffsverletzung abschießt.
    Lösung: Das '\0'-Zeichen dran tun oder std::string benutzen oder cout sonst irgendwie sagen, dass er nur die ersten 3 Zeichen ausgeben soll oder sich freuen, dass komische Sachen ausgegeben werden.


  • Mod

    nwp3 schrieb:

    Wenn du schreibst const char bla[3] = "xyz";, dann ist bla vom Typ const char [3] mit dem Inhalt {'x', 'y', 'z'}.

    Das sollte ill-formed sein. Ein Zeichenkettenliteral endet immer mit einem 0-Terminator, und damit liegen zuviele Initialisierer vor.



  • Boah...also der compiler macht alles richtig, indem er in bitch keine 3 buchstaben aufnehmen will??



  • vier



  • Er nimmt aber nicht mal drei, darum gehts doch.



  • Doch, da passen drei Zeichen rein. Wenn das letzte Zeichen kein '\0' ist, kannst du es aber nicht mit cout überprüfen, da das bei einem char* einen C-String erwartet.



  • Er nimmt noch nichtmal einen, er nimmt garkeinen, weil er die vier nicht nimmt, weil vier nicht in drei passen.



  • Ne guck doch mal auf die compilerwarnung in seite 1. Da steht doch dass 3 fuer ihn zu lang ist



  • Nee, steht da nicht!


Anmelden zum Antworten