fgetc пропускает первый символ в файле - PullRequest
0 голосов
/ 24 ноября 2018

В цикле while команда fgetc пропускает первый символ, и я не могу понять, почему.

void generate_people(FILE *p, struct person *a){
    int c;

    while((c = getc(p)) != EOF){
        fscanf(p, "%s %[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ], 
          %[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ] %d, %d %s.", 
            a->fornavn, a->efternavn, a->vejnavn, 
            &a->vejnummer, &a->postnummer, a->bynavn);
        a++; 
    }    
}

1 Ответ

0 голосов
/ 24 ноября 2018

Первый символ в c.Используйте результат fscanf() вместо (c = getc(p)) != EOF для обнаружения ошибки или EOF:

void generate_people(FILE *p, struct person *a)
{
    while (fscanf(p, "%s %[a-zA-Z], %[a-zA-Z] %d, %d %s.",
                     a->fornavn, a->efternavn, a->vejnavn, 
                     &a->vejnummer, &a->postnummer, a->bynavn) == 6)
    {
        ++a; 
    }    
}

Полный пример:

#include <stdlib.h>
#include <stdio.h>

struct person {
    char fornavn[30];
    char efternavn[30];
    char vejnavn[30];
    int  vejnummer;
    int  postnummer;
    char bynavn[30];
};

struct person* generate_people(FILE *p, struct person *a)
{
    while (fscanf(p, "%29s %29[a-zA-Z], %29[a-zA-Z] %d, %d %29s",  // ****)
           a->fornavn, a->efternavn, a->vejnavn,
           &a->vejnummer, &a->postnummer, a->bynavn) == 6)
    {
        ++a;
    }
    return a;
}

void person_print(struct person *a)
{
    printf("\"%s\" \"%s\", \"%s\" %d, %d \"%s\"\n",
           a->fornavn, a->efternavn, a->vejnavn,
           a->vejnummer, a->postnummer, a->bynavn);
}

int main(void)
{
    char const *filename = "test.txt";
    FILE *input = fopen(filename, "r");

    if (!input) {
        fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
        return EXIT_FAILURE;
    }

    struct person people[10];
    struct person *end = generate_people(input, people);

    for (struct person *i = people; i != end; ++i)
        person_print(i);

    fclose(input);
}

Входной файл:

Lars Jensen, Engtoften 23, 7182 Bredsten
Bo Olsen, Vestergade 56, 4261 Dalmose
Kurt Jensen, Haderslevvej 15, 8370 Hadsten
Birte Madsen, Universitetsvej 899, 9000 Aalborg
Kaj Moberg, Halevindingevej 2, 2670 Greve
Bo Rise, Hadsund Landvej 56, 8900 Randers

Вывод:

"Lars" "Jensen", "Engtoften" 23, 7182 "Bredsten"
"Lars" "Jensen", "Engtoften" 23, 7182 "Bredsten"
"Bo" "Olsen", "Vestergade" 56, 4261 "Dalmose"
"Kurt" "Jensen", "Haderslevvej" 15, 8370 "Hadsten"
"Birte" "Madsen", "Universitetsvej" 899, 9000 "Aalborg"
"Kaj" "Moberg", "Halevindingevej" 2, 2670 "Greve"

****) Обратите внимание: НИКОГДА не следует использовать "%s" с *scanf() без указания ширины поля для чтения: "%NNNs" где NNN - количество символов.Для массива размером 30: "%29" ... 29 + 1 для завершающего 0.

...