2017-02-08 6 views
0

Мне нужно выделить массив неизвестного числа пользователей, и каждый пользователь должен иметь массив с неизвестным количеством вариантов. Все данные считываются из файла CSV.Динамический массив структур в динамическом массиве структуры в C

До сих пор у меня есть:

typedef struct wybor   //struct choice 
{ 
    char rozmiar_kawy[2]; 
    char czy_z_mlekiem[4]; 
    char ile_cukru[2]; 
    char godzina[20]; 
}wybor; 

typedef struct user 
{ 
    char id[5]; 
    char imie[20]; 
    wybor *tablica_wyborow;  //dynamic array of struct choice 
}user; 


void odczyt_z_pliku(user **tab, int n);  //reading from file csv 
void godzina(user *kawa);    //doesnt matter :p 

int main() 
{ 
    int licznik = 0;   //counter for number of users 
    user *tablica_userow;  //dynamic array of struct users 
    tablica_userow = NULL; 
    setlocale(LC_ALL, "pl_PL"); 

    odczyt_z_pliku(&tablica_userow, licznik); 

    getchar(); 
    printf("%s", tablica_userow[0].tablica_wyborow[2].rozmiar_kawy);  //check if it works 
    getchar(); 
    return 0; 
} 

void odczyt_z_pliku(user **tab, int n) 
{ 

    int i = 0; 
    (*tab) = malloc(1*sizeof(*(*tab))); 
    tab[n]->tablica_wyborow = malloc(1*sizeof(*(tab[n]->tablica_wyborow))); 
    FILE *plik; 
    plik = fopen("users.csv", "a+"); 

     //start reading from file and its working until... 
     fscanf(plik, "%[^;] ; %[^;] ; %[^;] ; %[^;] ; %[^;] ; %s\n", tab[n]->id, tab[n]->imie, tab[n]->tablica_wyborow[i].rozmiar_kawy, tab[n]->tablica_wyborow[i].czy_z_mlekiem, tab[n]->tablica_wyborow[i].ile_cukru, tab[n]->tablica_wyborow[i].godzina); 
     i++; 

     tab[n]->tablica_wyborow = realloc(tab[n]->tablica_wyborow,(i+1)*sizeof(*(tab[n]->tablica_wyborow))); 

     fscanf(plik, "%[^;] ; %[^;] ; %[^;] ; %[^;] ; %[^;] ; %s\n", tab[n]->id, tab[n]->imie, tab[n]->tablica_wyborow[i].rozmiar_kawy, tab[n]->tablica_wyborow[i].czy_z_mlekiem, tab[n]->tablica_wyborow[i].ile_cukru, tab[n]->tablica_wyborow[i].godzina); 

     i = 0; 
     n++; 
     *tab = realloc(*tab,(n+1)*sizeof(user)); //...now, here there is a memory writing location error 

     tab[n]->tablica_wyborow = malloc(sizeof(*tab[n]->tablica_wyborow)); 

     fscanf(plik, "%[^;] ; %[^;] ; %[^;] ; %[^;] ; %[^;] ; %s\n", tab[n]->id, tab[n]->imie, tab[n]->tablica_wyborow[i].rozmiar_kawy, tab[n]->tablica_wyborow[i].czy_z_mlekiem, tab[n]->tablica_wyborow[i].ile_cukru, tab[n]->tablica_wyborow[i].godzina); 
     i++; 
     tab[n]->tablica_wyborow = realloc(tab[n]->tablica_wyborow, (i + 1) * sizeof(*(tab[n]->tablica_wyborow))); 

     fscanf(plik, "%[^;] ; %[^;] ; %[^;] ; %[^;] ; %[^;] ; %s\n", tab[n]->id, tab[n]->imie, tab[n]->tablica_wyborow[i].rozmiar_kawy, tab[n]->tablica_wyborow[i].czy_z_mlekiem, tab[n]->tablica_wyborow[i].ile_cukru, tab[n]->tablica_wyborow[i].godzina); 

    fclose(plik); 

} 

Я не знаю, почему я не могу перераспределить массив пользователей правильно.

Я не освобождал память, потому что она срабатывает, когда я пытался.

+0

В 'odczyt_z_pliku' у вас есть' tab [n] ', что неверно. Это должно быть '(* tab) [n]'. И тогда '(* tab) [n]' не является указателем, а фактическим экземпляром структуры, поэтому вы не должны использовать '->' для доступа к его элементам. –

+0

И почему у вас есть четыре одинаковых вызова 'fscanf'? Что делать, если в файле больше данных? Или менее? Как насчет цикла? –

+0

'wybor *' - указатель, а не массив. Но он может указывать на первый элемент массива. – Olaf

ответ

0

Вы можете использовать связанные списки чтобы прочитать их. Структура пользовательских данных имеет указатель на связанный список пользовательских вариантов.

Если вы все еще хотите использовать массивы, вы можете теперь подсчитать количество пользователей, выделить для него массив и заполнить его пользователями. Точно так же вы можете подсчитать количество вариантов пользователя и выделить для него массив, а затем заполнить его.

В вашем связанном списке должен быть член void *, который будет хранить указатель на отдельную структуру данных для пользователей, поэтому вы можете просто переместить указатель структуры пользовательских данных из связанного списка в ваш массив.

Структура пользовательских данных имеет член wybor *tablica_wyborow; для пользовательских выборов. Вы можете поддерживать один связанный список, который будет удерживать выбор пользователя во время чтения данных, а затем, когда все пользовательские варианты будут прочитаны, вы подсчитаете их и выделите для него массив и скопируете данные выбора (по значению или указателю) внутрь.

Как только все будет сделано, освободите связанные списки, поскольку они вам больше не нужны.

Альтернативно, вы можете прочитать файл для подсчета, а затем переработать его. Но это дает проблемы с подсчетом выбора отдельных пользователей.

+0

Да, я думал об этом только сегодня утром. Я писал функцию подсчета, ожидая помощи от вас: D – Felipe

Смежные вопросы