0

so I am having troubles reading a text file. I am very new to code, and I would like my code to be able to read the simple .txt file and store some things: the name of a person, the time (nr after the name), among others.

My txt file has this format: txt file I need to store the name of a person, which is located after a "." and before a ":" symbol:

  1. Pedro Mendes: 45

For exame, in this line I need to store "Pedro Mendes".

My code is not working properly:

FILE *f;
f = fopen(filename,"rt");
if(f==NULL){
    printf("Erro no acesso ao ficheiro.\n");
    return NULL;
}

(...)

while(fgetc(f) != '.'); // finds the point
fscanf(f," %s %s",pnome,unome); //saves the name of a person
while(fgetc(f) != ':');
fscanf(f,"%d",&tempo);

I should get "Pedro Mendes" but I have "Pedro Mendes:", and for the time I should get 45 but I have 46 (is reading from the next line I believe).

If anyone has answers that would be great, thanks.

Adam
  • 2,820
  • 1
  • 13
  • 33
  • 1
    Does this answer your question? [How to read the content of a file to a string in C?](https://stackoverflow.com/questions/174531/how-to-read-the-content-of-a-file-to-a-string-in-c) – Adam Jun 19 '20 at 13:13
  • Perhaps with (after finding the `'.'`) `if(fscanf(f, "%s %[^:]:%d", pnome, unome, &tempo) == 3) { /* success */ }` although IMO it would be better to read every whole line with `fgets` and analyse that. – Weather Vane Jun 19 '20 at 13:25
  • Thank you for your answer. It works! – Sandra Perdigao Jun 19 '20 at 13:43

2 Answers2

0

You can remove the ':' like this:

char *c = strchr(unome, ':');
if(c)
    *c = '\0';

As for reading the wrong number, remove while(fgetc(f) != ':'); as the ':' is being stored in unome.

Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46
0

The scanf family function is known as a poor mans's parser. It it intended to directly process white space separated elements (end of line being a white space here). In any other context it can or not be used but only with major caution, and other library functions often perform better (in sense of simpler or more robust code).

IIUC, you have:

  • something that you ignore, up to a dot (.)
  • a dot
  • a string representing a name, up to a colon (:)
  • a colon
  • a number representing a time

If you are not concerned by proper line separation you can use the [] format specifier:

FILE *f = fopen(filename,"rt");
if (f == NULL) {
    ...
}
int cr = fscanf(f, "%*[^.].%[^:]:%d", nome, &tempo);
if (cr != 2) {
    ...
}

You have lost the separation pnome, unome, but the good news is that it would accept Juan Pedro Mendez y Garcia...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252