0

I just found this thread with the same question but in C#.
How do you achieve this in C? Is there a better solution than using a loop until it reaches EOF like this or is there already a function in the libs which can do this?

#include <stdio.h>
#include <stdlib.h>

// ----- Macros -----
#define PATHSIZE 255
#define BUFFERPATHSIZE PATHSIZE + 1

// ----- Functions -----
short get_amount_of_lines_of_file(char * path);

// -----======##### CODDE #####=====-----
int main() {

    char buffer[PATHSIZE];
    fgets(buffer, BUFFERPATHSIZE, stdin);

    printf("%d\n", get_amount_of_lines_of_file(buffer));

    return EXIT_SUCCESS;
}

short get_amount_of_lines_of_file(char * path) {
    /*
     * This will return the amount of lines of a file.
     * ----- Variables -----
     * lines: The counter of the lines
     * 
     * ----- Return -----
     * -1: Couldn't open file
     * lines: The amount of lines 
     */

    FILE *file;
    int rofl;
    short lines = 0;

    if ((file = fopen(path, "r")) != NULL) {

        while ((rofl = getc(file)) != EOF) 
            lines++;

        return lines;
    }

    return EXIT_FAILURE;
}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
TornaxO7
  • 1,150
  • 9
  • 24
  • 2
    The most efficient way is to `mmap` the file and use `strchr` in a loop to count the lines. It is _much_ more efficient. See my answer: https://stackoverflow.com/questions/33616284/read-line-by-line-in-the-most-efficient-way-platform-specific/33620968#33620968 – Craig Estey Apr 11 '20 at 20:17
  • You are counting 1 line for every character. Add some more code (and some braces) to count the newlines. `if(rofl == '\n') lines++;` – Weather Vane Apr 11 '20 at 20:17
  • @CraigEstey I wouldn't really suggest `mmap`ing the entire file without checking the size like you are doing in your other answer. It's a pretty bad idea and I'm sure you can see why. – Marco Bonelli Apr 11 '20 at 20:21

1 Answers1

0

if you want to be fast, and if your memory is large enough, you can read in the entire file, and parse to to get the newline counts, try this: compile with gcc -g wc1.c -O3 -o wc1:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __OSX__
   #define NLINE '\r'
#else
   #define NLINE '\n'
#endif
void main(int argn, char **argv){
  if(argn<2) return;
  FILE *fp=fopen(argv[1],"rb");
  int count=0;
  size_t flen;
  char *nb,*body;

  fseek(fp,0,SEEK_END);
  flen=ftell(fp);
  body=(char*)calloc(1,flen+1);
  fseek(fp,0,SEEK_SET);
  if(fread(body,flen,1,fp)!=1){
    fclose(fp);
    exit(-1);
  }
  fclose(fp);
  nb=body;
  while(nb=strchr(nb,NLINE)){
      count++;
      nb++;
  }
  free(body);
  printf("filename %s: line count %d\n",argv[1],count);
}

alternatively, you can also set a maximum line width and call fgets to read line by line, try this: gcc -g wc2.c -O3 -o wc2

#include <stdio.h>
#define MAX_LINE_LENGTH 4096

void main(int argn, char **argv){
  if(argn<2) return;
  FILE *fp=fopen(argv[1],"rt");
  int count=0;
  char line[MAX_LINE_LENGTH];
  while(!feof(fp)){
      if(fgets(line,MAX_LINE_LENGTH,fp))
         count++;
  }
  fclose(fp);
  printf("filename %s: line count %d\n",argv[1],count);
}
FangQ
  • 1,444
  • 10
  • 18