Print struct data with read values from a text file in C

Asked

Viewed 250 times

4

I’m trying to make a simple program to read data from a text file, store it in a struct, and print that data on the screen. The code I have is this::

#include <stdio.h>

#define max 70

typedef struct
{
  int BI;
  float altura;
  int peso;
}PESSOA;

int main()
{
  PESSOA data[max];
  FILE *f;
  int N=0;
  f=fopen("dados2.txt", "r");
  if(f==NULL)
  {
    printf("Não foi possível abrir o arquivo.\n");
    return 0;
  }
  while(feof(f)!=0)
  {
    fscanf(f, "%d", &data[N].BI);
    fscanf(f, "%f", &data[N].altura);
    fscanf(f, "%d", &data[N].peso);
    printf("%d \n", data[N].BI);
    printf("%.2f \n", data[N].altura);
    printf("%d \n", data[N].peso);
    printf("\n");
    N++;
  }
  fclose(f);
  return 0;
}

The text file has the following format (repeated 65 times):

BI
Altura
Peso

Example:

9914241  
1.55
99
1171804
1.80
63
1796075
1.64
85

The problem is that when I run the program nothing appears on the screen. Can someone tell me what I’m doing wrong?

2 answers

5


There is a problem in using feof this way. For example, if the file has a blank line at the end:

1 2.2 3


The while will read the numbers twice and the output will be something like:

1
2.20
3

32577
-1363474432.00
32577

The last 3 numbers may vary with each execution (see in the Repl.it for example, with each run the numbers change).

If you want an explanation well more detailed, you can see here and here. But basically, feof checks the end-of-file Indicator, not the file itself. And who arrow the end-of-file Indicator is another function (in this case, one of those responsible for reading).

Since the file does not end after the first line, end-of-file Indicator it’s not set yet, so feof still indicates that it did not reach the end of the file (and in fact did not arrive at all). Only after the fscanf try to read the next line it will be indicated that the file has reached the end, but by then it will be too late.

Similar situation occurs if the file is empty: feof does not know that the file is empty because the end-of-file Indicator has not yet been set (only after you try to read with fscanf, it will be checked that it is empty), then it enters the loop once and will be printed the "garbage".


A more reliable way is to check the return of fscanf, which is the amount of arguments that have been correctly read. Then just read all the numbers at once and check if the return is 3. So you ensure that it will only print when in fact all the values have been correctly read (otherwise the loop is closed):

while (fscanf(f, "%d%f%d", &data[N].BI, &data[N].altura, &data[N].peso) == 3) {
    printf("%d\n%.2f\n%d\n\n", data[N].BI, data[N].altura, data[N].peso);
    N++;
}

See here the difference. Note that in this case the loop will be closed when he cannot read the 3 numbers, that is, even if he has not reached the end of the file, but one of the lines has no numbers (and has a text, for example), the while will be interrupted.

2

The problem is in using the function feof, more specifically in the comparison of their return.

The function feof returns 0 when the file is not in eof, and different than 0 when the file is in eof.


With this, to fix your code, just change the condition of your while, may be as follows:

while(!feof(f))

You could also reverse your comparison by checking if the return is equal to 0:

while(feof(f) == 0)

Your code will then be more or less as follows:

#include <stdio.h>

#define max 70

typedef struct
{
  int BI;
  float altura;
  int peso;
} PESSOA;

int main()
{
  PESSOA data[max];
  FILE *f;
  int N=0;

  f=fopen("dados2.txt", "r");

  if(f==NULL)
  {
    printf("Não foi possível abrir o arquivo.\n");
    return 0;
  }

  while(!feof(f))
  {
    fscanf(f, "%d", &data[N].BI);
    fscanf(f, "%f", &data[N].altura);
    fscanf(f, "%d", &data[N].peso);
    printf("%d \n", data[N].BI);
    printf("%.2f \n", data[N].altura);
    printf("%d \n", data[N].peso);
    printf("\n");
    N++;
  }

  fclose(f);
  return 0;
}

See online: https://repl.it/@Dadinel/AdoredPleasantColdfusion


https://www.tutorialspoint.com/c_standard_library/c_function_feof.htm

Browser other questions tagged

You are not signed in. Login or sign up in order to post.