Home > Net >  How to obtain the length of a file
How to obtain the length of a file

Time:01-07

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

CodePudding user response:

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);

CodePudding user response:

A couple problems:

  1. getc returns the value of the next char as an int or the special value EOF. Since your variable ch is a char, the EOF value may not be recognizable in which case the line counting loop might never end.

  2. You define arrays whose size is determined by a run time variable count. I use C regularly, but I have written in C in a very long time. When I did write in C, the size of arrays had to be determined at compile time. Perhaps this is a newer feature of C? I'd check. Make sure you have compiler warnings enabled.

  3. count might be short one line if the last line of the file doesn't end with '\n'. On Posix systems, a line is supposed to end with a newline character. On Windows, it's common for the newline sequence (typically CR LF) to be treated as a line separator. Thus files may or may not end with the newline sequence at the end of the last line.

  4. arrayNum is an array of count characters rather than an array of pointers to character strings.

  • Related