尝试创建一个结构数组并从文件加载数据
Trying to create an array of Struct and load data from file
我创建了一个名为 User 的结构,它存储所有类型的数据,
现在我正在尝试创建它的数组 (User*) 并从文件中获取数据,
这是我在主程序开始时所做的:
int amount = 0;
User* users = NULL;
// read from file functions
loadUsers(&users,&amount);
和功能(用户量是我的txt文件的第一行):
void loadUsers(User** users,int* amount2){
int amount, i = 0, j;
char temp[STRING_SIZE], temp2[STRING_SIZE];
FILE* f;
f = fopen("input.txt", "r");
if (!f){
return;
}
if (fileEmpty(f)){
return;
}
fscanf(f, "%d", &amount);
*amount2 = amount;
*users = malloc(sizeof(User)*amount);
/**users = (User*)malloc(sizeof(User)*amount);*/
while (!feof(f)){
fscanf(f, "%s", temp);
users[i]->ID = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->ID, temp);
fscanf(f, "%s", temp);
users[i]->f_name = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->f_name, temp);
fscanf(f, "%s", temp);
users[i]->l_name = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->l_name, temp);
i++;
}
出于某种原因,我得到一个错误,在调试时我发现分配是错误的,因为我只有 users[0]
而不是 users[1]
,就像一组用户应该有的那样,即使数量大于 1.
我的目标是有一个数组,它的每个单元格都是一个用户。
可能是什么原因?
编辑:
用户结构:
struct User{
char* ID;
char* f_name;
char* l_name;
int age;
char gender;
char* username;
char* password;
char* description;
char** hobbies;
}typedef User;
双指针语法错误。而不是这个:
users[i]->ID = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->ID, temp);
试试这个:
(*users)[i].ID = malloc(strlen(temp) + 1);
strcpy ((*users)[i].ID, temp);
其他字段依此类推。
您可能正在调用未定义的行为,因为您没有在 while 循环中检查 i < amount
,您也没有检查 fscanf()
以查看它是否成功读取数据,如果失败,temp
数组的内容将未初始化,并且尝试将它们复制到 malloc
ed 指针也是未定义的行为。
所以你的问题基本上是你的程序盲目地假设一切都按预期工作并可能调用未定义的行为,这个错误在新程序员中很常见。
您正在为 User
的 amount
结构分配 space,但您尝试在 for 循环中初始化 User
的 amount
指针,您应该取消引用双指针以使其正常工作。
这是您自己的代码,其中包含一些可以防止未定义行为的检查
void loadUsers(User** userlist, int* amount2)
{
int amount, i = 0;
char id[100];
char fname[100];
char lname[100];
FILE *file;
User *users;
file = fopen("input.txt", "r");
if (!file) {
return;
}
if (fileEmpty(file)) {
fclose(file);
return;
}
if (fscanf(file, "%d", &amount) != 1)
{
fclose(file);
return;
}
*amount2 = amount;
*userlist = malloc(sizeof(User) * amount);
if (*userlist == NULL)
return; /* malloc can fail, check that */
/* point to the destination pointer to prevent the need of (*users)[i] */
users = *userlist;
/* if fscanf() returns 3 it means that all the arguments where read */
while ((i < amount) && (fscanf(file, "%99s%99s%99s", id, fname, lname) == 3)) {
size_t length;
length = strlen(id);
users[i].ID = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].ID != NULL)
strcpy(users[i].ID, id);
length = strlen(fname);
users[i].f_name = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].f_name != NULL)
strcpy(users[i].f_name, fname);
length = strlen(lname);
users[i].l_name = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].l_name != NULL)
strcpy(users[i].l_name, lname);
i++;
}
fclose(file);
}
我创建了一个名为 User 的结构,它存储所有类型的数据, 现在我正在尝试创建它的数组 (User*) 并从文件中获取数据, 这是我在主程序开始时所做的:
int amount = 0;
User* users = NULL;
// read from file functions
loadUsers(&users,&amount);
和功能(用户量是我的txt文件的第一行):
void loadUsers(User** users,int* amount2){
int amount, i = 0, j;
char temp[STRING_SIZE], temp2[STRING_SIZE];
FILE* f;
f = fopen("input.txt", "r");
if (!f){
return;
}
if (fileEmpty(f)){
return;
}
fscanf(f, "%d", &amount);
*amount2 = amount;
*users = malloc(sizeof(User)*amount);
/**users = (User*)malloc(sizeof(User)*amount);*/
while (!feof(f)){
fscanf(f, "%s", temp);
users[i]->ID = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->ID, temp);
fscanf(f, "%s", temp);
users[i]->f_name = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->f_name, temp);
fscanf(f, "%s", temp);
users[i]->l_name = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->l_name, temp);
i++;
}
出于某种原因,我得到一个错误,在调试时我发现分配是错误的,因为我只有 users[0]
而不是 users[1]
,就像一组用户应该有的那样,即使数量大于 1.
我的目标是有一个数组,它的每个单元格都是一个用户。
可能是什么原因?
编辑: 用户结构:
struct User{
char* ID;
char* f_name;
char* l_name;
int age;
char gender;
char* username;
char* password;
char* description;
char** hobbies;
}typedef User;
双指针语法错误。而不是这个:
users[i]->ID = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->ID, temp);
试试这个:
(*users)[i].ID = malloc(strlen(temp) + 1);
strcpy ((*users)[i].ID, temp);
其他字段依此类推。
您可能正在调用未定义的行为,因为您没有在 while 循环中检查 i < amount
,您也没有检查 fscanf()
以查看它是否成功读取数据,如果失败,temp
数组的内容将未初始化,并且尝试将它们复制到 malloc
ed 指针也是未定义的行为。
所以你的问题基本上是你的程序盲目地假设一切都按预期工作并可能调用未定义的行为,这个错误在新程序员中很常见。
您正在为 User
的 amount
结构分配 space,但您尝试在 for 循环中初始化 User
的 amount
指针,您应该取消引用双指针以使其正常工作。
这是您自己的代码,其中包含一些可以防止未定义行为的检查
void loadUsers(User** userlist, int* amount2)
{
int amount, i = 0;
char id[100];
char fname[100];
char lname[100];
FILE *file;
User *users;
file = fopen("input.txt", "r");
if (!file) {
return;
}
if (fileEmpty(file)) {
fclose(file);
return;
}
if (fscanf(file, "%d", &amount) != 1)
{
fclose(file);
return;
}
*amount2 = amount;
*userlist = malloc(sizeof(User) * amount);
if (*userlist == NULL)
return; /* malloc can fail, check that */
/* point to the destination pointer to prevent the need of (*users)[i] */
users = *userlist;
/* if fscanf() returns 3 it means that all the arguments where read */
while ((i < amount) && (fscanf(file, "%99s%99s%99s", id, fname, lname) == 3)) {
size_t length;
length = strlen(id);
users[i].ID = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].ID != NULL)
strcpy(users[i].ID, id);
length = strlen(fname);
users[i].f_name = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].f_name != NULL)
strcpy(users[i].f_name, fname);
length = strlen(lname);
users[i].l_name = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].l_name != NULL)
strcpy(users[i].l_name, lname);
i++;
}
fclose(file);
}