arrayscfile-length

How to obtain the length of a file


I am trying to run a simple C program that takes a file of random floating point values, automatically identify the length of the file and use the length to perform further computation. However, my compiler either hangs or I get erroneous results. Here is my code

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

int main() {
  FILE *fptr;
  int count = 0; // Line counter (result)
  char ch; // To store a character read from file

  if ((fptr = fopen("C:\\Users\\Evandovich\\Desktop\\White_Noise.txt", "r"))
      == NULL) {
    printf("Error! opening file");
    // Program exits if the file pointer returns NULL.
    exit(1);
  }

  // Extract characters from file and store in character ch
  for (ch = getc(fptr); ch != EOF; ch = getc(fptr)) {
    if (ch == '\n') // Increment count if this character is newline
      count = count + 1;
  }
  printf("The file has %d lines\n ", count);

  // use the value of "count" to be the length of the array.
  char arrayNum[count];
  char *eptr;
  double result, result1[count];

  for (int i = 0; i < count; i++) {
    fscanf(fptr, "%s", &arrayNum[i]);

    /* Convert the provided value to a double */
    result = strtod(&arrayNum[i], &eptr);
    result1[i] = pow(result, 2);
    printf("value %f\n", result1[i]);
  }

  fclose(fptr);
  return 0;
}

What particularly is the error? Your input is well appreciated.

INPUT file (N.txt) contains

0.137726
0.390126
-0.883234
0.006154
-0.170388
-1.651212
0.510328

OUTPUT The file has 7 files

value 0.000000
value 0.000000
value 0.000000
value 0.000000
value 0.000000
value 0.000000
value 0.000000

Expected The file has 7 files

value 0.018968
value 0.152198
value 0.780102
value 0.000038
value 0.029032
value 2.726501
value 0.260435

Solution

  • At least these problems:

    At end of file

    Code fails as it attempts to read the floating point text from the end of the file. @ErlingHaaland

    After determining line count, add:

     rewind(fptr);
    

    Convoluted read

    Read a line with fgets(). Avoid "%s" without a width limit - it might overflow. Use a line buffer that is based on max line length, not line count. Convert to a double by starting at the begining of the line.

    #define LINE_SIZE 100
    char arrayNum[LINE_SIZE];
    if (fgets(arrayNum, sizeof arrayNum, fptr) == NULL) {
      break;
    }
    result = strtod(arrayNum, &eptr);
    

    Check conversion

    errno = 0;
    result = strtod(arrayNum, &eptr);
    if (arrayNum == eptr || errno) {
      break;
    }
    

    Too small a type

    int getc(FILE *) typically returns 257 different values: EOF and [0...UCHAR_MAX]. Saving that in a char loses information. Save in an int.

    Line count at risk

    May be off by 1 as the last line might not have a '\n': @Adrian McCarthy.

    Instead count line beginnings.

    size_t count = 0;
    int previous = '\n';
    int ch;
    
    while ((ch = getc(fptr) != EOF) {
      if (previous == '\n') {
        count++;
      }
      previous = ch;
    }
    printf("The file has %zu lines.\n ", count);
    
    // Also
    rewind(fptr);