Buchstaben zählen



  • Moin, wie kann ich aus einem char array bestimmte Buchstaben zählen (bspw. a, b, e , i, o, u)?
    Ich bekomme das ganze mit getline nicht wirklich hin. Also ich würds mit getchar schaffen wenn die Vorgabe nicht wäre "aus einem char array mit maximal 100 zeichen"
    Code hier:
    Die kommentare sind meine bisherigen Ideen für das mit getline.

    #include <iostream>
    
    
    using namespace std;
    
    int main()
    {
    	//char satz[100];
    	int alphabet[6] = { 0 };
    	char c = 0;
    	//int i = 0;
    	cout << "Gib bitte einen Satz ein: " << endl;
    	//cin.getline(satz, sizeof(satz));
    	while((c = getchar()))
    	{
    		if (c == 'e')
    		{
    			alphabet[0] ++;
    		}
    		else if (c == 'r')
    		{
    			alphabet[1] ++;
    		}
    		else if (c == 'n')
    		{
    			alphabet[2] ++;
    		}
    		else if (c == 's')
    		{
    			alphabet[3] ++;
    		}
    		else if (c == 't')
    		{
    			alphabet[4] ++;
    		}
    		else if (c == 'l')
    		{
    			alphabet[5] ++;
    		}
    		else if (c == '\n')
    			break;
    		//i++;
    	}
    	cout << endl << endl << endl;
    	cout << "e: " << alphabet[0] << endl;
    	cout << "r: " << alphabet[1] << endl;
    	cout << "n: " << alphabet[2] << endl;
    	cout << "s: " << alphabet[3] << endl;
    	cout << "t: " << alphabet[4] << endl;
    	cout << "l: " << alphabet[5] << endl;
    
    }
    


  • while(c = satz[i])
    


  • @Mxxrcel BTW: wenn du die Buchstaben auch in ein Array packst, bist du variabler und es ist auch kürzer.



  • @DirkB sagte in Buchstaben zählen:

    while(c = satz[i])
    

    Als ob das wirklich so einfach ist, wow
    Danke dir.



  • Wenn man die Beschränkungen der Aufgabe entfernt, wird es leichter:

    #include <iostream>
    #include <map>
    #include <string>
    
    int main() {
        std::cout << "Gib bitte einen Satz ein:\n";
        std::string s;
        getline(std::cin, s);
        std::map<char, int> charCount;
        for (char c : s) 
            ++charCount[c];
        for (const auto &[c, n] : charCount) {
            std::cout << "Zeiche '" << c << "' kommmt " << n << " mal vor.\n";
        }
    }
    

    Das gibt die für jedes Zeichen aus dem String aus, wie oft es vorkommt. Keine Längenbeschränkung, keine Buchstabenbeschränkung. (gut, die map ist für lange Strings hier wohl nicht wirklich am effizientesten, weil man ein Array mit 256 Einträgen nehmen kann, das man am Ende einmal durchloopt, aber ich finde das Programm so am einfachsten)



  • @Mxxrcel sagte in Buchstaben zählen:

    Als ob das wirklich so einfach ist,

    Das war das einfachste für deinen Code

    Aber while((c = satz[i]) != '\0') sollte keine Warnung mehr bezüglich == geben.
    Ist aber identisch zur kurzen Schreibweise.



  • Und noch eine Anmerkung

    @Mxxrcel sagte in Buchstaben zählen:

    char c = 0;
    while((c = getchar()))

    getchar() liefert ein intzurück. So kann neben den Zeichen (char) auch noch das EOF übermittelt werden.
    EOF ist häufig -1.

    Deine Schleife achtet aber nur auf ungleich 0, wird also im Fehlerfall bzw beim Ende nicht beendet.

    Spaßig wird das aber erst bei Binärdaten (aus einer Datei) oder einem erweiterten Zeichensatz (z.B. ASCII und Umlaute)



  • #include <iostream>
    
    int main() 
    {
        char satz[100];
        int alfabet[6] = {0};
    
        std::cin.getline(satz, 100);
    
        for (int i = 0; satz[i] != 0 && i < 100; i++)
        {
            switch (satz[i])
            {
            case 'a':
                alfabet[0]++;
                break;
            case 'b':
                alfabet[1]++;
                break;
            case 'e':
                alfabet[2]++;
                break;
            case 'i':
                alfabet[3]++;
                break;
            case 'o':
                alfabet[4]++;
                break;
            case 'u':
                alfabet[5]++;
                break;
            }
        }
    
        std::cout << std::endl << std::endl << std::endl;
    
        std::cout << "a: " << alfabet[0] << std::endl;
        std::cout << "b: " << alfabet[1] << std::endl;
        std::cout << "e: " << alfabet[2] << std::endl;
        std::cout << "i: " << alfabet[3] << std::endl;
        std::cout << "o: " << alfabet[4] << std::endl;
        std::cout << "u: " << alfabet[5] << std::endl;
    
        return 0;
    }
    
    hallo dies ist ein test ich bin so super toll im programmieren
    
    
    
    a: 2
    b: 1
    e: 6
    i: 7
    o: 4
    u: 1
    

    das problem war jetzt was?



  • @Wade1234 sagte in Buchstaben zählen:

    das problem war jetzt was?

    Dass es auch kürzer geht und trotzdem nicht string verwendet (warum zur Hölle lernen Anfänger eigentlich immer char-Arrays statt viel einfacher zu benutzende std::strings?!):

    #include <iostream>
    
    int main()
    {
        char satz[100];
        int letter_count[256] = {0};
        std::cin.getline(satz, 100);
    
        for (int i = 0; satz[i]; ++i)
            ++letter_count[satz[i]];
    
        for (char c : "abeiou") {
            if (c) std::cout << c << ": " << letter_count[c] << '\n';
        }
    }
    

    PS: ich habe mir mal die Freiheit genommen, "alfabet" umzubenennen.
    PS2: Unter der Annahme, dass char unsigned ist.



  • @wob sagte in Buchstaben zählen:

    @Wade1234 sagte in Buchstaben zählen:

    das problem war jetzt was?

    Dass es auch kürzer geht und trotzdem nicht string verwendet

    es kommt aber nicht auf die länge, sondern auf die technik (und in diesem fall die übersichtlichkeit und die verständlichkeit) an.

    (warum zur Hölle lernen Anfänger eigentlich immer char-Arrays statt viel einfacher zu benutzende std::strings?!):

    meine vermutung wäre jetzt, dass man bei c-strings seinen keks anstrengen muss, um einfache programmabläufe zu planen, während man bei strings einfach stupide eine methode an die andere klatscht. eine weitere vermutung wäre, dass es ungefähr 1 mrd programme gibt, die mit c-strings erstellt wurden, sodass ein gewisses verständnis dafür vorhanden sein sollte.

    PS: ich habe mir mal die Freiheit genommen, "alfabet" umzubenennen.

    um ehrlich zu sein habe ich das wort im duden "nachgeschlagen" (duden.de) und dabei festgestellt, dass es eigentlich immer noch "alphabet" heißt. weil man aber merkwürdiger weise statt "ketchup" "ketschup'" und statt "portemonnaie" "portmonee" schreibt, und mir das aus irgendwelchen gründen gewaltig auf den keks geht, dass diejenigen leute, die damals die rechtschreibreform begründet und das dann weiche wissenschaft genannt haben, wahrscheinlich entsprechen reich wurden, habe ich eben "alfabet" geschrieben. 😄

    PS2: Unter der Annahme, dass char unsigned ist.

    sowohl "-1" als auch "255" sind entsprechend zu 11111111 🙄



  • @Wade1234 sagte in Buchstaben zählen:

    @wob sagte in Buchstaben zählen:

    PS2: Unter der Annahme, dass char unsigned ist.

    sowohl "-1" als auch "255" sind entsprechend zu 11111111

    Selbst wenn -1 von char auf int erweitert wird, bleibt es -1.
    Es spielt da keine Rolle ob der Index int wird oder charbleibt.



  • @Wade1234 sagte in Buchstaben zählen:

    es kommt aber nicht auf die länge, sondern auf die technik (und in diesem fall die übersichtlichkeit und die verständlichkeit) an.

    Und du findest das riesige case-Statement und die vielen couts übersichtlicher und verständlicher? Zumal man sich Geheimwissen wie "e" ist an index 2 irgendwie merken muss.

    sowohl "-1" als auch "255" sind entsprechend zu 11111111

    hä?

    man müsste wohl sowas machen wie ++letter_count[static_cast<unsinged char>(satz[i])];
    Und eigentlich müsste ich wohl auch das Array auf std::numeric_limits<unsigned char>::max() begrenzen... Wobei, wenn ich ein System mit einem 64-bittigen char habe, ist meine Lösung nur sehr mäßig gut 😉

    festgestellt, dass es eigentlich immer noch "alphabet" heißt

    Das war ein Grund, weswegen ich es umbenannt habe, aber nicht der einzige.


Anmelden zum Antworten