Lista jednokierunkowa.

0

Witam, muszę napisać projekt (prosty program który umożliwia dodawanie i usuwanie wizytówek).
Jak na razie udało mi się skleić takie coś:

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

typedef struct Wizytowki
    {
        char imie[30], nazwisko[30];
        char nazwafirmy[50], branza[30];
        char telefon[15], email[50], www[30], ulica[30], nrdomu[4], pocztowy[7], miasto[20];

        struct Wizytowki *nastepny;

    } Wizytowki;


// zlicza dlugosc listy
int dlugosc_listy(Wizytowki *lista)
{
    int d = 0;
    Wizytowki *wsk = lista;
    while(wsk != NULL)
    {
              d++;
              wsk = wsk->nastepny;
              }
    return d;
    }


// dodaje nowy wezel do listy
void dodaj(Wizytowki **lista, Wizytowki *nowa)
{
     while (*lista != NULL) lista = &((*lista)->nastepny);
     *lista = nowa;
     nowa->nastepny = NULL;
}



// dodaje wizytowke do listy
void dodajWizytowke(Wizytowki **lista)
{    char line[500];
     Wizytowki* nowa = (Wizytowki*)malloc(sizeof(Wizytowki));
     printf("\nPodaj imie: ");
     scanf("%s", nowa->imie);

     printf("Podaj nazwisko: ");
     scanf("%s", nowa->nazwisko);

     printf("Podaj nazwe firmy: ");
     fflush(stdin);
     fgets(nowa->nazwafirmy, sizeof nowa->nazwafirmy, stdin);


     printf("Podaj branze: ");
     fflush(stdin);
     fgets(nowa->branza, sizeof nowa->branza, stdin);

     printf("Podaj numer telefonu: ");
     fflush(stdin);
     fgets(nowa->telefon, sizeof nowa->telefon, stdin);

     printf("Podaj email: ");
     scanf("%s", nowa->email);

     printf("Podaj adres strony www: ");
     scanf("%s", nowa->www);

     printf("Podaj adres zamiszkania: \n");
     printf("Ulica: ");
     scanf("%s", nowa->ulica);

     printf("Numer domu: ");
     scanf("%s", nowa->nrdomu);

     printf("Kod pocztowy: ");
     scanf("%s", nowa->pocztowy);

     printf("Miasto: ");
     fflush(stdin);
     fgets(nowa->miasto, sizeof nowa->miasto, stdin);



     dodaj(lista, nowa);
}



//Wypisuje cala liste
void wypisz_liste(Wizytowki *lista)
{

     Wizytowki *wsk = lista;

     if(lista == NULL)
     printf("\nLISTA JEST PUSTA");
     else
     printf("Lista zawiera %d wizytowek: \n\n", dlugosc_listy(lista) );
     int i = 1;
     while( wsk != NULL)
     {
            printf("%d. %s %s\n firma: %s branza: %s telefon: %s email: %s\n %s\n Adres:\n %s %s \n %s %s\n", i, wsk->imie, wsk->nazwisko, wsk->nazwafirmy, wsk->branza, wsk->telefon, wsk->email, wsk->www, wsk->ulica, wsk->nrdomu, wsk->pocztowy, wsk->miasto);
            wsk=wsk->nastepny;
            i++;
     }
}

//wipisuje wybrana wizytowke po imieniu
void wypisz_wizytowke_lista(Wizytowki *lista, char wyszukaj[50])
{

     Wizytowki *wsk = lista;

     if(lista == NULL)
     printf("\nLISTA JEST PUSTA");

     int i = 1;
     while( wsk != NULL )
     {
         if(wyszukaj == wsk->imie)
         {
             printf("%d. %s %s\n firma: %s branza: %s telefon: %s email: %s\n %s\n Adres:\n %s %s \n %s %s\n", i, wsk->imie, wsk->nazwisko, wsk->nazwafirmy, wsk->branza, wsk->telefon, wsk->email, wsk->www, wsk->ulica, wsk->nrdomu, wsk->pocztowy, wsk->miasto);
         }
            wsk=wsk->nastepny;
            i++;
     }
}

