Grundlagen für das Projekt (Teil 1)

Website: Lerne ELEKTROTECHNIK und PROGRAMMIEREN
Kurs: Kurs zum Buch "Lerne Programmieren mit Projekten: C++"
Buch: Grundlagen für das Projekt (Teil 1)
Gedruckt von: Gast
Datum: Saturday, 20. April 2024, 13:25

Beschreibung



1. Worum geht es?

In diesem Abschnitt lernst du die wichtigsten Grundlagen kennen, um das Kapitel-Projekt zu verstehen. Aus dem letzten Kapitel bringst du schon einige wichtige Grundlagen wie die while-Schleife oder die if-else-Verzweigung mit. 

Hier wird dieses Wissen nun um einen neuen Schleifentyp erweitert und um die Fähigkeit, größere Datenmengen wie z.B. Zeichen eines Textes effizient zu organisieren. Außerdem lernst du, wie du aus deinem eigenen Programm heraus Dateien erzeugen und deren Inhalt auslesen und verändern kannst.

2. FOR-Schleife: Anweisungen wiederholen

Worum geht es? 

Schleifen gehören zu den wichtigsten Werkzeugen einer Programmiersprache. Mit ihnen ist es möglich, Anweisungen wiederholt auszuführen, ohne dass dafür neuer Code entstehen muss. 

Du kannst zum Beispiel ein Menü programmieren, dass den Benutzer so lange nach einer Auswahl fragt, bis ein gültiger Wert eingegeben wurde. 

Oder du entwickelst ein Spiel und nutzt eine Schleife dazu, die einzelnen Animationsschritte nacheinander abzuarbeiten. Für beide Fälle ist die while-Schleife sehr gut geeignet, da die Schleifenausführung von einer konkreten Bedingung abhängt und die Anzahl der Wiederholungen nicht bekannt ist. 

Für Fälle (und davon gibt es viele), wo genau bekannt ist, wie viele Durchläufe nötig sind, ist die for-Schleife oft eine bessere Wahl. Im Code-Beispiel kannst du sehen, wie sie aufgebaut ist und wie sie sich von der while-Schleife unterscheidet.

Was kannst du danach?

  • Eine for-Schleife als Alternative zu while nutzen


#include <iostream>

using namespace std; 

int main() 
{
    // Komponenten der for-Schleife
    for (int i = 0; i < 5; i++)
    {
        cout << "i=" << i << endl;
    }

    // Zum Vergleich: die while-Schleife
    int cnt{0};
    while (cnt < 5)
    {
        cout << "cnt=" << cnt << endl;
        cnt++;
    }
    return 0;
}

2.1. Steuern der Durchlaufrichtung

Worum geht es? 

Im letzten Beispiel hat die Zählvariable i die Werte 0,1,2,3,4 durchlaufen. Wenn man wie im nachstehenden Code gezeigt Initialisierung und Anweisung anpasst, dann lässt sich die Durchlaufrichtung auch umkehren. 

Was kannst du danach?

  • Die Laufrichtung einer for-Schleife umkehren


#include <iostream>

using namespace std; 

int main() 
{
    // Steuern der Durchlaufrichtung
    for (int i = 4; i > 0; i--)
    {
        cout << "i=" << i << endl;
    }
    return 0;
}

2.2. Verändern der Schrittweite

Worum geht es? 

Im Anweisungsteil der for-Schleife können beliebige Anweisungen stehen, es muss nicht immer das häufig anzutreffende i++ sein. Wenn du die Zählvariable mit jedem Durchlauf um zwei statt um eins erhöhen willst, dann kannst du wie im Code-Beispiel gezeigt einfach i += 2 in den Anweisungsteil schreiben.

Was kannst du danach?

  • Die Schrittweite der Zählvariablen einer for-Schleife verändern


#include <iostream>

using namespace std; 

int main() 
{
    // Verändern der Schrittweite
    for (int i = 0; i <= 10; i += 2)
    {
        cout << "i=" << i << endl;
    }
    return 0;
}

2.3. Schleife mit mehreren Zählern

Worum geht es? 

In den bisherigen Beispielen haben wir im Kopf der for-Schleife immer nur eine Variable benutzt. Es gibt aber Fälle, wo mehrere Variablen sinnvoll sind, zum Beispiel um gleichzeitig hoch und runter zu zählen. 

In nachstehenden Code siehst du ein Beispiel für zwei Variablen i und j, die mit unterschiedlichen Werten initialisiert werden und im Anweisungsteil mit ++ hoch und mit -- herunter gezählt werden.

Was kannst du danach?

  • Mehrere voneinander unabhängige Zählvariablen in einer for-Schleife einsetzen


Beschreibung

#include <iostream>

using namespace std; 

int main() 
{
    // Schleife mit mehreren Zählern
    for (int i{0}, j{5}; i <= 5, j >= 0; i++, j--)
    {
        cout << "i=" << i << ", j=" << j << endl;
    }    return 0;
}

2.4. Typische Fehlerquellen

Worum geht es? 

Die for-Schleife ist einfach zu bedienen und wird in fast jedem Programm verwendet. Je nach Einsatz kann es aber zu einigen typischen Fehlern kommen, die im nachstehenden Code-Beispiel aufgeführt sind. 

Was kannst du danach?

  • Typische Fehler rund um die for-Schleife erkennen und vermeiden


Beschreibung

#include <iostream>

using namespace std; 

