Anzahl von einem String in einem anderen String
-
Ich soll ein Programm schreiben, dass zählt wieoft ein String in einem anderen String enthalten ist.
Ich bin bis jetzt soweit gekommen:
// Zählt Vorkommen von einem String in einem anderen #include <stdio.h> #include <string.h> int main(void) { int result = 0, count = 0; char quelle[160]; char suche[160]; char *location; // EINGABE puts("Geben Sie bitte den String ein, der durchsucht werden soll: "); gets(quelle); puts("Geben Sie bitte den zu suchenden Begriff ein: "); gets(suche); // BERECHNUNG while ( 1 ) { location = strstr((quelle+count), suche); count += (location-quelle); if ( location != NULL ) result++; else break; } // AUSGABE printf("\"%s\" wurde %d mal gefunden", suche, result); return 0; }
Das funktioniert auch soweit ABER:
- Wenn ein Wort nur einmal vorkommt wird trotzdem 2 mal angezeigt. Daher stimmt die Anzeige erst wenn das Wort tatsächlich 2 mal vorkommt.
- Wenn der Suchbegriff dem ersten Wort des Strings entspricht hängt sich das Programm auf (kommt irgendwie nicht mehr aus der Schleife raus).Ich habe viel rumprobiert, doch konnte das Problem leider nicht lösen.
-
Die Rumrechnerei in der Endlosschleife ist mir irgendwie suspekt. Sie ist v.a. auch total unnötig. Ich würde das z.B. so machen:
while( (temp = strstr(temp, suche)) ){ result++; temp++; }
-
Ich habe temp jetzt als char-Zeiger definiert und die Schleife übernommen.
Doch das zählen klappt immernoch nicht richtig.
-
Simonek schrieb:
Doch das zählen klappt immernoch nicht richtig.
Was klappt genau noch nicht richtig?
PS: Die [cpp]-Tags sind schöner als die öden [code]-Tags.
Edit: Und gets() solltest du gar nicht nehmen. Nimm man: fgets.
-
Es zeigt immer nur 1 mal an egal ob es garnicht oder mehrmals vorkommt.
P.S. Warum soll ich fgets verwenden?
Sorry bin noch Anfänger...
-
Zeig nochmal den ganzen Code. Ich glaube du hast da was beim einbauen der Schleife übersehen.
Zu gets(): gets() ist böse, weil man ihr (der Funktion) keine Angabe über die Länge/Größe des Zielpuffers mitgeben/übergeben kann. Deshalb liest gets() so lange von stdin (Standardeingabe, also idR die Tastatur) bis ein Enter kommt. Da kann es passieren, dass der eingelesene String länger ist als der Zielpuffer selbst und das Programm schreibt über die Grenzen des reservierten Speichers hinaus. Diesen Effekt nennt man "Buffer-Overflow". fgets() kann man die Größe des Zielpuffers übergeben, somit besteht da das Problem (bei fachgerechter Nutzung) nicht.
-
Ich habe einfach meine Schleife durch Deine ersetzt und einen Zeiger *temp deklatiert und mit quelle initialisiert.
So sieht das jetzt aus:
// Zählt Vorkommen von einem String in einem anderen #include <stdio.h> #include <string.h> int main(void) { int result = 0, count = 0; char quelle[160]; char suche[160]; char *temp; // Deklarierung temp = quelle; // Initialisierung // EINGABE puts("Geben Sie bitte den String ein, der durchsucht werden soll: "); fgets(quelle, 159, stdin); puts("Geben Sie bitte den zu suchenden Begriff ein: "); fgets(suche, 159, stdin); /* DEAKTIVIERT while ( 1 ) { location = strstr((quelle+count), suche); count += (temp-quelle); if ( temp != NULL ) result++; else break; } ENDE DEAKTIVIERT */ // BERECHNUNG while( (temp = strstr(temp, suche)) ) { result++; temp++; } // AUSGABE printf("\"%s\" wurde %d mal gefunden", suche, result); return 0; }
-
Ah sorry, da hab ich was nicht bedacht. Bei einem normalen Aufruf von fgets() wird das '\n' im String mitgespeichert, deswegen findet er auch den Suchstring praktisch nicht, ausser wenn der Suchstring direkt am Ende des Quellstrings liegt (oder natürlich exakt dieser ist). Das '\n' entfernen macht man am besten mit der Funktion strchr(), kannst ja mal selber hirnen
-
Ich habe das '\n'-Zeichen entfernt und es klappt wunderbar.
Hier der fertige Code:// Zählt Vorkommen von einem String in einem anderen #include <stdio.h> #include <string.h> int main(void) { int result = 0; // Für die Anzahl der Vorkommen char quelle[160]; // Quellstring char suche[160]; // Suchstring char nsuche[160]; // Suchstring ohne '\n' char *nullzeichen; // Ermittelt Position von '\n' int position = 0; // Position von '\n' im Suchstring char *temp; // Deklarierung temp = quelle; // Initialisierung // EINGABE puts("Geben Sie bitte den String ein, der durchsucht werden soll: "); fgets(quelle, 159, stdin); puts("Geben Sie bitte den zu suchenden Begriff ein: "); fgets(suche, 159, stdin); // '\n' im Suchstring entfernen nullzeichen = strchr(suche, '\n'); position = nullzeichen-suche; strncpy(nsuche, suche, position); // BERECHNUNG while( (temp = strstr(temp, nsuche)) ) { result++; temp++; } // AUSGABE printf("\nDer Begriff \"%s\" wurde %d mal gefunden\n", nsuche, result); return 0; }
Vielen Dank für die Hilfe!!
:xmas1:
-
Bei fgets() sollst du schon die echte Länge des Arrays übergeben, nicht länge-1. Die Funktion "denkt" von selbst an die '\0'. Aber tröste dich, das machen fast alle Anfänger falsch
Und die Rumrechnerei und Stringkopiererei beim entfernen des '\n' ist auch unnötig. Ein einfaches
if ( (nullzeichen = strchr(suche, '\n')) ){ *nullzeichen = '\0'; }
hätte auch gereicht.
:xmas1:
-
Hi
Ich mach das immer so:array[strlen(array)]='\0'
Ist das so auch gut, oder überseh ich da was?
-
Jay schrieb:
Hi
Ich mach das immer so:array[strlen(array)]='\0'
Ist das so auch gut, oder überseh ich da was?
ja, das ist schon 0
:xmas2:
-
Mal davon abgesehen, dass das array[strlen(array)] Element eigentlich per Definition schon eine '\0' ist kannst du dir bei fgets() nie sicher sein, dass wirklich ein '\n' hinten drankelebt (im gegensatz zur '\0', die ist sicher).
-
Ok danke euch. Sonst hät ich das noch die nächsten 10 Jahre so geschrieben
-
Jay schrieb:
Ok danke euch. Sonst hät ich das noch die nächsten 10 Jahre so geschrieben
einem schlauen compiler hätte das nix ausgemacht. hättest vielleicht ein warning gesehen, wie 'removed dead code'
-
char *last = string + strlen(string)-1; if(*last == '\n') *last = 0;