2017-02-08 23 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); 

} 

私はきちんとユーザーの配列をreallocのできない理由を私は知りません。

私は試したときにクラッシュするため、メモリを解放しませんでした。

+0

'odczyt_z_pliku'にはあなたが間違っている' tab [n] 'があります。 '(* tab)[n]'でなければなりません。そして、 '(* tab)[n]'はポインタではなく実際の構造体インスタンスなので、その要素にアクセスするために ' - >'を使うべきではありません。 –

+0

なぜ4つの同じfscanfコールがありますか?ファイルにさらにデータがある場合はどうなりますか?以下?ループはどうですか? –

+0

'wybor *'はポインタであり、配列ではありません。しかし、配列の最初の要素を指すことができます。 – Olaf

答えて

0

リンクリストを使用してデータを読み取ることができます。ユーザーデータ構造には、ユーザーの選択肢のリンクリストへのポインターがあります。

それでも配列を使用する場合は、ユーザーの数を数え、配列を割り当ててユーザーに入力することができます。同じ方法で、ユーザーの選択肢の数を数え、それに配列を割り当ててからそれを設定することができます。

リンクリストには、ユーザの別のデータ構造へのポインタを格納するvoid *メンバーが必要です。そのため、リンク先リストからユーザデータ構造のポインタを配列に移動することができます。

ユーザーデータ構造には、ユーザーchoincesのメンバーwybor *tablica_wyborow;があります。データを読み込んでいる間にユーザーの選択肢を保持する1つのリンクされたリストを維持することができます。そして、ユーザーの選択肢のすべてが読み込まれたら、それらを数えて配列を割り当て、選択肢のデータを(値またはポインターで)それに

すべての操作が完了したら、不要になったリンクされたリストの割り当てを解除します。

また、カウントするためにファイルを読み取り、再処理することもできます。しかし、個々のユーザーの選択肢を数えるのに問題があります。

+0

はい、私はちょうど今日の朝に考えました。私はあなたからの助けを待っているカウント関数を書いていました:D – Felipe