У меня есть созданная мной структура под названием 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;
2 ответа
Возможно, вы вызываете неопределенное поведение, потому что вы не проверяете i < amount
в цикле while, вы также не проверяете fscanf()
, чтобы узнать, успешно ли он прочитал данные, если это не удается, то содержимое массива temp
будет неинициализированным, и попытка скопировать его в редакторы malloc
также является неопределенным поведением.
Итак, ваша проблема в основном в том, что ваша программа слепо предполагает, что все работает, как ожидалось, и потенциально вызывает неопределенное поведение, эта ошибка очень распространена среди новых программистов.
Вы выделяете место для amount
структур User
и все же пытаетесь инициализировать amount
указатели User
в цикле for, вам следует разыменовать двойной указатель, чтобы он работал правильно.
Это ваш собственный код с некоторыми проверками, которые предотвратят неопределенное поведение
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);
}
Синтаксическая ошибка двойного указателя. Вместо этого:
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);
И так далее для других полей.
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.