1

I'm trying to read some strings from a txt file. Each line has a 5 digit number, a full name that occupies 51 characters (including spaces), 2 city names, each one occupyng 11 characters including spaces, and one number. Example:

12345António Manuel Silva Mendes                        Frankfurt  Varsovia    1

I can now scan the first 2 strings, but I can't scan the city names, nor the last number.

Here's the struct:

typedef struct bilhete{

    int BI;
    char nome[51];
    char partida[11];
    char chegada[11];
    int data[2];

}BILHETE;

here's the way I'm reading the file

while(!feof(fp)){

        fscanf(fp,"%d%51[^\n]s%11c%11c%d\n", &bilhete.BI, bilhete.nome, bilhete.partida, bilhete.chegada, &bilhete.data);

What am I doing wrong? when I print the city names, nothing appears!

losvatos
  • 11
  • 1
  • 3
    What does fscanf return? What does that mean? – Useless Dec 06 '17 at 23:27
  • 4
    `while(!feof(fp))` is wrong. https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – MFisherKDX Dec 06 '17 at 23:36
  • given the sizing of the input fields, the struct definition char fields are too short by 1 char. This is because when calling any for the `scanf()` family of functions, the input format specifiers `%s` and `%[...]` always append a NUL byte to the end of the input. – user3629249 Dec 07 '17 at 10:08
  • the call to `fscanf()` has an spurious 's' after the input format specifier `%51[^\n]` The 's' doesn't exist in the input data, so the input activity will stop there. If you had been checking the returned value from `fscanf()` (which in the current scenario should be: 5) it would have returned 2. You seem to have a misunderstanding about the '%[]' input specifier. This is a 'standalone' specifier, so does NOT need a trailing 's'. – user3629249 Dec 07 '17 at 10:16
  • in general, NEVER use `feof()` in a while loop. For the current scenario, use this for the `while` statement: `while( 5 == fscanf(fp,"%d %51[^\n] %11c %11c %d\n", &bilhete.BI, bilhete.nome, bilhete.partida, bilhete.chegada, &bilhete.data) )` – user3629249 Dec 08 '17 at 01:45
  • Additionally, your last parameter is passed incorrectly. format specifier is `%d`, which expects `int *` argument to write number value. You're passing `&bilhete.data`, where data is an array of ints, so basically `int **`. Either change data to be single int, or pass it without `&`. – Jakub Piskorz Dec 08 '17 at 22:08

1 Answers1

0

Since you have fixed columns, I would consider just reading in the data and doing my own scanning with something like:

char linein[200];
char *p;

while (fgets(linein, sizeof(linein), fp))
{
    char biBuf[10]={0};
    char dataBuf[10]={0};

    p=linein;
    memcpy(biBuf,linein,5);
    bilhete.BI=atoi(biBuf);
    p+=5;
    memcpy(bilhete.nome,p,51);
    p+=51;
    memcpy(bilhete.partida,p,11);
    p+=11;
    memcpy(bilhete.chegada,p, 11);
    p+=11;
    memcpy(dataBuf,p,2);
    bilhete.data[0]=atoi(dataBuf);
    printf("%.51s %d\n",bilhete.nome, bilhete.data[0]);
}

I am not sure what you wanted to do with the data variable but this will give you an integer. Observe, the biBuf and dataBuf variables are allocated in the loop so they get set to zeros each time.

user1683793
  • 1,213
  • 13
  • 18