Programmcode Verständnisproblem (Thema: Strings)



  • Hi,

    ich bin C++-Anfänger und arbeite gerade das Tutorial auf www.cpp-tutor.de durch.
    Momentan habe ich aber ein Verständnisproblem bei einer Zeile im Code eines Programms, das als Beispiel zur Veranschaulichung des Themas gegeben wurde.
    Das Programm zählt die Häufigkeit des Auftretens der einzelnen Buchstaben des Alphabets in einem bestimmten Text.
    Ich denke, einige kennen das Tutorial und den Inhalt, aber ich poste hier zum besseren Verständnis am besten den gesamten Code:

    // Lösung zur string Klasse
     #include <iostream>
     #include <iomanip>
     #include <fstream>
     #include <string>
     using std::cout;
     using std::endl;
    
    // Konstanten für Dateiname und Anzahl der Buchstaben im Alphabet
     const char *const pFILENAME = "test.txt";
     const int NUMOFCHARS = 26;
    
    // main() Funktion
     int main()
     {
        // Datei öffnen
        std::ifstream inFile(pFILENAME);
        if (!inFile)
        {
           cout << "Kann Datei " << pFILENAME << " nicht öffnen!" << endl;
           exit(1);
        }
    
        // Zähler für die Anzahl der Buchstaben definieren und initialisieren
        int characters[NUMOFCHARS] = {0};
        // Zähler für Sonderzeichen wie z.B. '.' oder ',' usw.
        int specialChar = 0;
    
        // Schleife zum Einlesen der Datei
        do
        {
           // String für eingelesene Zeile aus der Datei
           std::string line;
           // Eine Zeile aus der Datei einlesen
           std::getline(inFile,line);
           // Falls Dateiende nicht erreicht
           if (!inFile.eof())
           {
              // Komplette Zeile durchlaufen
              for (unsigned int index=0; index<line.size(); index++)
              {
                 // Falls Buchstabe im String a...z
                 if ((line[index]>='a') && (line[index]<='z'))
                    [b]characters[line[index]-'a']++;[/b]
                 else 
                    // Falls Buchstabe im String A...Z
                    if ((line[index]>='A') && (line[index]<='Z'))
                      [b]characters[line[index]-'A']++;[/b]
                    else
                       // Sonderzeichen erhöhen
                       specialChar++;
              }
           }
        } while (!inFile.eof());
    
        // Datei auch wieder schliessen!
        inFile.close();
    
        // Ergebnis ausgeben
        cout << "Anzahl der Buchstaben in der Datei " << pFILENAME << endl;
        // Alle Buchstabenzähler ausgeben
        for (int index=0; index<NUMOFCHARS; index++)
        {
           // Nach jedem 5. Buchstaben eine neue Zeile beginnen
           if (index%5 == 0)
              cout << endl;
           cout << static_cast<char>(index+'a') << ": " << std::setw(3)
                << characters[index] << '\t';
        }
        // Noch Anzahl der Sonderzeichen ausgeben
        cout << "\nSonderzeichen: " << specialChar << endl;
     }
    

    Ich verstehe die fettgedruckten Zeilen (Zeile 44 und 48) nicht wirklich. Eventuell kann mir das jemand erklären?
    Danke schon im Voraus.

    Grüße



  • Der Wert von Line[index] entspricht einem ASCII-Wert der weniger 'a' / 'A' gerechnet werden muss, damit dies eine Zahl zwischen 0 und 25 ergibt. Dieser Index von "characters" wird dann hochgezählt.

    Siehe auch ASCII-Tabellen.



  • Du zählst die Anzahl der Buchstaben des Alphabets, unabhängig davon, ob sie klein- oder großgeschrieben werden. Dazu hast du ein Array der Länge 26, um die Anzahl der Vorkommen zu speichern. Die von dir markierten Zeilen machen nichts anderes, als den Index anhand des Zeichens zu bestimmen.
    Bsp:
    Der Buchstabe 'a' kommt gehört an den Index 0, der entsprechende Integer Wert von 'a' ist 65. 'a' ist lediglich eine andere Schreibweise für 65 (siehe ASCII Tabelle), also ziehst du 65 von 'a' ab und kommst zu Index 0. Da in der ASCII Tabelle alle Buchstaben lückenlos aufeinanderfolgen kannst du den Index einfach bestimmen:

    if( CH >= 'a' && CH <= 'z' )
    {
       unsigned int Index = CH - 'a';
    }
    

    Für Großbuchstaben funktioniert das Ganze analog.



  • Alles klar, habs kapiert.
    Ich hatte einfach nicht an die ASCII-Tabelle gedacht, damit ist das ganze logisch, jetzt versteh ich auch den Rest zu 100%.
    Danke nochmal!



  • Conny Lingo schrieb:

    .. arbeite gerade das Tutorial auf www.cpp-tutor.de durch. ...
    Das Programm zählt die Häufigkeit des Auftretens der einzelnen Buchstaben des Alphabets in einem bestimmten Text.
    Ich denke, einige kennen das Tutorial und den Inhalt, aber ich poste hier zum besseren Verständnis am besten den gesamten Code:

    Hallo Conny,

    der Code hat einen Fehler. Falls die Datei als letztes Zeichen keinen(!) LF hat, so werden die Zeichen der letzten Zeile nicht mehr mitgezählt. Finde ich für ein Tutorial ziemlich schwach. Anbei die Variante, die zumindest diesen Fehler nicht mehr hat.

    // Lösung zur string Klasse ???
    #include <iostream>
    #include <iomanip> // setw
    #include <fstream> 
    #include <cctype> // tolower
    using std::cout;
    using std::endl;
    
    // Konstanten für Dateiname und Anzahl der Buchstaben im Alphabet
    const char *const pFILENAME = "Test.txt";
    const int NUMOFCHARS = 26; // besser: NUMOFCHARS = 'z'-'a'+1;
    
    // main() Funktion
    int main()
    {
        // Zähler für die Anzahl der Buchstaben definieren und initialisieren
        int characters[NUMOFCHARS] = {0};
        // Zähler für Sonderzeichen wie z.B. '.' oder ',' usw.
        int specialChar = 0;
        {
            // Datei öffnen
            std::ifstream inFile(pFILENAME);
            if (!inFile)
            {
                cout << "Kann Datei " << pFILENAME << " nicht öffnen!" << endl;
                exit(1);
            }
    
            // ggf. inFile >> std::noskipws; falls Leerzeichen/LFs auch mitgezählt werden sollen
            for( char c; inFile >> c; )
            {
                c = std::tolower( c );
                // Falls Buchstabe im Intervall a...z
                if ((c>='a') && (c<='z'))
                    ++characters[c-'a'];
    
                // Sonderzeichen erhöhen
                else
                    ++specialChar;
            }
        }
        // Ergebnis ausgeben
        cout << "Anzahl der Buchstaben in der Datei " << pFILENAME << endl;
        // Alle Buchstabenzähler ausgeben
        for (int index=0; index<NUMOFCHARS; index++)
        {
            // Nach jedem 5. Buchstaben eine neue Zeile beginnen
            if (index%5 == 0)
                cout << endl;
            cout << static_cast<char>(index+'a') << ": " << std::setw(3)
                << characters[index] << '\t';
        }
        // Noch Anzahl der Sonderzeichen ausgeben
        cout << "\nSonderzeichen: " << specialChar << endl;
    
        return 0;
    }
    

    im übrigen verstehe ich nicht, was das mit strings zu tun haben soll.

    Gruß
    Werner


Anmelden zum Antworten