0

So, i need a code to read a TXT file with 5 contents each line, and store each line values in a variable. but the number of lines in the TXT will vary. so i thought of excecuting something like this:

int counter=0;
char nome="TXT NAME.txt";
 FILE *f = fopen(NAME,"r");
 do{
 if(!feof(p))
 counter++;
}while(!feof(f)); 
 fclose(f)
 int X[counter][5];

so when declaring like this, X will have the number of lines of the file. but the issue is that to store the values, i would need to open and read the file again. is there a way to save the values while declaring the variable so i dont need to open twice ?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
GBinow
  • 13
  • 3
  • 1
    https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – William Pursell Jun 04 '20 at 19:20
  • 1
    Apart from that `feof` business mentioned, you are not even reading anything from the file. – Weather Vane Jun 04 '20 at 19:21
  • 1
    Are you actually able to accurately count the number of lines with that code? I am skeptical. Looks like an infinite loop to me. – William Pursell Jun 04 '20 at 19:21
  • 1
    what is the variable `p`? – Christian Gibbons Jun 04 '20 at 19:22
  • 1
    Short answer: yes. Read one line of the file. Store it. Read the next line. Continue until you reach the end of the file. `man realloc` – William Pursell Jun 04 '20 at 19:22
  • to read the file use fgets e.g. `char line[128]; while (fgets( line, sizeof(line), f) != NULL) { ... }` – AndersK Jun 04 '20 at 19:24
  • Your loop doesn't appear to count lines. It is just loops around checking if you reached the end of the file, but you haven't done anything at all with the file. What you want is to read line by line, do whatever you want with the data in each line, and increment the counter once per line. The accepted answer here: https://stackoverflow.com/questions/9206091/going-through-a-text-file-line-by-line-in-c can help you read the file line-by-line. – Basya Jun 04 '20 at 19:27
  • @Basya `feof()` does not "check if you have reached the end of the file." – Weather Vane Jun 04 '20 at 19:30
  • @WeatherVane -- it checks, after reading from a file and getting an error, whether the 'problem' is that you are at the end. But he is not reading from the file or doing anything at all with the file. That is the point I was trying to make. – Basya Jun 04 '20 at 19:31
  • @Basya no, `feof()` checks if you attempted to read beyond the end of a file. It does *not* check if you are at the end. – Weather Vane Jun 04 '20 at 19:34
  • @WeatherVane that sounds like what I said but in different words. – Basya Jun 04 '20 at 19:35
  • I disagree with that wording. `feof` does not check if an attempt was made to read beyond the end of the file. `feof` checks if the reason that a `read` failed is because the end of the file was reached. – William Pursell Jun 04 '20 at 19:42
  • GBinow `do{ if(!feof(p)) counter++; }while(!feof(f));` never _reads_ anything. – chux - Reinstate Monica Jun 04 '20 at 19:42
  • `feof()` reports the end-of-file indicator. That indicator is set _after_ a read occured and end-of-file was detected. The indicator is cleared by some functions: `clearerr(), freopen(),`, sometimes with `ungetc()`. ... – chux - Reinstate Monica Jun 04 '20 at 19:45
  • @WilliamPusell from the man page "The feof function returns a nonzero value if a read operation has attempted to read past the end of the file; it returns 0 otherwise. " – Weather Vane Jun 04 '20 at 19:59

2 Answers2

1

How to read a file in C and at the same time create a variable with the number of lines?
is there a way to save the values while declaring the variable so i dont need to open twice ?

A nice way is to read one line at a time with fgets(), copy the buffer with strdup() and save in a linked list of your creation.

Some pseudo-code to get you going.

f = open file
exit if unable to open
line_count = 0;
list = LL_Create()
char buffer[100];
while (fgets(buffer, sizeof buffer, f)) {
  Maybe special handling here to deal with lines longer than 100
  char *s = strdup(buffer);
  LL_Append(list, s);
  line_count++;
}
fclose(f);

// Use the link-list of strings

// When done
while !LL_Empty(list)
  s = LL_Pop(list)
  free(s);

LL_Destroy(list)
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

You can use realloc to gradually expand your "array".

But a simpler approach is to use a linked list, that way the list just grows as you read the file.

typedef struct 
{
  char data[5];
  Line* next;
} Line;

Line* first = NULL;
Line* last = NULL; 

char line[128];
while (fgets(line, sizeof(line), f)
{
  Line* tmp = malloc(sizeof(Line));
  memcpy(tmp->data,line,5);
  tmp->next = NULL;

  if (first == NULL)
  {
    first = last = tmp;
  }
  else
  {
    last->next = tmp;
    last = tmp;
  }
}

Now to go through the lines

for(Line* p = first; p != NULL; p = p->next)
{
   p->data ...
}
AndersK
  • 35,813
  • 6
  • 60
  • 86