C: Wörter, Zeichen, und Zeilen zählen

lordosiris

Mitglied
Hallo,

ich möchte ein Programm schreiben, welches ein Textfile öffnet, alle Chars, Lines und Words zählt.
Geöffnet wird die Datei mit fopen, mit fgetc werden alle Zeichen durchgegangen. Der Chars Counter wird dabei jedes mal erhöht, sollt es zufällig \n sein, wird der Lines Counter auch erhöht.
Beim Word Counter hab ich momentan noch so meine Probleme. Momentan habe ich das mit isspace() realisiert, allerdings zählt der beispielsweise Zahlen auch als Wörter mit. ("Ich bin Hans und bin 8 Jahre alt." Wären 8 Words).

Hier der wichtigste Teil meines C Codes:
C:
do {
n = fgetc (pFile); //in pFile ist das Textfile geöffnet)
c++; //chars
if (n == '\n') l++; //lines
if (isspace(n)) w++; //words
} while (n != EOF);

Wie kann ich das hübscher/besser/effektiver regeln?
 
Zuletzt bearbeitet von einem Moderator:
Hi und Willkommen bei tutorials.de,

Mehrere Leerzeichen hintereinander werden bei dir als mehrere Wörter gezählt.
Da könnte man zB. eine Variable machen, die 1 oder 0 ist,
je nachdem, ob man gerade "in" einem Wort ist.
Auf diese Weise kann man dann auch zeichenweise prüfen, ob es ein gültiges Wort ist.

Fälle, die unterschieden werden müssen:
In einem Wort/nicht
Aktuelles Zeichen ist Buchstabe/Space/Anderes

C++:
char imwort = 0;
do {
    n = fgetc (pFile); //in pFile ist das Textfile geöffnet)
    c++; //chars
    if (n == '\n') l++; //lines

    if(!imwort) //Gerade kein Wort
    {
         if(isalpha(n)) //n ist ein Buchstabe
         {
              w++; //Als Wort(beginn) zählen
              imwort = 1;
         }

         else if(!isspace(n)) //Kein Buchstabe, kein Space
              imwort = 1; //Etwas beginnt, aber es wird nicht gezählt

         //Space brauchen keine Behandlung, wenn man sowieso außerhalb eines Wortes ist
    }

    else //in einem Wort
    {
         if(isspace(n)) //Space beendet das Wort
              imwort = 0;

         else if(!isalpha(n)) //Kein Buchstabe, kein Space, aber im Wort: Irgendwas wie w23x89
         {
              w--; //Wurde beim Anfangsbuchstaben gezählt, ist aber doch kein Wort
         }

         //Buchstaben im Wort brauchen keine Behandlung
    }

} while (n != EOF);

Ich würde mir wegen dem Wortzählen aber keine keine großen Umstände machen,
sogar MS Word zählt Zahlen als Wort :D

Gruß

PS: Bei den Codetags gehört ein / statt \
Habs ausgebessert.
 
Ich würde mir wegen dem Wortzählen aber keine keine großen Umstände machen,
sogar MS Word zählt Zahlen als Wort :D

Wenn das so ist, glaub ich werd ich das auch so stehen lassen!

Ich schau mir auf jeden Fall deinen Code noch genauer an, zum Zwecke des Verständnisses.
Das verschiebe ich aber glaube ich auf morgen, um die Uhrzeit seh ich vor lauter Bäumen den Wald nichtmehr!

Danke schonmal für die sehr rasche Antwort!
 
Okay, also folgendes.

Ich hab mein Programm jetzt etwas erweitert.

Und zwar um die Möglichkeit, einen Suchstring per Parameter einzugeben, welcher in den Files gesucht wird.

Jetzt bin ich schon soweit, dass ich die Files jeweils öffne (ist ja auch keine große Kunst), aber wie ich in den Files jetzt nach dem Suchstring suche und ggf. ausgebe: Ja, in dem eben geöffneten File befindet sich der Suchstring - dafür hab ich absolut keinen Lösungsweg.

Ob mit fgetc, fgets, etc.. Ich google mich dumm und dämlich, aber ich raffs einfach nicht, wie ich die Wörter in der Datei mit dem Suchstring vergleichen soll.

Hat da jemand einen Lösungsansatz?

Vielen Dank
 
Hallo