int main() 
{
    /*
    // Fehler: Bedingung nie erfüllt!    
    for (int i = 1; i != 10; i += 2)
    {
        cout << "i=" << i << endl;
    }
    */

    // Fehler: Durchlauf-Anzahl um 1 daneben
    string text = "Hallo";
    for (int i = 0; i <= text.length(); i++)
    {
        // Probiere beide Varianten aus
        cout << text[i] << endl;
        //cout << text.at(i) << endl;
    }

    // Fehler: Zähler der äußeren Schleife genutzt
    for(int i=0; i<5; i++)
    {
        for(i=0; i<5; i++)
        {
            cout << i << endl;
        }
    }
    return 0;
}

3. FSTREAM: Textdateien lesen und schreiben

Worum geht es? 

Du hast mit iostream-Bibliothek schon Daten in der Kommandozeile ausgegeben und von dort eingelesen. Dabei hast du die Objekte cin und cout sowie den Eingabeoperator >> und den Ausgabeoperator << kennen gelernt.

In diesem Modul lernst du jetzt die fstream-Bibliothek kennen, die auf fast die gleiche Weise funktioniert, aber statt der Kommandozeile eine Datei zur Ein- und Ausgabe verwendet.

Der nachstehenden Code ist ein erstes, einfaches Beispiel, in dem der Inhalt einer Datei gelesen und in der Kommandozeile ausgegeben wird. 

Was kannst du danach?

  • Inhalt von Textdateien auslesen


Dies ist der Inhalt von "datei1.txt":
#include <string>
#include <iostream>
#include <fstream> // File-Stream

using namespace std;

int main()
{
// Text aus Datei lesen
    std::ifstream lesen{"datei1.txt"};
    while (lesen)
    {
        std::string text;
        //lesen >> text; // Trennzeichen = " "
        std::getline(lesen, text); //  = "\n"
        std::cout << text << endl;
    }
    
    return 0; 
}
Beim Einlesen kannst du zwischen zwei Varianten wählen: cin oder getline. Probiere durch ein- und auskommentieren beide Befehle aus und sieh dir die Unterschiede in der Ausgabe an. 

3.1. Text in Dateien schreiben

Worum geht es? 

Nachdem du im letzten Beispiel gesehen hast, wie der Inhalt einer Textdatei ausgelesen werden kann, lernst du jetzt, wie Textinhalte in einer Datei gespeichert werden können. 

In diesem Beispiel wird eine Datei zum Schreiben geöffnet. Wichtig dabei ist, dass hier ein Objekt vom Typ ofstream verwendet wird (o für Output). 

Was kannst du danach?

  • Inhalt von Textdateien auslesen


#include <string>
#include <iostream>
#include <fstream> // File-Stream

using namespace std;

int main()
{
    // Text in Datei schreiben
    std::ofstream schreiben{"datei1.txt"};
    schreiben << "Dies ist Zeile 1" << endl;
    schreiben << "Dies ist Zeile " << 2 << endl;
    schreiben.close();
    
    // Text zur Kontrolle aus Datei lesen
    std::ifstream lesen{"datei1.txt"};
    while (lesen)
    {
        std::string text;
        //lesen >> text; // Trennzeichen = " "
        std::getline(lesen, text); //  = "\n"
        std::cout << text << endl;
    }
    
    return 0; 
}
Da du dir den Inhalt der erzeugten Datei nicht in deinem Web-Browser ansehen kannst, wird im Anschluss an das Schreiben der Inhalt mit dem Code aus dem letzten Beispiel ausgegeben. 

3.2. Text an Dateien anhängen

Worum geht es? 

Im letzten Beispiel hast du den Schreibzugriff auf Dateien bereits kennen gelernt. Bei der dort gewählten Zugriffsart würden allerdings vorhandenen Inhalte überschrieben werden. 

Wenn du aber gespeicherte Inhalte erhalten möchtest (z.B. beim Erzeugen von Messprotokollen), dann ist es sinnvoll, neue Inhalte ans Ende der Datei anzuhängen. Wie das funktioniert, zeigt dieses Beispiel. 

Was kannst du danach?

  • Text an existierende Dateien anhängen.


#include <string>
#include <iostream>
#include <fstream> // File-Stream

using namespace std;

int main()
{
    // Text in Datei schreiben
    std::ofstream schreiben{"datei1.txt"};
    schreiben << "Dies ist Zeile 1" << endl;
    schreiben << "Dies ist Zeile " << 2 << endl;

    // Text anhängen (engl. 'append')
    schreiben.close(); // Datei schließen
    schreiben.open("datei1.txt", std::ios::app);
    if (!schreiben) // Auf Fehler prüfen
    {
        // Versuchsweise 'open' auskommentieren
        std::cerr << "Datei nicht geöffnet!n";
        return 1; // Programm mit Fehler beenden
    }
    schreiben << "Dies ist Zeile 3" << endl;    
    
    // Text zur Kontrolle aus Datei lesen
    std::ifstream lesen{"datei1.txt"};
    while (lesen)
    {
        std::string text;
        //lesen >> text; // Trennzeichen = " "
        std::getline(lesen, text); //  = "\n"
        std::cout << text << endl;
    }
    
    return 0; 
}
Da du dir den Inhalt der erzeugten Datei nicht in deinem Web-Browser ansehen kannst, wird im Anschluss an das Schreiben der Inhalt mit dem Code aus dem letzten Beispiel ausgegeben.