//Usuwa wizytowke z listy
void usun(Wizytowki **lista, int ID)
{
             Wizytowki *poprzedni = NULL;
             Wizytowki *wsk = *lista;

             int i;
             for(i = 1; i < ID; i++)
             {
                     poprzedni=wsk;
                     wsk=wsk->nastepny;

                     }
             if(poprzedni==NULL)
             {
             (*lista)=(*lista)->nastepny;
             free(wsk);
             }
             else
             {
                 poprzedni->nastepny=wsk->nastepny;
                 free(wsk);
                 }
}

//Usuwa wizytowke z listy na podstawie numeru
void usun_wizytowke(Wizytowki **lista)
{
     int ID;
     printf("Podaj numer wizytowki do usuniecia: " );
     scanf("%d", &ID);

     if((ID > dlugosc_listy(*lista)) || (ID < 1))
     {
           printf("\nNie ma takiego indeksu");

           }
     else
     {
         usun(lista,ID);
         printf("\nUsunieto wizytowke");
         }
}

//usuwa branze z listy
int usun_branza_lista(char* usbranza, Wizytowki **lista)
     {
          Wizytowki *poprzedni=NULL;
          Wizytowki *wsk= *lista;
           //strcmp porownoje napisy
          while((wsk != NULL) && ( ( strcmp(wsk->branza, usbranza)!=0) ))
          {
                     poprzedni=wsk;
                     wsk=wsk->nastepny;
          }
          if(wsk == NULL )
          {
                 return 0;
                 }
          else
          {
                 if(poprzedni==NULL)
             {
             (*lista)=(*lista)->nastepny;
             free(wsk);
             }
             else
             {
                 poprzedni->nastepny=wsk->nastepny;
                 free(wsk);
                 }
               return 1;
               }
}

//usuwa po branzy
void usun_branza(Wizytowki **lista)
{
          char usbranza[30];
          int ilosc=0;

           printf("Podaj branze do usuniecia: ");
           fflush(stdin);
           fgets(usbranza, 30, stdin);



          while(usun_branza_lista(usbranza, lista)==1)
          {
              if(usun_branza_lista(usbranza, lista))
              ilosc++;

              else
              {
                  ilosc++;
                  break;
              }

          }

          if(ilosc>=1)
          printf("Usunieto wizytowki o podanej branzy");
          else
          printf("Zadna wizytowka nie zostala usunieta poniewaz branza nie istnieje");

          }




int main()
{

    int wybor=1, ile, k;
    char szukaj[50];
    Wizytowki *lista = NULL;

printf("\n\nWitaj w programie WIZYTOWNIK");

    while(wybor != 6)
           {


printf("\n\nmozesz korzystac z nastepujacych polecen:\n\n");
printf("1.Dodaj | 2.Edytuj | 3.Usun | 4.Wyswietl wszystkie | 5.Szukaj | 6.Wyjscie\n\n");
printf("wpisz 1,2,3,4,5 lub 6\n");
scanf("%d",&wybor);


switch(wybor)
{
    case 1:
    printf("Ile wizytowek chcesz dodac?\n");
    scanf("%d",&ile);
    if(ile==0)
    break;
    for(k=0;k<ile;k++)
    dodajWizytowke(&lista);
    break;

    case 3:
    printf("Wpisz 1 jesli chcesz usuwac na podstawie numeru \nlub 2 jesli chcesz usuwac dana branze\n");
    scanf("%d",&ile);
    if(ile==1)
    usun_wizytowke(&lista);
    else if(ile==2)
    usun_branza(&lista);
    break;

    case 4:
    wypisz_liste(lista);
    break;

    case 5:
    scanf("%s",szukaj);
    wypisz_wizytowke_lista(lista, szukaj);
    break;


}
}


    return 0;
}

Mam jednak problem z funkcją wyszukującą wizytówkę po imieniu wypisz_wizytowke_lista. Co powinienem zrobić aby zaczęła działać?
Zaznaczam, że słabo jeszcze znam ten język... Z góry dzięki za pomoc ;)