So vielleicht?
C:
char Suchstring[512];
fgets(Suchstring, 512, STDIN);
FILE* f = fopen("Datei.txt","r");
if(f == NULL) return -1;
char temp[512]; //Wenn die Datei Zeilen hat, die länger als 512 Zeichen sind, erweitern
while(fgets(temp,512,f) != NULL)
{
     if(strstr(temp,Suchstring) != NULL) //Treffer
     {
          printf("Treffer in dieser Zeile: %s",temp);
     }
}
fclose(f);

Ungetestet.


cwriter
 
Danke schön für den Vorschlag schonmal.

Ich poste jetzt einfach mal meinen momentanen Code:

C:
while ((zeile=readdir(verzeichnis)) != NULL){
			printf("Folgende Datei wird durchsucht: %s\n", (*zeile).d_name);
			pFile = fopen("zeile","r");
			while (fgets(compare,512,pFile)!=NULL){
				if (strstr(compare,Suchstring) != NULL){
					printf("Treffer in dieser Datei!");
				}
			}
			n++;
			fclose(pFile);
		}

Vorher öffnet er das momentane Verzeichnis.
Solange zeile ungleich Null ist, also solange noch Dateien im Verzeichnis unbearbeitet sind, gibt er erstmal aus, welche Datei er momentan durchsucht. (Ist nur für mich eine kleine Kontrolle).
Danach öffnet er die Datei, die zeile gerade anzeigt. Solange fgets in der Variable compare noch 512 Zeichen aus dem File pFile bekommt, kontrolliert er per strstr den Inhalt der beiden Variablen compare und Suchstring. Sollten die gleich sein, somit ungleich Null, wird "Treffer.." ausgegeben,. Dann wird noch ein Counter erhöht (nur zur Kontrolle) und das File wieder geschlossen.

Funktionieren tut das trotzdem nicht.

Er kompiliert zwar einwandfrei, wenn ich das Skript allerdings in einem Verzeichnis nach "Josef" suchen lasse, wobei ich genau weiß, dass es ein Txt File gibt, in welchem Josef steht, dann passiert einfach nichts. Mit Ctrl + C kann ich dann den Auftrag abbrechen.

Vorschläge?
 
Erster Fehler:
C++:
pFile = fopen("zeile","r");
muss heißen
C++:
pFile = fopen(zeile,"r");

Sollte deswegen aber nicht endlos warten...hm...

ah:
readdir git keinen String zurück
Da sollte der Compiler aber warnen...
 
Danke für den Hinweis.

Ich hatte zeile sogar anfangs so drinnen stehen, allerdings hat mir der Compiler dabei immer einen Fehler rausgehauen.

Code:
search.c:23:4: Warnung: Übergabe des Arguments 1 von »fopen« von inkompatiblem Zeigertyp [standardmäßig aktiviert]

Jetzt ist mir schon aufgefallen, warum er wartet.

Ich hab fgets(Suchstring,512,STDIN); drinnen stehen. Ergo wartet er natürlich auf die Tastatureingabe.

Wenn ich das mit fgets(Suchstring,512,argv[1]); austausche, kommt eine ähnliche Kompilerfehlermeldung.

E:/ ignoriere ich die Fehler und starte das Programm, kommt es nun zur sofortigen Beendung mit dem Hinweis "Speicherzugriffsfehler".

C ist leider Neuland für mich und muss mir jetzt sehr kurzfristig relativ viel Stoff anschauen.
 
@sheel
readdir() gibt einen String zurück? Ohne an deiner Kompetenz zu zweifeln:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/readdir.html
Ich glaube, es müsste das sein:
C:
pFile = fopen((*zeile).d_name,"r");
Und abstürzen tut es, weil keine Überprüfung da ist, ob die Datei geöffnet werden kann.
C:
if(pFile == NULL)

cwriter

/EDIT: Zu deinem Post: fgets() liest eine Datei, keinen char* []. So sollte es besser gehen:
C:
//Zuerst überprüfen:
if(argc < 3) return;
char Suchstring[512];
strcpy(Suchstring,argv[1]);
 
Zuletzt bearbeitet:
Zum fgets:
Der dritte Parameter muss pFile sein, nicht der Dateiname.

readdir:
Gibt nicht direkt den String zurück (http://linux.die.net/man/3/readdir)
Mach sowas:
C++:
struct dirent *dateiname;
...
while ((dateiname=readdir(verzeichnis)) != NULL){
...
pFile = fopen(dateiname->d_name, "r");

Bzw, was ist die Variable verzeichnis?
Ein String oder DIR?

@cwriter: Oh...das sollte heißen keinen String :D
Einen String hatte er ja schon vorher...
 
Zurück