fgetc 跳过文件中的第一个字符

fgetc skips first character in file

在 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++; 
    }    
}

第一个字符在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.