[英]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.