Losowanie haseł z pliku

0

Na początek poinformuję że jestem niestety noobem w programowaniu i bardzo proszę o tłumaczenie "jak krowie na rowie" :D
Mam problem z programem koło fortuny. Nie chodzi o sam mechanizm gry, z nim wszystko jest w porządku od momentu //szyfrowanie pola do odgadywania wszystko powinno być okej, (zresztą nawet prosiłam już na tym forum o pomoc z tą częścią.

Problem pojawia się w miejscu kiedy hasła z pliku (w każdym sztywno po 10 haseł, każde w nowej linijce) mam wczytać do tablicy linia po linii.
przykładowy plik txt:

kot
pies
sowa
jerzyk
kogut
kaczka
delfin
rekin
kucyk
krowa

Program po prostu przestaje się wykonywać po wybraniu kategorii. Próbowałam wcześniej z funkcją getline, lecz nie mogłam znaleźć zrozumiałej dla mnie instrukcji jak jej odpowiednio użyć.
Jak rozwiązać problem losowania hasła z pliku?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main ()
{
    FILE* category;
    int cases;
    printf("Wybierz kategorie. \n1 - zwierzeta\n2 - rosliny\n3 - kraje\n\n");
    scanf("%d", &cases);
    switch(cases)
    {
    case 1:
        printf("Wybrano kategorie ZWIERZETA.\n");
        category = fopen("zwierzeta.txt", "w");
        break;
    case 2:
        printf("Wybrano kategorie ROSLINY.\n");
        category = fopen("rosliny.txt", "w");
        break;
    case 3:
        printf("Wybrano kategorie KRAJE.\n");
        category = fopen("kraje.txt", "w");
        break;
    default:
        printf("Wybrano zla kategorie."); break;
    }

    if (category == NULL)
    {
        puts("Blad otwarcia pliku");
        exit(-1);
    }

    char line[30];

    char **zbior = (char**) malloc (10 * sizeof(char*));
      for(int i=0;i<10;i++)
    {
        zbior[i] = (char*) malloc (30 * sizeof(char*));
        zbior[i]=(fgets(line, sizeof(line), category));
    }


    int losowana;
    char word[30];
    char input[30];
    char litera;

    srand(time(NULL));
    losowana = ((rand() % 10));
    strcpy(word,zbior[losowana]);
    strcpy(input, word);

    printf("Wylosowano haslo %s", word);

//Szyfrowanie pola do odgadywania
    for(int i=0;word[i]!=0;i++)
    {
        if(word[i]!=' ')
        input[i]='_';
        else
        input[i]=' ';
    }
    printf("slowo: %s\n", input);

    int licznikProb=0;
    while(licznikProb<=25)
    {


        printf("\nPodaj litere: ");
        scanf(" %c", &litera);   /// <-spacja przed %c!
        licznikProb+=1;
        for (int i=0; word[i]!=0; i++)
        {
            if(litera==word[i])
                input[i]=litera;
        }

        printf("slowo: %s", input);
        if(strcmp(word,input)==0)
        {
            printf("\nWygrales!"); break;
        }

    }
    if (licznikProb>25) puts("\nWykorzystano wszystkie proby. Koniec gry.");

//Zwalnianie pamieci
    for (int i=0;i<5;i++)
    {
        free (zbior[i]);
        zbior[i]=NULL;
    }
    free(zbior);
    return 0;



}



0
	zbior[i] = (char*)malloc(30 * sizeof(char*));
	zbior[i] = (fgets(line, sizeof(line), category)); // <--- !!!

```c
fgets(line, sizeof(line), category);
zbior[i] = strcpy(malloc(strlen(line) + 1), line);
5

Miej dla siebie litość i podziel ten kod na małe funkcje, które robią jedną konkretną rzecz.
Jak wszystko masz w jednej funkcji to trudno ogarnąć: co jest czym i co nie działa.
To jak w języku naturalnym, zdania wielokrotnie złożone, są trudne w zrozumieniu. Równocześnie, przy zapisie łatwo popełnić w nich błędy gramatyczne lub logiczne.
Pisząc krótkie zadania (funkcje) łatwej je zrozumieć i łatwiej je poprawnie zapisać.

0

Po pierwsze zastanów się jaką chcesz przyjąć strategię obsługi tych danych. Możesz nie tylko wczytać je do tablicy ale bazować na pliku jako przestrzeni pamięci. Pliki mają jednak tą wadę, że są dostępne sekwencyjnie.

  1. Jeśli przyjąć że dane pozostaną w pliku, to nie wiesz ile ich jest i w jakim miejscu pliku znajdują się poszczególne słowa. Pozostanie więc (w naiwnym przypadku), odczytanie ilości wierszy i w trakcie pobrania danego wiersza... rozpoczynanie od pierwszego i sekwencyjne wczytywanie do docelowego. Chyba widać wadę tego rozwiązania ale także (być może) zalety/koszty w konkretnym przypadku.
  2. Jeśli przyjąć rozwiązanie z tablicą, masz także warianty.
    Możesz wcześniej wczytać ilość wierszy i dynamicznie alokować tablicę na te wiersze. Później każdy z wierszy także alokujesz dynamicznie a wskaźnik zapisujesz do pierwotnie alokowanej tablicy wierszy.
    Innym podejściem będzie użycie realloc(...), która będzie "poprawiała" alokację (poszerzając ilość danych), do pożądanego rozmiaru.
    Jeszcze inną strategią będzie alokowanie tablicy na całość danych w jednej transakcji. Ale to ostatnie wybierane jest dla zastosowań wymagających wysokiej wydajności.

Tak czy siak, podziel kod na funkcje. Eksperymenty z budowaniem w trybie "strumienia świadomości", zostaw literatom :)

1
category = fopen("zwierzeta.txt", "w");

to w spowoduje, że dane w pliku zostaną wymazane bo plik zostanie otwarty do zapisu. Powinno tam być r

1 użytkowników online, w tym zalogowanych: 0, gości: 1