Wissenswertes über den Umgang mit Dateien und das Allokieren mit new bzw. löschen mit delete



  • Ich grüße,

    Dieser Beitrag ist an alle gerichtet die Fragen zum Umgang mit Dateien haben.
    In erster Linie geht es um CFile, CStdioFile, CString, CStringArray sowie das
    Speicher allokieren mit new, um bei größeren Dateien keine Speicherprobleme
    zu bekommen.

    Ich werde die einzelnen Klassen nacheinander besprechen und die Codeabschnitte
    ergänzen. Jedesmal wenn ich etwas ergänze, schreibe ich das zuvorgeschrieben in
    Kommentare um das ganze farbliche anzuheben.

    1. Die Wahl zwischen CFile und CStdioFile

    Auf dem ersten Blick scheint kein großer Unterschied der zwischen beiden
    Klassen zu bestehen, doch CStdioFile ist eine von CFile abgeleitete Klasse,
    die für Textdateien spezialisiert wurde. Möchte man eine Datei im Binärmodus
    öffnen benutz man besser CFile, im gegensatz dazu; Möchte man eine Textdatei
    öffnen sollte man sich lieber für CStdioFile entscheiden, da es z.B. eine
    Methode zum Lesen und schreiben einer ganzen Zeile gibt.

    Hat man sich für eine der beiden Klassen entschieden kann es weiter gehen.

    2. Richtiges Öffnen von Dateien

    Ich habe schon in vielen Beiträgen gesehen, dass es bereits am bloßen Öffnen
    der Dateien lag, dass das Programm nicht funktionierte. Ich beschreibe nun 2
    Möglichkeiten wie man eine Datei öffnen kann. Das ganze für die Klassen CFile und CStdioFile:

    - Das Öffnen direkt beim deklarieren der Variable

    CFile

    CFile Datei( "NameDerDatei", CFile::Flags, CFileException );
    

    Als ersten Parameter übergibt man den vollständigen Pfad der Datei

    Z.B : "C:\\Daten\\Ich\\Datei.txt"
    oder: "E:\\Urlaub\\Datei.dat"

    Man kann jeden Typ von Datei öffnen, egal ob *.dat, *.txt, *.jpg usw...
    Ob man diese nacher bearbeiten kann ist eine andere Frage, im Binärmodus
    sicherlich, deshalb empfehle ich für Nicht-Textdateien immer CFile,
    für Textdateien eher CStdioFile.

    ***ACHTUNG***

    Bei Pfadangaben nicht vergessen: Ein \ ist in Cpp ein \\ !!!

    Als zweiten Parameter übergibt man die Rechte bzw. Eigenschaften die man
    benutzen möchte:

    CFile::modeRead        //Nur lesen
    CFile::modeWrite       //nur schreiben
    CFile::modeReadWrite   //Lesen und Schreiben
    CFile::modeCreate      //Datei wird neu erstellt
    CFile::modeNoTruncate  //Wenn die Datei existieren sollte und man modeCreate
                           //benutzt hat, wird diese Datei NICHT überschrieben
                           //sondern die Daten werden angehangen.
    CFile::typeBinary      //Dieses Flag ist ein Standardflag von CFile
    CFile::typeText        //Dieses Flag kann nicht für CFile verwendet werden,
                           //da das Programm sonst abstürtzen würde.
    
    //Also nochmal eine Komplette Zeile:
    
    CFile Datei( "E:\\Urlaub\\Datei.dat", CFile::modeReadWrite | CFile::typeBinary );
    

    CFileException muss nicht umbedingt gesetzt werden. Habe mich damit schon
    auseinander gesetzt, bin aber leider noch zu keinem brauchbaren Ergebnis
    gekommen. Ich werde dies bei Gelegenheit ergänzen.

    CStdioFile:

    Für CStdioFile gelten alle beschriebenen Eigenschaften die oben stehen.
    Außer das ich diese Klasse für Textdateien empfehle und die Eigenschaft
    CFile::typeText zu verfügung steht.

    Hier ein komplettes Beispiel:

    CStdioFile StdioFile( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );
    
    //Die Eigenschaften werden auch mit CFile:: eingleitet da CStdioFile von CFile 
    abgeleitet ist.
    

    - Das öffnen mit der Methode CFile::Open() bzw. CStdioFile::Open()

    Dieses Öffnen funktioniert wie das Andere, wird aber erst nach der Deklaration der Variable ausgeführt:

    Beispiele:

    CFile File;  //Deklaration
    
    CStdioFile StdioFile;
    
    File.Open( "E:\\Urlaub\\Datei.dat", CFile::modeReadWrite | CFile::typeBinary );  //Öffnen
    
    StdioFile.Open( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );
    
    if( StdioFile.m_pStream == NULL )
    	return 0;
    
    /*
    Nur bei StdioFile:
    
    Mit Hilfe von CStdioFile::m_pStream könnt ihr herausfinden ob das öffnen der 
    Datei geklappt hat:
    
    Steht NULL in der Variable ist das Öffnen fehlgeschlagen.
    
    Bei CFile muss man mit CFileException arbeiten.
    */
    
    File.Close();  //Schließen
    
    StdioFile.Close();
    

    3. Das Auslesen der Datei

    Beim Auslesen der Dateien gibt es verschiedene Möglichkeiten. Man kann einen
    CString benutzen einen char Array oder einen CStringArray. Ich empfehle
    allerdings die CString oder CStringArray Variante, werde aber trotzdem alle
    Varianten hier aufführen.

    Zum Auslesen einer mit CFile geöffneten Datei steht uns die CFile::Read
    Methode zur verfügung. Bei StdioFile gibt es zusätzlich noch die Methode
    CStdioFile::ReadString, die es uns ermöglicht eine ganze Zeile zu lesen.

    - Die char Variante

    Bei char muss man voher einen großen Array erzeugen:

    char Array[1024] = "\0";  //Array mit 1024 Bytes initalisieren.
    

    Dieser Array kann nun 1024 Bytes bzw. Zeichen speichern. und ist mit \0
    initalisiert. Nun Öffnen wir und lesen eine Datei aus.

    //CFile File;
    
    //File.Open( "E:\\Urlaub\\Datei.dat", CFile::modeReadWrite | CFile::typeBinary );
    
    //char Array[1024] = "\0";
    
    File.Read( Array, 1024 );
    
    //File.Close();
    

    Es wird solange gelesen bis der Datenzeiger am Ende der Datei angekommen ist
    oder die 1024 Zeichen gelesen wurden. Dabei wird auf die Zeilen keine
    Rücksicht genommen. Wenn eine Zeile zu ende ist, geht's in der Nächsten weiter
    bis 1024 Zeichen voll sind. Dadurch das wir den Array voher mit \0
    initalisiert haben, wird uns nacher kein Datenmüll angezeigt, wenn wir
    den Inhalt des Arrays in einem Edit-Fenster erscheinen lassen.

    Für CStdioFile kann man das oben geschriebene komplett übernehmen.

    -Die CString Variante

    Mit einem CString ist es schon wesentlich komfortabler eine Datei auszulesen.
    Nicht nur, dass man keinen Array mehr initalisieren muss, sondern auch das man
    bei CStdioFile nun auch die CStdioFile::ReadString Methode nutzen kann, da
    diese nur CStrings erlaubt.

    Anmerkung: Soweit ich weiß, ist es gar nicht möglich bei den Methoden
    CFile::Read und CStdioFile::Read mit einem CString als Variable zu arbeiten.

    //CStdioFile StdioFile;
    
    //StdioFile.Open( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );
    
    CString Puffer = "";
    
    CStdioFile.ReadString( Puffer );
    
    //StdioFile.Close();
    

    Hier wird nun genau EINE Zeile ausgelesen. Der Dateizeiger wird dabei in die
    neue Zeile gesetzt um anschließend dort weiter zu lesen.

    Der Vorteil hieran ist das man nun die Daten beliebig bearbeiten kann, aber
    dazu komme ich später.

    4. Die komplette Datei auslesen

    Bisher haben wir nur eine Zeile ausgelesen. Wir wollen aber alle Daten aus der
    Datei einlesen.

    - Das erste Beispiel für char, jedes einzelne Zeichen wird hierbei ausgelesen

    //CFile File;
    
    //File.Open( "E:\\Urlaub\\Datei.dat", CFile::modeReadWrite | CFile::typeBinary );
    
    char Array[2] = "\0";
    
    CString str = "";
    
    while( File.Read( Array, 1 ) != 0 )
    {
    	if( strcmp( Array, "\r" ) == 0 )
    	{
    		//Eine Zeile ausgelesen, hier etwas mit der Zeile machen
    
    		//Nachdem etwas mit der Zeile gemacht wurde
    		str = "";
    	}
    	else if( strcmp( Array, "\n" ) != 0 )
    		str.Format( "%s%s", str, Array );
    }
    
    //File.Close();
    

    - Zweites Beispiel für CString und CStringArray

    Diese Methode ist in meinen Augen am besten für das Auslesen von Textdateien
    geeignet, jede Zeile ein Element im CStringArray bildet.
    Die Methode CStringArray::Add fügt immer ein Element hinzu ohne das man die
    genaue Anzahl der Elemente wissen muss.

    //CStdioFile StdioFile;
    
    //StdioFile.Open( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );
    
    //CString Puffer = "";
    
    CStringArray StringArray;
    
    while( StdioFile.ReadString( Puffer ) )
    	StringArray.Add( Puffer );  //Fügt ein Element hinzu
    
    //StdioFile.Close();
    

    Es würde auch so gehen, obwohl die obere Variante eleganter ist:

    //CStdioFile StdioFile;
    
    //StdioFile.Open( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );
    
    //CString Puffer = "";
    
    CStringArray StringArray;
    
    while( StdioFile.ReadString( Puffer ) )
    	StringArray.InsertAt( StringArray.GetCount() + 1, Puffer );  //Fügt ein Element hinzu
    
    //Es gibt noch die Methode CStringArray::SetAt. Diese wird benutz um ein
    bereits existierendes Element zu überschreiben.
    
    //StdioFile.Close();
    

    Hier wird jede Zeile in ein Element des Arrays geschrieben. So kann man jede
    Zeile im Speicher ansprechen, in einen CString kopieren und verändern. Mit der
    Methode CString::Remove können z.B. Zeichen entfernt werden:

    //CStringArray StringArray;
    
    StringArray.Add( "\"Hallo\"");
    StringArray.Remove( '\"' );  //Entfernt alle \" also " im String
    

    Außerdem können im String nach bestimmten Zeichenfolgen gesucht werden:

    //CStringArray StringArray;
    //CString Puffer = "";
    
    StringArray.Add( "E:\\Bilder\\MeineBilder\\Ich.jpg" );
    
    Puffer = StringArray.GetAt( 0 );  //Holt das Element an Stelle 0 aus dem Array
    
    Puffer = Puffer.Left( Puffer.ReverseFind( '\\' ) );  //Sucht von hinten nach vorne den ersten \\
    

    Hinweis zum Rückgabewert von CString::Find

    Wenn eine Zeichenfolge in einem String vorkommen soll und ihr dies testen
    wollt, müsst ihr es so formulieren:

    CString Puffer = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    if( Puffer.Find( "M" ) != -1 )
    {
    	//Code
    }
    
    /*
    Wenn die Funktion -1 zurückgibt wurde die Zeichenfolge NICHT gefunden
    Wenn die Zeichenfolge gefunden wurde wird der Startposition zurückgegeben, 
    deshalb != -1, da man zur Laufzeit nie weiß wo das Zeichen sich befindet.
    */
    

    Wenn ihr mehere Dateien auslesen wollt, bitte unbedingt darauf achten den
    Array mit CStringArray::RemoveAll() komplett zu leeren, bevor ihr wieder neue
    Elemente hinzufügt.

    Bitte auch bei CStringArray::InsterAt aufpassen:

    CStringArray Array;
    
    Array.Add( "Element 0" );
    
    Array.InsertAt( 0, "Element 0 überschreiben" );
    
    //In Array.GetAt( 0 ) steht schon etwas, deshalb rutsch das ganze einen nach 
    oben, d.h.
    //Array.Get( 1 ) == "Element 0", Array.GetAt( 0 ) == "Element 0 überschreiben" );
    

    5. Dynamische Arrays um größere Dateien auszulesen

    Um größeren Dateien auszulesen gibt es auch wieder mehere Möglichkeiten.
    Entweder man liest sie häppchenweise aus, also Dateien größer 100 MB oder man
    nimmt sich Speicher vom Freestore bzw. Heap. Es gab schon heiße Diskusionen
    über das Thema Heap und Freestore. Verschiedene Buch-Autoren haben auch andere
    Ansichten was nun was ist. Die einen sagen, alles was mit malloc allokiert
    wurde kommt vom Heap und alles was mit new allokiert wurde kommt vom
    Freestore. Andere sagen es sei genau andersherum. Nun es ist für uns egal von
    wo es kommt, hauptsache wir machen es richtig^^.

    Vorab: Wir werden hier den Befehl new benutzen. Alles was mit new allokiert
    wurde muss mit delete wieder gelöscht werden. Alles was mit new[] allokiert
    wurde muss auch mit delete[] gelöscht werden, da sonst Speicherfehler und
    Leaks entstehen die erst nach einem Neustart des Rechners wieder weg sind.

    - Beispiele für einen dynamischen CStringArray

    Um den CStringArray richtig zu allokieren müssen wir folgendes schreiben:

    CStringArray *Array = new CStringArray;
    

    Es handelt sich hierbei um einen Zeiger wie man an dem * erkennen kann. Je
    mehr Elemente wir dem Array hinzufügen umso mehr Speicher wird vom Heap bzw.
    Freestore genommen. Theoretisch gesehen könnten wir bis zu 4 GB Speicher
    anfordern wenn wir uns auf einem 32 Bit System befinden. Praktisch gesehen ist
    das unmöglich^^. 64 Bit Systeme könnten theoretisch 15 Terrabyste allokieren.
    Eigentlich unvorstellbar, aber irgendwann wirds wohl möglich sein^^.
    Wir beschränken uns erstmal auf gebräuchliche Zahlen wie z.B 50 - 200 MB.

    ***WICHTIG***

    Wir haben oben den Array mit new allokiert. Das heißt wir müssen ihn mit

    delete Array;
    

    wieder löschen. Sonst entstehen böse überraschungen. Ich weiß nicht wer's war,
    aber einer sagte zu mir: "Es könnte passieren, dass deine Mutter böse
    Pornomails bekommen könnte." Ganz so schlimm wirds wohl nicht sein^^, aber es
    wird dem PC nicht gut tun und es ist auch ein schlechter Stil, allokierte
    Arrays nicht wieder zu löschen. Selbst wenn der Stack aufgelöscht wird indem
    der Array allokiert wurde, der Speicher ist trotzdem noch da.

    Nun nehmen wir mal an wir haben eine Datei die ca. 150 MB groß ist. Um diese
    auszulesen müssen wir folgendes schreiben:

    //CStdioFile StdioFile;
    
    //StdioFile.Open( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );
    
    //CString Puffer = "";
    
    CStringArray *StringArray = new CStringArray;
    
    while( StdioFile.ReadString( Puffer ) )
    	StringArray->Add( Puffer );  
    
    //Hier komm nun -> statt einem Punkt hin, oder (*StringArray).Add( Puffer );
    
    //viel viel code
    
    delete StringArray;
    
    //StdioFile.Close();
    

    6. Das Schreiben von Dateien

    Das Schreiben funktioniert genauso wie das lesen, nur das statt CFile::Read,
    nun CFile::Write bzw. statt CStdioFile::ReadString, nun
    CStdioFile::WriteString geschrieben werden muss. Ein konkretes Beispiel:

    //CFile File;
    
    //File.Open( "E:\\Urlaub\\Datei.dat", CFile::modeReadWrite | CFile::typeBinary );
    
    char *buffer = "Hallo Welt!!!\r\nTest 12345";
    
    File.Write( buffer, strlen( buffer ) );
    
    //strlen gibt die Länge von buffer zurück, die Methode CFile::Write benötigen
    diesen Wert um zu wissen wieviele Zeichen geschrieben werden sollen.
    
    //File.Close();
    

    Bei StdioFile geht das schreiben bequemer, mittels CStdioFile::WriteString.

    //CStdioFile StdioFile;
    
    //StdioFile.Open( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );
    
    CString str = "Hallo Welt!!!\r\nTest 12345";
    
    StdioFile.WriteString( str );
    
    //StdioFile.Close();
    

    Sooooo, war zwar ein langer Text, aber ich hoffe für die, die in die FAQ
    schauen, sehr hilfreich. Falls etwas nicht stimmen sollte, oder ihr
    Verbesserungsvorschläge habt, immer raus damit, bin für alles offen. Der
    Beitrag soll übrigens in die FAQ^^.

    MfG

    Nocadas



  • Also ein CStringArray Objekt auf dem Heap anzulegen hat irgendwie keinen Sinn. Das kann ruhig auf den Stack. Denn in der Klasse CStringArray wird intern dynamisch Speicher auf dem Heap angelegt.



  • Es befinden sich sehr viele Fehler darin.
    z.B.
    char Array[1024] = "\0";
    Dzu willst da jetzt 1024 Zeichen plus das "\0" drin haben?
    Überprüfe mal ob sich das ausgeht und ob \0 keine Platz braucht.

    Warum sollte man eine Datei mit 100MB in ein CStringArray lesen wollen.
    Sowas macht nur MS und sollte verhindert werden. Wenn ich so eine TXT-Datei öffne möchte ich nicht X-MB speicher brauchen und 10 min warten bis die Datei geladen ist.

    PS.: Du hast dir sehr viel Mühe gemacht aber musst jetzt damit rechnen das man deinen Text in der Luft zerreißt.



  • Moin,

    Also man kann Microsoft leider nicht hinter die Karten schauen, wie die ihre
    Programm schreiben, doch man kann sich selbst Gedanken darüber machen wie man es am geschicktesten macht. Daher weiß ich nicht ob der CStringArray beim Hinzufügen von Elementen auch Speicher vom Heap benutzt, dazu müsste man mal jemand von MS fragen, aber logisch wäre es ja. Aber es ändert nichts daran, die ganze Saceh trotzdem aufzuschreiben, falls Neulinge fragen haben, denn es steht hier so wie man es auf schreiben muss, egal ob es sich nun um

    CStringArray *pArray = new CStringArray;
    
    //oder
    
    int *pInteger = new int;
    
    //oder
    
    int *pSchleife = new int[100];
    

    handelt.

    So nun zu Unix-Tom:

    Versuche mal anstatt

    char Array[1024] = "\0";
    
    //zu schreiben
    
    char Array[1024] = '\0';
    

    Im Programm gibt der dir eine Fehlermeldung aus.

    'Initialisierung' : 'char' kann nicht in 'char [1024]' konvertiert werden.

    Selbst:

    strcpy( Array, '\0' );
    
    //funktioniert nicht, nur
    
    strcpy( Array, "\0" );
    

    Letzes führt dazu das immernoch Datenmüll in Array steht nur

    char Array[1024] = '\0';
    

    führt dazu das dann im Array "" steht, debugg das mal, dann siehst du es.

    Aber finde es schön das beim Text nicht unberüht bleibt und gelesen wird^^.

    MfG

    Nocadas



  • Du solltest meine Beitrag mal lesen.

    Was hat
    char Array[1024] = '\0';
    damit zu tun was ich geschrieben habe?
    Du solltest Dir überlegen wieviel Zeichen in diese Variable reingehen ohne das Du probleme bekommst und nicht ob man doppelte Hochkommas oder einfache Hochkommas verwendet. C ist nicht PHP wo man sich die Hochkommas Grundsätzlich aussuchen kann.

    Die Klasse CStringArray liegt als Sourcecode vor. Da braucht man nur nachzusehen.
    Die MFC gibt es nicht weil MS nur die WINAPI kapseln wollte sondern auch um bestimmte Dinge zu vereinfachen. Dazu gehört auch das man sich nicht um die Speicherfreigabe von CString oder ähnliches kümmern muss.



  • Ok da hab ich deinen Beitrag erst falsch verstanden aber behaupte nicht, dass ich ihn nicht gelesen hätte, sonst würd ich keine Antwort drunter schreiben.
    Wenn ich deinen Beitrag nochmal neu aufgreifen darf, das "\0" verbaucht genau einen Platz im Array, hab das mit

    char Array[1] = "\0"  // geht nicht
    
    //und
    
    char Array[2] = "\0"
    

    ausprobiert.

    Beim ersten gibts einen Überlauf, deshalb muss mindestens eine 2 in den [] stehen. Hab ich also einen Array mit 1024 Zeichen reserviert und initalisier diesen mit "\0" und lese danach 1024 Zeichen ein, wird das "\0" überschrieben, doch es müsste sich theoretisch wieder im Element 1023 befinden. Nur da bin ich mir noch nicht ganz schlüssig^^. Es ist die Frage, es ist ja sogesehen ein Array mit Zeichen, und kein String der mit \0 enden muss. Wenn du mir da nochmal eien Ansatz geben könntest^^.

    Und nun nochmal zur MFC. Sicherlich liegt es im Sinne von MS alles zu vereinfachen, doch es gibt Leute, die die MFC nicht benutzen und lieber mit der WinApi basteln, dann gibt es wiederum Leute die sich nicht immer auf die MFC verlassen und deshalb ist es sinnvoll auch Beispiele ohne MFC anzuführen.

    Du hast auch geschrieben das sehr viele Fehler in meinem Artikel drin sind, bisher hast du nur einen genannt, hab jedes Beispiel bei mir getestet und es ging tadelos und auch im Debugmodus standen in den Variablen immer Werte die nicht nach Speichermüll aussehen, falls es doch Sachen gibt die umständlich sind, ruhig raus damit, dafür diskutieren wir hier doch^^.



  • Ein \ ist in Cpp ein \\ !!!

    Stimmt nicht
    Im String steht immer noch
    E:\\Urlaub\Datei.dat"
    Übrigend nennt man dies Escapen.

    CFileException muss nicht umbedingt gesetzt werden.

    Warum? Nur weil du es nicht geschafft hast. Deshalb kann man nicht so eine Aussage machen.

    CStdioFile( "C:\\Daten\\Ich\\Datei.txt", CFile::modeReadWrite | CFile::typeText );

    Das funktioniert nicht

    u.s.w.

    Zu deinen Fragen: Anfängertut

    http://tutorial.schornboeck.net/c_string.htm
    NULL-Terminiert.

    char Array[2] = "\0"

    Nimmt ein Zeichen von dir auf weil die Terminierung noch dazu kommt.

    CStringArray ist eine Klasse der MFC. Diese beschreibst Du. SOmit hat dies nichts mit WINAPI zu tun.
    Wenn du die verwendest brauchst du diese Instanz nicht mit NEW anlegen nur um große Dateien einlesen zu können.



  • hi

    wieso ist dies "Ein \ ist in Cpp ein \\ !!! " falsch?
    wenn der Pfad so heißt E:\\Urlaub\Datei.dat"
    muss ich doch schreibe:

    E:\\\Urlaub\\Datei.dat"

    oder 😕



  • Das mit CStdioFile habe ich geändert, aber wieso stimmt das \\ nicht.
    Ich formuliere den Satz dann um:

    "Möchte man in einem Pfad einen \ schreiben muss man im Quellcode \\ dafürschreiben, da ein \ ein Spezialzeichen einleitet."

    Wenn das geht, schreib ich das oben auch hin.

    Nun zu CFileException. Was passiert wenn man diesen Parameter nicht angiebt bei:

    CStdioFile file( "bla.txt", CFile::modeRead );
    

    Nichts... er öffnet diese Datei genauso, als wenn es nicht da stünde und darauf kommt es mir an. Wenn du allerdings das "bla.txt" weglässt funktioniert der aufrufe nicht. Und wenn du mal genauer nachgelesen hättest, steht da, dass ich es bei Gelegenheit ergänze. Denn einfach kopieren und einfügen ist quatsch. Ich schreib erst was hierhin wenn ich es selbst getestet habe und es funktioniert hat. Sonst jubel ich den anderen Leuten nichts unter.

    Soooo dann das mit dem char, also ich hab mir das Tutorial angeschaut.

    Es steht ja dadrin: "H" "a" "l" "l" "l" "\0", wäre das hier:

    char *buffer = "Hallo";
    

    In wirklichkeit ist buffer ein Array mit 6 Feldern also von 0 bis 5.
    Was ich nun an meinem Beispiel nicht verstehe ist, ich habe ein Array für 3 Zeichen reserviert, von 0 bis 2. Kann davon aber NUR 2 Zeichen gebrauchen, da im dritten Feld ein \0 steht. Nur was ich bei einem Feld von [1]. 2 Zeichen...
    1 + Terminierung. D.h. wenn ich den String mit \0 initalisiere müsste im Feld [0] eine Terminierung stehen und im Feld [1], oder sehe ich das falsch.

    Ok und was mach ich mit dem letzen Teil, dem Speicher allokieren...
    Soll ich das gegen ein int Beispiel ersetzen oder ganz weglassen?


Anmelden zum Antworten