fread无法读取unsigned int? [C]

时间:2013-04-15 04:27:56

标签: c file binaryfiles

我有一个Person结构如下:

typedef struct Person {
    char name[NUM_CHARS];
    unsigned int age;
} Person;

其中#define NUM_CHARS 20

我想把这个结构写成二进制文件,所以我编写了两个函数来处理它:

int writePerson(Person* person, FILE* _fp) {
    int i = 0;
    int count = 0;
    int len = strlen(person->name);
    // Write name
    for(i = 0; i < len+1; i++) {
        count += fwrite(&(person->name[i]), sizeof(char), 1, _fp);
    //  fseek(_fp, 1, SEEK_CUR);
    }
    // Continue
    // Write age
    count += fwrite(&(person->age), sizeof(unsigned int), 1, _fp);

    return count;
}

int readPerson(Person* person, FILE* _fp) {
    int i = 0;
    int count = 0;
    // Write name
    for(i = 0;person->name[i] != NULL;i++) {
        count += fread(&(person->name[i]), sizeof(char), 1, _fp);
    }
    // Continue
    // Write age
    count += fread(&(person->age), sizeof(unsigned int), 1, _fp);

    return count;
}

所以我写了一个Person到我提前创建的空白文件Px.bin

int main() {
    FILE* fp = fopen("Px.bin", "r+b");
    Person person = {"Billie", 40};
//  Person y ;
    int x = writePerson(&person, fp);
    printf("%d", x);
//  printPerson(&y);
    getchar();
    fcloseall();
    return 0;
}

似乎运作良好,打印8

但是当我尝试阅读此文件时:

int main() {
    FILE* fp = fopen("Px.bin", "r+b");
//  Person person = {"Billie", 40};
    Person y ;
    int x = readPerson(&y, fp);
    printf("%d\n", x);
    printPerson(&y);
    getchar();
    fcloseall();
    return 0;
}

我得到了这个结果:

11
Billie
-858993460

printPerson是:

void printPerson(Person* p) {
    printf("%s\n%d\n", p->name, p->age);
}

有什么问题?

2 个答案:

答案 0 :(得分:0)

您的代码读取名称会检查可能未初始化(或清零)的person->name[i]元素。结果,循环在某个不可预测的时间结束(即,如果它被归零,则循环将不fread甚至单个字符。

for(i = 0;person->name[i] != NULL;i++) {
    count += fread(&(person->name[i]), sizeof(char), 1, _fp);
}

您希望将其更改为do / while循环,或者不要读取文件字符串中带有长度的0前缀数据,并读取多个字符。

答案 1 :(得分:0)

这一位

for(i = 0;person->name[i] != NULL;i++) {
    count += fread(&(person->name[i]), sizeof(char), 1, _fp);
}

将使用未初始化(IOW,包含垃圾)person->name[]作为阅读条件。并且可能会发生在这里读取错误的字节数。

之后的以下

count += fread(&(person->age), sizeof(unsigned int), 1, _fp);

可以读取文件中不正确位置的整数,而不是存储所述整数的位置。

修复方法是首先读取一个字符,然后查看它是否为'\0'。如果是,则完全读取字符串。如果不是,请继续阅读字符。

相关问题