pętla do listy jednokierunkowej

0

Witam, obecnie funkcja "nowy" wczytuje poprawnie tytuł i autora książki z pliku (bez pętli while) , chciałbym zastosować pętle tak aby funkcja wczytała mi wszystkie 20 elementów (z pliku) jednak żaden warunek jak dotąd nie był poprawny bowiem funkcja przestaje wyświetlać cokolwiek. Dziękuję z góry za pomoc.

struct ksiazka
{
    char *tytul;
    char *autor;
    int *rok_wydania;
    struct ksiazka *next;
} ksiazka;

// wskaznik do struktury glownej
struct ksiazka *dodaj_ksiazka;
struct ksiazka *poczatek = NULL;
struct ksiazka *koniec = NULL;

// dodaje elementy struktury do pamieci
void nowy()
{
    char t[max];
    char a[max];
    int r;

    FILE *lista_ksiazek = fopen("lista_ksiazek.txt","r");

while((fscanf(lista_ksiazek,"%s",t)) != EOF) // nic nie wyświetla 
{

            dodaj_ksiazka = malloc(sizeof (ksiazka));

            fscanf(lista_ksiazek,"%s",t);

            dodaj_ksiazka->tytul=malloc(sizeof(char) * strlen(t));
            strcpy( dodaj_ksiazka->tytul, t );

            fscanf(lista_ksiazek, "%s",a);

            dodaj_ksiazka->autor=malloc(sizeof(char) * strlen(a));
            strcpy( dodaj_ksiazka->autor, a );

            fscanf(lista_ksiazek, "%d",r);

            dodaj_ksiazka->rok_wydania=malloc(sizeof(int) * r); 
            dodaj_ksiazka->rok_wydania = r;

            dodaj_ksiazka -> next = NULL;

            if (poczatek == NULL)
            {
                poczatek = dodaj_ksiazka;
                koniec = dodaj_ksiazka;
            }
            else
            {
                koniec->next = dodaj_ksiazka;
                koniec = dodaj_ksiazka;
            }

        }
        fclose(lista_ksiazek);
}
0

Jaki format ma ten plik z książkami?
Czy jest to 20 linii w formacie:
Tytuł Autor RokWydania?
W swojej pętli w linii: while((fscanf(lista_ksiazek,"%s",t)) != EOF) już wczytujesz do zmiennej tytuł. W efekcie wczytujesz kolejny łańcuch (Autor) do t oraz liczbę (Rok wydania) do zmiennej a. Wtedy próba wczytania do zmiennej r powinna zakończyć się błędnie (o ile ciąg nie zaczyna się znakiem, który można przypisać liczbie całkowitej).

Edit:
Przegapiłem kolejny problem z rokiem wydania. W strukturze trzymasz zmienną typu int*, a zmienna r jest typu int.
Kompilator gcc w tym miejscu ostrzega, że linia

  fscanf(lista_ksiazek, "%d",r);

jest niepoprawna. Próba takiego zapisu oznacza naruszenie pamięci, więc należy przekazać adres do r:

  fscanf(lista_ksiazek, "%d",&r);

Przy przypisaniu wartości r do zmiennej dodaj_ksiazka->rok_wydania jest podobna sytuacja. Należy do wartości utworzonego wskaźnika wpisać liczbę, aby faktyczny zapis był poprawny.

0

Rzeczywiście był tam problem jednak zależy mi głownie na konstrukcji pętli która będzie działać tzn wprowadzi do pamięci wszystkie dane z pliku (autor tytul rok) aktualnie wprowadza tylko jeden wiersz z 20.

0

Może nie tu jest problem. U mnie sama pętla działa bez problemu, tj. wczytuje wszystkie linie. Nie widzę reszty Twojego kodu, ale mogę wnioskować, że tam będzie problem.

0

To ostatni fragment kodu

// wyswietla elementy struktury
void screen()
{

    while(dodaj_ksiazka != NULL)
    {
        if(dodaj_ksiazka == NULL)
            printf("Baza danych jest pusta. Wprowadz dane.\n\n");
        else
            printf("%s %s %s", dodaj_ksiazka->tytul, dodaj_ksiazka->autor, dodaj_ksiazka->rok_wydania);

        dodaj_ksiazka = dodaj_ksiazka->next;
    }
}
0

Tutaj tez nic nie wyświetla.

// wyswietla elementy struktury
void screen()
{

    int i;
    for(i=1;i<=20;i++)
    {

        printf("%s %s %s", dodaj_ksiazka->tytul, dodaj_ksiazka->autor, dodaj_ksiazka->rok_wydania);

        dodaj_ksiazka = dodaj_ksiazka->next;
    }
}
0

Coś wątek umarł.
Liczyłem, że podpowiedzi @Delor będą wystarczające - uwagi są bardzo wartościowe.
Jeśli nie zmieniasz zmiennej dodaj_ksiazka po pętli wczytywania, to będzie ona wskazywała na najświeższy element Twojej listy (koniec).

0
#define IGNORE_UNTIL_NEW_LINE "%*[^\n]%*c"

typedef struct Ksiazka
{
    char *tytul;
    char *autor;
    int rok_wydania;
    struct ksiazka *next;
} Ksiazka;

void KsiazkaElementZwolnij(Ksiazka* k)
{
    if (!k) return;
    if (k->tytul) free(k->tytul);
    if (k->autor) free(k->autor);
    free(k);
}

Ksiazka* KsiazkaElementNowy(const char *tytul, const char *autor, int rok_wydania)
{
    Ksiazka* k = alloc(sizeof(Ksiazka));
    if (k) {
        k->tytul = strdup(tytul);
        k->autor= strdup(autor);
        k->rok_wydania = rok_wydania;
        k->next = NULL;
    }
    return k;
}

void KsiazkaDodaj(Ksiazka **root, const char *tytul, const char *autor, int rok_wydania)
{
    assert(root);
    Ksiazka* k = KsiazkaElementNowy(tytul, autor, rok_wydania);
    if (!k) return;
    k->next = *root;
    *root = k;
}

int KsiazkaFWczyajListe(FILE *f, Ksiazka **root)
{
    char tytul[256];
    char autor[256];
    int rok_wydania;
    while (3 == fscanf(f,
               "%255[^\n]" IGNORE_UNTIL_NEW_LINE  
               "%255[^\n]" IGNORE_UNTIL_NEW_LINE
               "%d" IGNORE_UNTIL_NEW_LINE,
               tytul, autor, &rok_wydania)) {
         KsiazkaDodaj(root, tytul, autor, rok_wydania);
    }
}

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