lista dwukierunkowa i scanf dla char C

0

Uczę się programować w C i mam do zrobienia projekt. Niestety utknęłam na samym początku tj. dodawanie elementów do listy. Po wpisaniu ciągu znaków dla el->imie_autor i/lub el->nazwisko_autor program się wysypuje. Próbowałam zrobić to na dodatkowych zmiennych i dopisać je do elementu, ale wtedy wpisywany ciąg znaków wyświetlał jedynie zmodyfikowane nazwisko z buźką.
Tutaj podaję Funkcję:

#include<stdio.h>
#include<stdlib.h>

typedef struct ObiektWypozyczenia
{
    int ID;
    char *tytul;
    char *imie_autor;
    char *nazwisko_autor;
    char *kategoria;
    char *imie_osoba;
    char *nazwisko_osoba;
    int ilosc_wyp;

    struct data_wyp
    {
        int rok, miesiac, dzien;
    };
    struct ObiektWypozyczenia *next;
    struct ObiektWypozyczenia *prev;

}dane;

dane *head = NULL;
dane *tail = NULL;

void dodaj(dane *head, int ID)
{
    dane *el = (dane*)malloc(sizeof(dane));

    printf("\nPodaj dane obiektu\n");
            unsigned int m;
        printf("\tKategoria (1.ksiazka/2.film/3.gra planszowa): ");
            scanf("%d", &m);
        if(m == 1)
        {
            el->kategoria = "ksiazka";
        }
        else if(m == 2)
        {
            el->kategoria = "film";
        }
        else if(m == 3)
        {
            el->kategoria = "gra planszowa";
        }
        else
        {
            printf("\nNieprawidlowy znak. Sprobuj ponownie.\n");
//                        return menu();
        }
        printf("\tTytul: ");
            scanf(" %s", el->tytul);
        printf("\tImie autora: ");
            scanf(" %s", el->imie_autor);
        printf("\tNazwisko autora: ");
            scanf(" %s", el->nazwisko_autor);

    if(head == NULL)
    {
        head = el;
        el->ID = ID;
       // el->imie_autor = imie_autor;
      //  el->nazwisko_autor = nazwisko_autor;
        el->next = NULL;
        el->prev = NULL;
        tail = el;
    }
    else
    {
        el->ID = ID;
     //   el->imie_autor = imie_autor;
      //  el->nazwisko_autor = nazwisko_autor;
        el->next = NULL;
        el->prev = tail;
        tail->next = el;
        tail = el;
    }
}
```
0

@Moniia: Wysypuje się, czyli?
Co się wyświetla?

0

nie wiem, zgaduje - scanf przez referencje i usun spacje, tj np scanf("%s", &el->imie_autor) - moze imie_autor nie jako wskaznik, tylko zwykla zmienna
zmiennej "imie_autor" nie ma zdefiniowanej
jesli chcesz do zmiennych tymczasowych, nie delkaruj jako wskaznik char *zmienna , tylko char zmienna i wtedy , scanf("%s",&zmienna)

1

Nie widze pamieci przydzielanej dla wskaznikow w ObiektWypozyczenia (!).
malloc na poczatku przydziela pamiec tylko do samych wskaznikow, do ktorej mozna przypisac zaallokowana pamiec dla stringow.
Na pewno nie rob tak:

jesli chcesz do zmiennych tymczasowych, nie delkaruj jako wskaznik char *zmienna , tylko char zmienna i wtedy , scanf("%s",&zmienna)

co poprawnie przydzieli pamiec tylko dla 1 znaku wiec, ale nawet 1-znakowego stringa uzytkownik nie moze wprowadzic bo juz brakuje pamieci dla znaku konca stringa.
Zamiast tego, zeby nie meczyc sie z mallocami, mozna zmienic strukture trzymajac tam tablice, np char imie_autor[64];. Tyle ze to tez nie jest poprawne (jak zgaduje ze wiekszosc uzycia scanf spotykanego w przyrodzie) dlatego ze uzytkownik moze wprowadzic wiecej niz 63 znaki i pamieci zabraknie.

(!) dla kategoria pamieci przydzielac nie trzeba. Tam przypisujesz adres do juz przydzielonej pamieci (ale kompilator, szczegolnie z odpowiednimi flagami, powinien krzyczec dlatego ze przypisujesz const char* do char*).

1

Może zapoznaj się z strdup()

char *readString(const char *prompt,size_t max_size)
{
   char fmt[8];
   char *buff=(char*)malloc(max_size+1),*ret;
   printf("%s: ",prompt);
   sprintf(fmt," %%%ds%%*s",max_size);
   scanf(fmt,buff);
   ret=strdup(buff);
   free(buff);
   return ret;
}
...
el->tytul=readString("Podaj tytul",96);
el->imie_autor=readString("Podaj imie autora",32);
0

Wszystkim dziękuję za pomoc. Udało się rozwiązać problem

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