簡體   English   中英

如何從C中的文件中獲取未知數量的字符串?

[英]How to take unknown number of string from file in C?

我有一個存儲人員姓名、姓氏和薪水的結構,但他們的姓名數量是隨機的。 例如:

列表.txt

 John Smith Green 1000 //He has two names Jennifer Wilson 2000 //She has one name Steve Adams 1500 //He has one name James Robert Harris 1250 //He has two names Robin Walker 1750 //He has one name

我想將他們的姓名存儲在person[count].name中,將他們的姓氏存儲在person[count].surname中,將他們的薪水存儲在person[count].salary中。

為此,我寫道:

fscanf(file, "%s %s %d", person[count].name, person[count].surname, &person[count].salary)

但是,問題是如果一個人有兩個名字,他的第二個名字存儲在person[count].surname中,我不能取這個姓氏。

如何在person[count].name中取一個有兩個名字的人的名字?

對於此文本文件:

person[0].name ==> "約翰·史密斯"

人[1].name ==> "詹妮弗"

人[2].name ==> “史蒂夫”

person[3].name ==> "詹姆斯羅伯特"

人[4].name ==> "羅賓"

我嘗試逐行讀取文件,然后將其分成標記(單詞)。 我假設每行最多包含 10 個標記(單詞),最后一個標記是薪水,最后一個標記是姓氏,前 N-2 個標記是人名。 所以,我假設每個人的姓氏都只能用一個詞。 這是代碼,請注意我沒有注意內存泄漏或懸空指針等。

我根據@chux 的建議編輯了解決方案 - Reinstate Monica

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

typedef struct Person
{
    char *name, *surname;
    int salary;
} Person;

int main()
{
    Person persons[10];
    FILE *file = fopen("text.txt", "r");
    if (file == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }
    // read file line by line
    char line[256];
    int person_count = 0;
    while (fgets(line, sizeof(line), file) != NULL)
    {
        char *tokens[10];
        int i = 0;

        tokens[0] = strtok(line, " ");
        while (tokens[i] != NULL && i < 9)
        {
            tokens[++i] = strtok(NULL, " ");
        }

        char name[sizeof line];
        strcpy(name, tokens[0]);
        for (int j = 1; j < i - 2; j++)
        {
            strcat(name, " ");
            strcat(name, tokens[j]);
        }
        persons[person_count].name = strdup(name);
        persons[person_count].surname = strdup(tokens[i - 2]);
        persons[person_count].salary = atoi(tokens[i - 1]);
        person_count++;
    }
    for (int i = 0; i < person_count; i++)
    {
        printf("%s %s %d\n", persons[i].name, persons[i].surname, persons[i].salary);
    }

    fclose(file);
}

你不能使用fscanf()來解決這個問題。 這是一種簡單的方法,一次讀取一行並使用strrchr()顯式解析:

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

struct Person {
    char *name, *surname;
    int salary;
};

int main() {
    const char *filename = "list.txt";
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno));
        return 1;
    }
    // read file line by line
    char line[256];
    struct Person *persons = NULL;
    int count = 0;
    while (fgets(line, sizeof line, file) != NULL) {
        char *last = strrchr(line, ' ');
        if (!last)  // invalid format
            continue;
        *last++ = '\0';
        int salary;
        if (sscanf(last, "%d", &salary) != 1)
            continue;
        const char *name = line;
        char *surname = strrchr(line, ' ');
        if (surname) {
            *surname++ = '\0';
        } else {
            name = "";  // handle Superman: no first name
            surname = line;
        }
        persons = realloc(persons, (count + 1) * sizeof(*persons));
        if (persons == NULL) {
            fprintf(stderr, "out of memory\n");
            return 1;
        }
        persons[count].name = strdup(name);
        persons[count].surname = strdup(lastname);
        persons[count].salary = salary;
        count++;
    }
    fclose(file);

    // dump the database
    for (int i = 0; i < count; i++) {
        printf("%s %s %d\n", persons[i].name, persons[i].surname, persons[i].salary);
    }

    // free the database
    for (int i = 0; i < count; i++) {
        free(persons[i].name);
        free(persons[i].surname);
    }
    free(persons);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM