Zeichen in einer Zeichenkette zählen C#



  • Servus miteinander,
    bin neu hier, stell mich kurz vor.
    Heiße Benji und bin 21 Jahre alt. Da ich in der Schule Informatik 4-Stündig hatte, interessiere ich mich immer noch sehr dafür und programmiere ab und zu.
    Jetzt habe ich ein paar Aufgaben und bin dabei die zu lösen, eine besorgt mir momentan noch kleinere Probleme, ich komme einfach nicht drauf.

    Ich solle ein Programm schreiben, dass eine Zeichenkette als char-array und dann ein einzelnes Zeichen einliest, (das habe ich, siehe unten) und dann zählt wie oft dieses Zeichen in der Zeichenkette vorkommt. Hier gibt es zwei Teilaufgaben:
    a.) Mit Hilfe des Index
    b.) Mit Hilfe eines Pointers

    Hier mal mein Code, soweit bin ich und das funktioniert auch:

    #include <stdio.h>
    #include <string.h>
    #include <Windows.h>
    
    void main()
    {
    	char wort[50], buchstabe[2];
    
    	printf("Bitte ein Wort eingeben: ");
    	scanf("%s", &wort);
    
    	printf("\nBitte einen Buchstaben eingeben: ");
    	scanf("%s", &buchstabe);
    
    	system("PAUSE");
    }
    

    Jetzt komme ich einfach nicht weiter...
    Dachte an eine for-schleife? Aber bin echt planlos sitz nun schon eine ganze Weile davor..
    MfG und Danke schonmal.



  • Erstmal sollst du den einzelnen Buchstaben nicht in ein char-Array, sondern in ein char einlesen. Der Typ muss für buchstabe also char sein, und der format specifier für scanf %c.

    Eine for-Schleife ist schon mal eine gute Idee (die Pointer-Variante geht aber auch prima mit einer while-Schleife, aber das später). Sie sollte über alle Elemente von wort laufen und jedes einzelne Element mit buchstabe vergleichen. Versuch das erst mal und poste deinen Versuch inkl. Frage, falls du nicht weiterkommst.



  • Danke schonmal für die Antwort, werds sofort probieren, aber ich kann kein char mit scanf einlesen, wenn ich als Beispiel folgendes eingeb:
    [code="c"]
    scanf("%c", &buchstabe);
    [code="cs"]
    ignoriert das der Compiler einfach, so hatte ichs davor nämlich schon probiert.
    MfG


  • Mod

    Computer ignorieren nichts. Zeig mal das vollständige Programm, welches nicht funktioniert und sag genau was du machst, was du meinst, was passieren sollte und was stattdessen passiert.

    P.S.: Das ist übrigens kein C#, sondern C, aber du bist (unabsichtlich?) im richtigen Forum dafür gelandet. C und C# haben nur eine ähnliche Syntax und einen ähnlichen Namen, ansonsten haben sie nichts gemeinsam.

    P.P.S.: Außerdem sollte dein Formatstring " %c" lauten (mit Leerzeichen), ansonsten wird das Trennzeichen nach dem Ende des Wortes als Buchstabe genommen (also vermutlich ein Zeilenumbruch oder ein Leerzeichen).



  • Oh sorry, das tut mir leid, natürlich ist das C und nicht C# 🙄

    Ähm, ja ich gebe den gleichen Code wie oben ein, bis auf diese Zeile, sprich so:

    #include <stdio.h> 
    #include <string.h> 
    #include <Windows.h> 
    
    void main() 
    { 
        char wort[50], buchstabe; 
    
        printf("Bitte ein Wort eingeben: "); 
        scanf("%s", &wort); 
    
        printf("\nBitte einen Buchstaben eingeben: "); 
        scanf("%c", &buchstabe); 
    
        system("PAUSE"); 
    }
    

    Ich will ein einzelnes Zeichen einlesen und das unter der Variablen buchstabe speichern, aber das macht er nicht.
    Da kommt "Bitte einen Buchstaben eingeben: " und dann springt er ans Ende.
    MfG

    Edit:
    Ich komm mir grad ziemlich dumm vor, da ich ja schon des öfteren ein einzelnes Zeichen so eingelesen habe, aber irgendwie will er nicht..?!

    Edit2:
    Wenn ich, wie von SeppJ gesagt, " %c" schreibe, funktioniert es, aber den Grund habe ich nicht richtig verstanden?

    MfG



  • Du hast das Leerzeichen vor dem %c vergessen.
    Und in ZEile 10 gehört kein & vor wort, da es ein Array ist.



  • Also Jungs, Teilaufgabe a.) hab ich geschafft.
    Siehe Code:

    #include <stdio.h>
    #include <string.h>
    #include <Windows.h>
    
    void main()
    {
    	char wort[50];
    	char buchstabe;
    	int i, anzahl=0;
    
    	printf("Bitte ein Wort eingeben: ");
    	scanf("%s", wort);
    
    	printf("\nBitte einen Buchstaben eingeben: ");
    	scanf(" %c",&buchstabe);
    
    	for (i = 0; i<50; i++)
    	{
    		if (wort[i] == buchstabe)
    			anzahl = anzahl+1;
    	}
    	printf("\nDer Buchstabe %c kommt im Wort %d mal vor.\n", buchstabe, anzahl);
    
    	system("PAUSE");
    }
    

    Vielen Dank für eure Hilfe bis hier hin.
    Jetzt zur Teilaufgabe b.) Mit Hilfe eines Pointers.
    Könnt ihr mir ein Denkantritt geben?
    MfG



  • Ups, zu langsam.

    Benjoo #1 schrieb:

    Edit2:
    Wenn ich, wie von SeppJ gesagt, " %c" schreibe, funktioniert es, aber den Grund habe ich nicht richtig verstanden?

    Das was du da scanf als ersten Parameter übergibst ist der Formatstring.
    Daran erkennt scanf was für Eingaben du erwartest.
    Das Leerzeichen bedeutet: Überlese alle Whitespace (Leerzeichen, Tabulatoren Newline, CarriageReturn).

    Warum ist das nötig? Von der Eingabe für wort bleibt die Entertaste noch im Eingabestrom stehen. Die wird von scanf nicht eingelesen.

    Normalerweise überliest scanf die Whitespace auch, aber gerade nicht bei %c, denn du könntest ja genau die Taste einlesen wollen.

    Es gibt noch andere Funktionen zum einlesen. Z.B: getchar


  • Mod

    Benjoo #1 schrieb:

    Könnt ihr mir ein Denkantritt geben?

    Was weißt du denn alles über Pointerarithmetik? Du brauchst nicht viel. Falls du nichts darüber weißt, hast du nun ein Stichwort.

    Dein Programm ist übrigens falsch. Was passiert denn, wenn das Wort weniger als 50 Zeichen hat? Du hast bloß Pech, dass dein Programm bei deinen Testfällen zufällig funktioniert hat, daher hast du den Fehler nicht bemerkt.



  • Das Ende eines Strings erkennt man an dem '\n' Zeichen.
    Stell mal deine for-Schleife darauf um.

    Für b) brauchst du erstmal einen Zeiger, der auf wort zeigt.

    Solange das Zeichen auf das der Zeiger zeigt != '\0' ist kannst du weiter machen.
    Am Ende der Schleife musst da dann noch den Zeiger weiterzählen.

    Lösung gibt es nicht, nur Verbesserungen 😉


  • Mod

    DirkB meint übrigens '\0', nicht '\n'.



  • Hmm, ich weiß nicht so Recht wie ich das verbessern soll, eigentlich wollte ich auch nicht 50 reinschreiben, sondern das so machen, dass das Array immer die Anzahl der Elemente hat, wie lang das Wort nun ist, bzw. ein Element mehr. Wusste aber nicht wie das geht.

    Wenns um Pointer geht bin ich noch nicht soo fit.. Bin gerade ziemlich Ahnungslos..
    MfG



  • Na irgend etwas wirst du ja schon von Zeigern gehört haben.

    Weißt du wie man an die Adresse einer Variablen kommt?
    Weißt du wie man an den Wert kommt, auf den der Zeiger zeigt?



  • Ja die Adresse einer Variablen bekomme ich durch &, wenn ich mich richtig erinnere.
    Bsp. &s liefert die Adresse der Variablen s.
    Richtig soweit?



  • Im Prinzip ja.
    Und wie kommst du an den Inhalt an der Adresse?



  • Ja wenn ich einen Zeiger habe namens Bsp. ptr_a mache ich:
    *prt_a = &s;
    y = *ptr_a;
    Wenn jetzt s=4 ist, zeigt ptr_a auf 4 und y wird der Wert zugewiesen.


  • Mod

    Soweit so gut. Jetzt noch der große Trick:

    int foo[2] = {1,2};
    int *ptr = &foo[0];
    ptr = ptr + 1;
    int y = *ptr;
    // Welchen Wert hat y?
    


  • 2? bzw. foo[1]


  • Mod

    Benjoo #1 schrieb:

    2? bzw. foo[1]

    Genau. Und mit diesen drei Zutaten (Adressoperator, Addition von Zahlen zu Pointern und '\0' als Ende von Zeichenketten), die DirkB und ich dir gezeigt haben, fällt dir da eine Möglichkeit ein, mittels eines Pointers zeichenweise durch eine Zeichenkette zu laufen?



  • Hmm, ich steh total aufm Schlauch momentan... 😕



  • Erst nochmal mit Array:

    for (i = 0; wort[i] != '\0'; i++)  // i<50 ersetzt.
        {
            if (wort[i] == buchstabe)
                anzahl = anzahl+1;
        }
    

    Du brauchst einen Zeiger auf das Array

    char *p; 
    ... 
    p = wort; // bei eienem Array kein &
    

    Beim Vergleich greifst du dann auf das Element mit * zu:

    *p != '\0';
    

    Und dann musst du noch den Zeiger weiterzählen

    p++
    

    Dann schaust du mal wo das oben hinpassen könnte. (das i brauchst du dann nicht mehr)


Anmelden zum Antworten