2

W ten sposób nie porównujesz dwóch napisów, tylko wartości wskaźników na tablice znaków. Poczytaj o funkcji strcmp http://www.cplusplus.com/reference/cstring/strcmp/.

0

Dzięki. Wyszukiwanie już działa.

Może ktoś wie jak napisać funkcję do edytowania wizytówek?

2

Znajdz na liscie wskaznik na element ktory cie interesuje, potem zakatlizuj nowe dane.

0

tylko jak je zaktualizować?

1

Pobierasz od usera dane, przekazujesz je do funkcji aktualizujacej.
Funkcja ta znajduje odpowiedni pointer w liscie i edytuje struktury wskazywana przez niego.
np. pointer_na_strukture->dana = nowa_wartosc;

0

Ok, dzięki. Postaram się coś skleić ;)

0

Jak już pisałem, słabo ograniam C... ;)
Napisałem na razie na podstawie wcześniejszych funkcji coś takiego ale niestety wartość się nie zmienia.
Może ktoś wyjaśni co zrobiłem źle?

//edytuje wizytowke o podanym id
void edytuj(Wizytowki **lista, int ID)
{
             Wizytowki *poprzedni = NULL;
             Wizytowki *wsk = *lista;
             Wizytowki *nowa = (Wizytowki*)malloc(sizeof(Wizytowki));

             int i;
             char imie[10];
             for(i = 1; i < ID; i++)
             {
                     poprzedni=wsk;
                     wsk=wsk->nastepny;

               }

                     scanf("%s", imie);
                     nowa->imie==imie;


}


//funkcja edytujaca wizytowke
void edytuj_wizytowke(Wizytowki **lista)
{

int ID;
     printf("Podaj numer wizytowki ktora chcesz edytowac: " );
     scanf("%d", &ID);

     if((ID > dlugosc_listy(*lista)) || (ID < 1))
     {
           printf("\nNie ma takiego indeksu");

           }
     else
     {
         edytuj(lista,ID);
         printf("\nWizytowka zmieniona");
         }
}
2

nowa->imie==imie; // porównanie?

0

Została mi już tylko najtrudniejsza funkcja:

wyświetlanie wizytówek posegregowanych według nazwiska

Jak się w ogóle za to zabrać?

1

dla list najbardziej pasuje:

  • przez scalanie
  • radix
0

Może komuś się bardzo nudzi i mógłby napisać funkcję wyświetlającą wizytówki posortowane według imienia bo sam raczej nie dam rady? :D
Z góry dzięki ;)

1

to zrób to w sposób prymitywny:

  1. zliczasz ilość elementów (o ile od razu nie wiesz)
  2. przydzielasz tablice o odpowiednim rozmiarze
  3. do elementów tablicy przypisujesz wskaźniki do elementów listy
  4. odpalasz funkcję qsort
  5. wyświetlasz z tablicy
  6. usuwasz tablicę
1
Wizytowki **tm=(Wizytowki**)malloc(N*sizeof(Wizytowki*));
0

Jak mam teraz przypisać do elementów tej tablicy, wskaźniki do elementów listy?

0

Pomoże ktoś? ;D

0

Niestety wiem, że nic nie wiem... Może ktoś się nudzi sklei za mnie funkcję wyświetlającą wizytówki posortowane według imienia? :/

0

Tak powinienem dodawać wskaźniki do tabeli?

 int d=dlugosc_listy(lista);
    Wizytowki *wsk = lista;

    Wizytowki **tm=(Wizytowki**)malloc(d*sizeof(Wizytowki*));

    int i = 0;
    while(wsk != NULL)
    {

              tm[i]=wsk;
              wsk = wsk->nastepny;
              i++;


    }
1

można i tak, ale wole krótsze kody:

 int N=0,i=0;
 for(Wizytowki *wsk=lista;wsk;wsk=wsk->nastepny) ++N;
 Wizytowki **tm=(Wizytowki**)malloc(N*sizeof(Wizytowki*));
 for(Wizytowki *wsk=lista;wsk;wsk=wsk->nastepny) tm[i++]=wsk;
