C -> Zeilen in Datei zählen

Servusla,
iiiich bräuchte:
eine funktion, das eine datei einliest, die zeilen zählt und wieder ausspuckt.
woran ich dachte:

[quote]
int count(char *filename) {
int counter = -1;

FILE *file = fopen(filename, “r”);
if(file != NULL) {
counter++;
while(fscanf(file, “%s\n”) != EOF) counter++;
} else {
printf(“Datei nicht vorhanden.\n”);
}
fclose(file);
return counter;
}[/quote]

haut das so hin? ich kann grade nicht kompilieren, und muss “trocken” schreiben…

zumindest mal so von der logik her. oder gibts da vllt schon iwelche vorgefertigten funktionen oder so?

fgets() liest genau eine Zeile ein, aber du kannst das ganze auch problemlos mit fgetc() machen.

#define BETWEEN(x, a,b) (x >= a && x <= b)

int count(FILE* file, unsigned int* lines, unsigned int* words, unsigned int* chars)
{
  char c = 0;

  fseek(file, 0, SEEK_SET); //Dateizeiger auf Anfang setzen
  
  do
  {
    if(c == '\r')
    {
      ++*lines;
      c = fgetc(file);
      if(c == '\n')
         c = fgetc(file);
    }
    else if(c == '\n')
    {
      ++*lines;
      c = fgetc(file);
    }
    else if(BETWEEN(c, 'a', 'z') || BETWEEN(c, 'A', 'Z') || BETWEEN(c, '0', '9'))
    {
      c = fgetc(file);
      if(c == '\r' || c == '\n' || c == ' ')
        ++*words;
    }
    else
      c = fgetc(file);
    
    ++*chars;
  } while(!feof(file))
  
  return 0;
}

Da müsste noch Fehlerbehandlung rein und so… C ist so hässlich, in C++ wär das viel angenehmer :ps:

PS: Die Funktion ist bei weitem nicht perfekt, der chars-Zähler zählt immer eins zu viel und das letzte Zeichen wird nicht ausgewertet. Das musst du aber selbst lösen, wenn du die Funktion verwenden solltest.

um gottes willen das is wie die sprichwörtliche bazooka auf die fliege :ps:

nur die zeilen in einer datei zählen…

fgets hab ich mir schon angesehn, allerdings will die funktion folgende parameter:

char *fgets(char *s, int length, FILE *fp);

s is klar - kann hier gerne ins leere laufen oder wohin auch immer, fp, filepointer auch klar, aber length - ich weiß nicht wie lang eine zeile in der datei is, uu auch unterschiedlich lang…

Da geht es um die Länge des Buffers, damit da nicht zu viel geschrieben wird :wink:

oh mann… das erklärt einiges…
gut, dann werd ichs so machen. ähm nur mal theoretisch, ein formatierter scan, würde der auch funktioniern?

was ist ein formatierter Scan?

printf übergibt man ja zb ("%s blablabla %d", mein_string, meine_zahl)
der formatiert das dann alles zusammen und gibts aus.
das ganze geht auch andersrum, also einlesen -> scanf
dann entsprechen fprintf und fscanf

ich dachte ich lese den formatierten String “%s\n” ein - müsste eine zeile sein. das kann man fast mit regex vergleichen:
\n
steht für eine zeile, mit \n am ende…

soweit die theorie xD

jo… aber dann soweit ers ma danke, hast mir verry geholfen :stuck_out_tongue:

Bei fscanf musst du auch buffer in der richtigen Größe spezifizieren. zeichenweises lesen ist die beste Lösung. Per fgets geht es aber auch (Prüfe, ob das letzte Zeichen im Buffer eine neue Zeile ist, dann Zeilenzahl erhöhen, ansonsten nicht)

es kommt doch auf die größe an, wa?.. spaß beiseite, wo muss ich da die buffer-größe angeben? steht nix von im prototyp…

Du musst dir schon die Doku ansehen, z.B. funktioniert das so:

Der Stringbuffer muss groß genug sein, um den ganzen String aufzunehmen (+ nullchar). Daher solltest du bei %s immer eine Länge angeben (%#s)

ach so meinst du das

lösung - für alle dies intressiert

jo, habe heute das thema noch mal aufgegriffen. nach relativ langem rumexperimentieren habe ich den formatieren scan gelassen, da man dazu die länge der zeilen wissen müsste (wegen dem puffer).
herausgekommen ist folgende lösung:

#include <stdio.h>

void main(void) {
  FILE *file = fopen("/home/stefan/Desktop/test.txt", "r");
  int counter = -1;
  if(file != NULL) {
    char c = 0;
    counter++;
    while((c = fgetc(file)) != EOF)
      if(c == '\n')
        counter++;
    printf("counter: %d", counter);
  } else printf("file ist NULL.\n");
  fclose(file);
}