将多行文件读入 C89 中的结构

Reading a file with multiple lines into a struct in C89

我试图读取一个包含大约 200 行的文件,然后将不同的行保存到一个结构中。结构如下:

struct person_data{
  char name[20];
  char lastname[30];
  int age;
  char country[3]
};

文件中的行设置为:

"Tom HALL"                            32   ENG
"Ryan SMITH"                          24   USA

所以我的问题是我不确定应该如何读取该文件并将信息放入结构中。我一直在尝试将文件保存到我的结构中,然后打印它,但结果是我的计算机上出现了一个目录路径,并且在它崩溃之前出现了很多奇怪的符号。 我的代码是:

int main(){
FILE *fp;
fp = fopen("person.txt", "r");
person_data *person = malloc(sizeof(struct person_info));
int i = 0;
if(fp != NULL) {
    while ( i < 200 ) {
        fscanf(fp, "%[A-Za-z] %[A-Z] %d %[A-Z]",
               person[i].name,
               person[i].lastname,
               &person[i].age,
               person[i].country);

        i++;
    }
}
else{
    perror(fp);
}
for (i = 0; i < 200; i++) {
    printf("%s %s  %d %s",
           person[i].name,
           person[i].lastname,
           person[i].age,
           person[i].country);

}
fclose(fp);
return 0;
}

我不确定哪里出了问题,因此想问问是否有人知道我做错了什么以及如何解决这个问题。当我 运行 程序看起来像这样:

如果您需要 200 个该结构,则需要分配该结构大小的 200 倍

#define NUMBER 200

person_data *person = malloc(NUMBER * sizeof(struct person_info));

或使用 calloc(将分配的内存初始化为零 - 在您的情况下不是必需的,但更易于阅读)

person_data *person = calloc(NUMBER, sizeof(struct person_info));

并且 country 需要至少 4 个字符(@PeterJ_01 注释)如果您在其中存储 3 个字符的字符串(由于尾随零)。

首先看看你的malloc,想想哪里不对?您只为一个结构分配了内存。分配对所有类型都一样。如果您需要分配 struct person 的数组,您可以使用:

struct person_data *person = malloc(number_of_elements * sizeof(struct person_data));

顺便说一下,你在 sizeof(sturct person_info) 中有错别字,你没有 person_info struct

我测试了你的代码,使用这个语句它不起作用fscanf(fp, "%[A-Za-z] %[A-Z] %d %[A-Z]")我不知道为什么......但我只是将它重写为fscanf(fp, "%s %s %d %s")并且一切正常

perror() 中你传递了 FILE* 但它期望来自 man 的 const char *s

The perror() function produces a message on standard error describing the last error encountered during a call to a system or library function.

First (if s is not NULL and *s is not a null byte ('[=22=]')), the argument string s is printed, fol‐ lowed by a colon and a blank. Then an error message corresponding to the current value of errno and a new-line. To be of most use, the argument string should include the name of the function that incurred the error.

而且您还需要将字符串的大小增加 1,因为最后一个字符是 '\0'; 在你的情况下国家有 [3] 需要 [4];

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

struct person_data {
    char name[20];
    char lastname[30];
    int age;
   char country[4];
};


int main(){
    FILE *fp;
    fp = fopen("person.txt", "r");
    struct person_data *person = malloc(sizeof(struct person_data) * 4);
    int i = 0; 
    if(fp != NULL) {
         while ( i < 4 ) {
           fscanf(fp, "%s %s %d %s",
                person[i].name,
                person[i].lastname,
                &person[i].age,
                person[i].country);
                i++;
        }
    }
    else{
      perror("FP ERROR: ");
    }
    for (i = 0; i < 4; i++) {
        printf("%-8s %-10s  %-10d %-10s\n",
        person[i].name,
        person[i].lastname,
        person[i].age,
        person[i].country);

   }
   fclose(fp);
   return 0;
}

我在我的 person.txt 中尝试与四个人一起工作,并且成功了。并打印:

"Tom     HALL"       32    ENG  
"Ryan    SMITH"      24    USA  
"Hal     Al"         25    UKR  
"Peter   Peters"     99    ENG