0

Jak się używa funkcji qsort? Posortuje ona wskaźniki dodane do tablicy na podstawie np. imienia?

0

Do czego jest te compar w tej funkcji? Może ktoś inny pomoże w zastosowaniu funkcji qsort? :D

0

A jak sobie wyobrazasz porownanie dwoch strktur?
Musisz zdefiniowac funkcja, ktora porowna po prostu. Funkcja ta ma zwracac int i pobierac 2 const void*.
W funkcji mozesz np. rzutowac to na swoj typ, porownywac lancuchy i zwracac odpowiednia wartosc.
Pozniej przekazujesz pointer do funkcji porownujacej do qsorta i tyle.

0

I powinienem dodać tam np. porównywanie imienia i później przekazać to do qsort aby posortował w tabeli?

0

Jak mam się odwołać w funkcji porównującej w jednym warunku do bieżącego i następnego elementu listy?

0

pomoże ktoś posortować? ;)

1

Dobra troche tak bardziej po przedszkolnemu.
Cel - porownanie 2 napisow.
Jako, ze C posiada funkcje porownujaca napisy to nie wiele trzeba zrobic.
strcmp(const char*, const char*).
Wywolanie:
strcmp("blabla", "lala");
Zwracana wartosc:
0 - jesli rowne.

0 - jesli pierwszy jest wiekszy.
<0 - jesli drugi jest wiekszy.
Funkcja ta porownuje po kolei odpowiadajace sobie znaki w lancuchu. Pasuje jak ulal.
Cel2 - posortowanie tablicy.
Tutaj rowniez C nie zawodzi i daje nam gotowca.
qsort(void*, unsigned, unsigned, int (cmp)(const void, const void*));
Wywolanie:
qsort(pointer, elements, size, compare_func);

Podsumowujac:
krok 1. tworzymy funkcje porownujaca:
int compare(const void* a, const void* b)
{
return strcmp((char*)a, (char*)b);
}
krok 2. wywolujemy qsort
qsort(adres_pierwszego_elementu_w_tablicy, liczba_elementow, rozmiar_elementow, funkcja_porownujaca);

1
int compare(const void* first, const void* second)
{
    return strcmp((Wizytowki*)first->imie, (Wizytowki*)second->imie);
}

int main()
{
    Wizytowki* tab[10];
    qsort(tab, 10, 30, compare);
    
    return 0;
}

P.S. nie mysle juz dzis, wiec z gory przepraszam za ew. bledy.

0

Mam taki kod ale niestety wyświetla nieposortowaną listę. Proszę o wytknięcie błędów :D

int compare(const void* first, const void* second)
{
    Wizytowki* a = (Wizytowki*)first;
    Wizytowki* b = (Wizytowki*)second;
    return strcmp((char*)a->imie, (char*)b->imie);
}

//funkcja wyswietlajacaposegregowane wizytowki
void sortuj_imie(Wizytowki *lista)
{

    int d=dlugosc_listy(lista);
    Wizytowki *wsk = lista;

    Wizytowki **tm=(Wizytowki**)malloc(d*sizeof(Wizytowki*));


    int i = 0;
    while(wsk != NULL)
    {

              tm[i]=wsk;
              wsk = wsk->nastepny;
              i++;

    }

    qsort(tm, i, sizeof(tm), compare);

    int j=0;

    while( j < i )
     {

            printf("%d. %s %s\n firma: %s branza: %s telefon: %s email: %s\n %s\n Adres:\n %s %s \n %s %s\n", j+1, tm[j]->imie, tm[j]->nazwisko, tm[j]->nazwafirmy, tm[j]->branza, tm[j]->telefon, tm[j]->email, tm[j]->www, tm[j]->ulica, tm[j]->nrdomu, tm[j]->pocztowy, tm[j]->miasto);
            j++;
     }



}
1

return strcmp(a->imie,b->imie)<0;

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