Discussione Ufficiale Programmiamo con Inforge | Esercitazione 02 in C | Livello base

Una Discussione Ufficiale punta a raccogliere tutte le informazioni su un argomento o un fatto di attualità, con costanti aggiornamenti da parte del creatore e dei partecipanti.

Dazorn

Utente Gold
23 Dicembre 2014
752
250
269
Ultima modifica:
Posto subito una bozza sbarbina che devo uscire per una mezz'oretta, quando torno spero ci sia già qualcuno che ha distrutto e pestato a sangue questo codice.
p.s. non ricordo come "cancellare" per bene quindi ho semplicemente cambiato il contatto in un campo vuoto.

C++:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
class elenco
{
        char nome[20];
        char cognome[20];
        short eta;
        public:
        void inserisci();
        void visualizza();
        void cancella();
};
void elenco::inserisci()
{
        printf("Inserisci nome: ");
        scanf("%s",&nome);
        printf("Inserisci cognome: ");
        scanf("%s",&cognome);
        printf("Inserisci eta': ");
        scanf("%d",&eta);
      

}
void elenco::visualizza()
{

        printf("\nNome: %s", nome);
        printf("\nCognome: %s", cognome);
        printf("\nEta'': %d", eta);
        
}

void elenco::cancella()
{
    nome"";
    cognome="";
    eta="";
}




main()
{
    elenco r[10];
    int x=-1,c=1;
    while(x!=3)
    {
    printf("1)Inserisci utente\n2)Ricerca utente\n3)Cancella\n4)Esci\n");
    scanf("%d",&x);
        switch(x)
        {
           case 1:
           {        
                r[c].inserisci();
                c++;
                break;
           }
           case 2:
           {
                       int cerca=0;
                       printf("\nInserisci posizione>0 del contatto da cercare:");
                       scanf("%d",&cerca);                
                    r[cerca-1].visualizza();                
                    break;        
           }
           case 3:
           {
                   int num=0;               
                   printf("\nInserisci posizione>0 del contatto da eliminare:");
                   scanf("%d",&num);
                   r[num-1].cancella();
                   break;
           }
           case 4:
           {           
            break;
           }
        }
    }
}
Il case 4 secondo me potrebbe anche non servire in questo caso (certamente non influenza le prestazioni dell'algoritmo). Normalmente si inserisce un controllo di questo tipo quando hai un while che circonda il tuo menù a console, in maniera tale da uscire dal while stesso solamente quando l'utente finisce di utilizzare l'applicazione.
Comunque la consegna chiedeva una sequenza di dimensione variabile e nel tuo caso mi sembra fissa a 10.

Devi implementare un struttura dati LISTA
 
  • Mi piace
Reactions: Valley

Sax3r28

Utente Gold
8 Aprile 2016
625
310
248
Ultima modifica:
Comunque la consegna chiedeva una sequenza di dimensione variabile e nel tuo caso mi sembra fissa a 10.
Dico subito che non ho la minima idea di come mettere qualcosa di lunghezza variabile in uno struct, quindi da buona capra metto array a lunghezza definita e pace.
Riguardo la seconda parte, praticamente deve ordinare dopo ogni inserimento? *dopo una mezz'ora passata a pensarci, ancora non mi viene in mente niente :V
 
DOWNLOAD
Supporta Inforge con una donazione

Valley

Super Moderatore
Super Moderatore
10 Aprile 2011
8,495
3,274
1,339
Non vedo l'ora di leggere le vostre soluzioni, è stupendo vedere come vi siano innumerevoli vie di risoluzione e la caccia a quella più ottimizzata è una cosa che adoro. Magari un giorno le facciamo anche per la programmazione web :rulzz:

p.s. postate le soluzioni non siate timidi, c'è solo da imparare! :D
 

JunkCoder

Moderatore
5 Giugno 2020
758
606
345
Ultima modifica:
Ecco la mia follia con le linked list:
Scusate le funzioni di getString e getInt ma senza usare le STL di C++ mi viene da bestemmiare con la commandline quindi le ho abbozzate in quel brutto modo (per qualche motivo MSVC conosce solo la getline di std).
C:
#include <stdio.h>

typedef struct
{
    char* name;
    char* lastName;
    int age;
} Person;

typedef struct LinkedNode
{
    Person val;
    LinkedNode* next;
} LinkedNode, *PersonList;

char* getString(const char* prompt)
{
    if (prompt != NULL)
        printf("%s ", prompt);

    char* str = (char*)malloc(1024);
    if (str == NULL)
        return NULL;

    do
    {
        fgets(str, 1023, stdin);

    } while (str[0] == '\n');

    int len = strlen(str);
    str[len - 1] = 0;
    return (char*)realloc(str, len);
}

int getInt(const char* prompt)
{
    if (prompt != NULL)
        printf("%s ", prompt);

    int n = 0;
    scanf("%d", &n);
    return n;
}

void free_person(Person& p)
{
    if (p.name != NULL)
        free(p.name);
    if (p.lastName != NULL)
        free(p.lastName);
}

void free_node(LinkedNode* node)
{
    if (node != NULL)
    {
        free_person(node->val);
        free(node);
    }
}

void print_person(Person& p)
{
    printf("Nome: %s \tCognome: %s \tEta': %d\n", p.name, p.lastName, p.age);
}

void print_persons(PersonList& list)
{
    LinkedNode* pNode = list;
    while (pNode != NULL)
    {
        print_person(pNode->val);
        pNode = pNode->next;
    }
}

void insert_person(PersonList& list)
{
    Person p;
    p.name = getString("Inserisci nome:");
    p.lastName = getString("Inserisci cognome:");
    p.age = getInt("Inserisci eta':");

    LinkedNode* node = (LinkedNode*)malloc(sizeof(LinkedNode));
    node->val = p;
    node->next = NULL;

    // sorting by age
    LinkedNode *prevNode, *pNode = list;
    prevNode = NULL;
    while (pNode != NULL)
    {
        if (p.age > pNode->val.age)
        {
            node->next = pNode;

            if (prevNode == NULL)
                list = node;
            else
                prevNode->next = node;
        }
        else if (pNode->next == NULL)
        {
            pNode->next = node;
            break;
        }
        prevNode = pNode;
        pNode = pNode->next;
    }

    if (list == NULL)
        list = node;
}

void find_person(PersonList& list)
{
    LinkedNode* pNode = list;

    char* search = getString("Cerca per Nome o Cognome:");
    int c = 0;

    while (pNode != NULL)
    {
        if (strstr(pNode->val.name, search) != NULL
            || strstr(pNode->val.lastName, search) != NULL)
        {
            print_person(pNode->val);
            c++;
        }
        pNode = pNode->next;
    }
  
    printf("%d risultati trovati\n", c);
    free(search);
}

void delete_person(PersonList& list)
{
    LinkedNode *prevNode, *pNode = list;

    char* name = getString("Nome da eliminare:");
    char* lastName = getString("Cognome da eliminare:");
    int c = 0;

    prevNode = NULL;

    while (pNode != NULL)
    {
        if (strcmp(pNode->val.name, name) == 0
            && strcmp(pNode->val.lastName, lastName) == 0)
        {
            if (pNode == list)
            {
                list = list->next;
                free_node(pNode);
                pNode = list;
            }
            else
            {
                prevNode->next = pNode->next;
                free_node(pNode);
                pNode = prevNode;
            }

            c++;
        }
        prevNode = pNode;
        pNode = pNode->next;
    }

    printf("%d risultati eliminati\n", c);
    free(name);
    free(lastName);
}

typedef void(*cbHandler)(PersonList& list);

typedef struct
{
    const char* Description;
    cbHandler handler;
} Action;

int esercizio2_main()
{
    PersonList list = NULL;

    const Action actions[] = {
        { "Lista persone",      print_persons },
        { "Inserisci persona",  insert_person },
        { "Ricerca",            find_person },
        { "Elimina",            delete_person }
    };

    const int nActions = (sizeof(actions) / sizeof(Action));

    printf("Menu:\n");
    for (int i = 1; i <= nActions; i++)
        printf("- [%d] %s\n", i, actions[i - 1].Description);

    printf("- [0] Esci\n\n");

    int cmd = 0;

    do
    {
        cmd = getInt(">");
      
        if (cmd < 0 || cmd > nActions)
            printf("Comando non valido\n");
        else if (cmd != 0)
            actions[cmd - 1].handler(list);

    } while (cmd > 0);

    return 0;
}

sample.png
 

Kode

Utente Emerald
10 Dicembre 2013
1,213
336
393
Ecco la mia follia con le linked list:
Scusate le funzioni di getString e getInt ma senza usare le STL di C++ mi viene da bestemmiare con la commandline quindi le ho abbozzate in quel brutto modo (per qualche motivo MSVC conosce solo la getline di std).
C:
#include <stdio.h>

typedef struct
{
    char* name;
    char* lastName;
    int age;
} Person;

typedef struct LinkedNode
{
    Person val;
    LinkedNode* next;
} LinkedNode, *PersonList;

char* getString(const char* prompt)
{
    if (prompt != NULL)
        printf("%s ", prompt);

    char* str = (char*)malloc(1024);
    if (str == NULL)
        return NULL;

    do
    {
        fgets(str, 1023, stdin);

    } while (str[0] == '\n');

    int len = strlen(str);
    str[len - 1] = 0;
    return (char*)realloc(str, len);
}

int getInt(const char* prompt)
{
    if (prompt != NULL)
        printf("%s ", prompt);

    int n = 0;
    scanf("%d", &n);
    return n;
}

void free_person(Person& p)
{
    if (p.name != NULL)
        free(p.name);
    if (p.lastName != NULL)
        free(p.lastName);
}

void free_node(LinkedNode* node)
{
    if (node != NULL)
    {
        free_person(node->val);
        free(node);
    }
}

void print_person(Person& p)
{
    printf("Nome: %s \tCognome: %s \tEta': %d\n", p.name, p.lastName, p.age);
}

void print_persons(PersonList& list)
{
    LinkedNode* pNode = list;
    while (pNode != NULL)
    {
        print_person(pNode->val);
        pNode = pNode->next;
    }
}

void insert_person(PersonList& list)
{
    Person p;
    p.name = getString("Inserisci nome:");
    p.lastName = getString("Inserisci cognome:");
    p.age = getInt("Inserisci eta':");

    LinkedNode* node = (LinkedNode*)malloc(sizeof(LinkedNode));
    node->val = p;
    node->next = NULL;

    // sorting by age
    LinkedNode *prevNode, *pNode = list;
    prevNode = NULL;
    while (pNode != NULL)
    {
        if (p.age > pNode->val.age)
        {
            node->next = pNode;

            if (prevNode == NULL)
                list = node;
            else
                prevNode->next = node;
        }
        else if (pNode->next == NULL)
        {
            pNode->next = node;
            break;
        }
        prevNode = pNode;
        pNode = pNode->next;
    }

    if (list == NULL)
        list = node;
}

void find_person(PersonList& list)
{
    LinkedNode* pNode = list;

    char* search = getString("Cerca per Nome o Cognome:");
    int c = 0;

    while (pNode != NULL)
    {
        if (strstr(pNode->val.name, search) != NULL
            || strstr(pNode->val.lastName, search) != NULL)
        {
            print_person(pNode->val);
            c++;
        }
        pNode = pNode->next;
    }
 
    printf("%d risultati trovati\n", c);
    free(search);
}

void delete_person(PersonList& list)
{
    LinkedNode *prevNode, *pNode = list;

    char* name = getString("Nome da eliminare:");
    char* lastName = getString("Cognome da eliminare:");
    int c = 0;

    prevNode = NULL;

    while (pNode != NULL)
    {
        if (strcmp(pNode->val.name, name) == 0
            && strcmp(pNode->val.lastName, lastName) == 0)
        {
            if (pNode == list)
            {
                list = list->next;
                free_node(pNode);
                pNode = list;
            }
            else
            {
                prevNode->next = pNode->next;
                free_node(pNode);
                pNode = prevNode;
            }

            c++;
        }
        prevNode = pNode;
        pNode = pNode->next;
    }

    printf("%d risultati eliminati\n", c);
    free(name);
    free(lastName);
}

typedef void(*cbHandler)(PersonList& list);

typedef struct
{
    const char* Description;
    cbHandler handler;
} Action;

int esercizio2_main()
{
    PersonList list = NULL;

    const Action actions[] = {
        { "Lista persone",      print_persons },
        { "Inserisci persona",  insert_person },
        { "Ricerca",            find_person },
        { "Elimina",            delete_person }
    };

    const int nActions = (sizeof(actions) / sizeof(Action));

    printf("Menu:\n");
    for (int i = 1; i <= nActions; i++)
        printf("- [%d] %s\n", i, actions[i - 1].Description);

    printf("- [0] Esci\n\n");

    int cmd = 0;

    do
    {
        cmd = getInt(">");
     
        if (cmd < 0 || cmd > nActions)
            printf("Comando non valido\n");
        else if (cmd != 0)
            actions[cmd - 1].handler(list);

    } while (cmd > 0);

    return 0;
}

View attachment 50763


Perfetto, uso magistrale delle liste puntate. Se devo dire un modo per migliorare il codice, l'unica cosa che mi viene in mente è quello di inserire una Head al PersonList in modo da piazzarci anche un contatore del numero di Persone e monitorarne il numero, questo perchè se si ha una lista molto grande, risulterebbe difficile capire se l'eliminazione o l'inserimento sono avvenuti con successo o meno (ovviamente il counter lo stampi all'interno della funzione print_persons).
 
DOWNLOAD

DispatchCode

Moderatore
24 Maggio 2016
392
263
193
@Sax3r28

Perchè non stai "includendo" il namespace, dovresti fare using namespace std; oppure quando definisci la stringa usare std::. Quindi ad esempio std::string nome;. ;)
In C++ per distruggere la memoria allocata esistono i distruttori. Per vedere come si utilizzano https://en.cppreference.com/w/cpp/language/destructor

Poi fai attenzione ad un'altra cosa: stai usando un array di oggetti di tipo elenco, quindi quando elimini una persona... dovresti trovare un modo per "compattare" il tuo array, così da non avere buchi.

Anche nei case 2 e 3, attenzione: dovresti verificare il valore inserito, altrimenti andresti fuori dai limiti dell'array.

Ultima cosa: l'elenco di persone non dovrebbe avere una lunghezza definita. Prova a modificare l'algoritmo così da accettare più di 10 persone. ;)

@JunkCoder
C'è poco da dire, non ho considerazioni da fare, bel lavoro.
 
  • Love
Reactions: Not an engineer

Dazorn

Utente Gold
23 Dicembre 2014
752
250
269
Ultima modifica:
Eccomi qui con la mia versione. Ho utilizzato una lista ordinata bidirezionale.
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MODE_INSERT 0
#define MODE_FIND 1
#define MODE_REMOVE 2

struct Person
{
  char* name;
  char* last_name;
  int age;
};

struct LLNode
{
  struct Person data;
  struct LLNode *next;
  struct LLNode *prev;
};

struct LLNode *head = NULL;
int LLSize = 0;

void clean_input_buffer()
{
  char c;
  while ((c = getchar()) != '\n' && c != EOF);
}

void pause()
{
  printf("\n\nPremere un tasto per continuare.. ");
  getchar();
}

int get_int(char* message)
{
  int input = 0;

  printf("\n%s:\t", message);
  scanf("%d", &input);

  clean_input_buffer();

  return input;
}

char* get_string(char* message)
{
  char* input = (char*)malloc(1024);

  printf("\n%s:\t", message);
  scanf("%[^\n]%*c", input);

  int len = strlen(input);
  input[len] = 0;

  return (char*)realloc(input, len + 1);
}

void print_list()
{
  struct LLNode *node = head;

  printf("\n\nLISTA PERSONE (%d):", LLSize);

  while(node != NULL)
  {
    printf("\n%s\t%s\t%d", node->data.name, node->data.last_name, node->data.age);

    node = node->next;
  }
}

struct Person insert_person(char* name, char* last_name, int age)
{
  struct Person person;
  person.name = name;
  person.last_name = last_name;
  person.age = age;

  struct LLNode *new_node = (struct LLNode*)malloc(sizeof(struct LLNode));
  new_node->data = person;

  if(head == NULL)
  {
    head = new_node;
  }
  else
  {
    struct LLNode *node = head;
    int index = 0;

    while(node != NULL)
    {
      if(node->data.age < new_node->data.age)
      {
        new_node->next = node;
        node->prev = new_node;

        if(index == 0)
        {
          head = new_node;
        }

        break;
      }

      if(node->next == NULL)
      {
        node->next = new_node;
        break;
      }

      node = node->next;
      index++;
    }
  }

  LLSize++;

  return person;
}

void find_people(char* name, char* last_name)
{
  struct LLNode *node = head;

  printf("\n\nRISULTATI:");

  while(node != NULL)
  {
    if(strstr(node->data.name, name) ||
      strstr(node->data.last_name, last_name))
    {
      printf("\n%s\t%s\t%d", node->data.name, node->data.last_name, node->data.age);
    }

    node = node->next;
  }
}

struct Person* remove_person(char* name, char* last_name)
{
  struct Person *person = NULL;
  int index = 0;
  struct LLNode *node = head;

  while(node != NULL)
  {
    if(strstr(node->data.name, name) &&
      strstr(node->data.last_name, last_name))
    {
      person = &node->data;

      if(index == 0)
      {
        if(LLSize > 1)
        {
          head = node->next;
        }
        else {
          head = NULL;
        }
      }
      else
      {
        if(index < LLSize - 1)
        {
          node->prev->next = node->next;
          node->next->prev = node->prev;
        }
        else
        {
          node->prev->next = NULL;
        }
      }

      LLSize--;

      break;
    }

    node = node->next;
    index++;
  }

  return person;
}

void ask_person(int mode)
{
  char* name;
  char* last_name;
  int age;

  switch(mode)
  {
    case MODE_INSERT:
      printf("\n\nINSERIMENTO NUOVA PERSONA\n");
   
      name = get_string("DIGITARE IL NOME");
      last_name = get_string("DIGITARE IL COGNOME");
      age = get_int("DIGITARE L'ETA'");

      struct Person inserted = insert_person(name, last_name, age);

      printf("\n%s %s INSERITO!", inserted.name, inserted.last_name);

      print_list();
      break;
    case MODE_FIND:
      printf("\n\nRICERCA PERSONA\n");
   
      name = get_string("DIGITARE IL NOME");
      last_name = get_string("DIGITARE IL COGNOME");

      find_people(name, last_name);
      break;
    case MODE_REMOVE:
      printf("\n\nRIMOZIONE PERSONA\n");
   
      name = get_string("DIGITARE IL NOME");
      last_name = get_string("DIGITARE IL COGNOME");

      struct Person *removed = remove_person(name, last_name);

      if(removed == NULL)
      {
        printf("\nNESSUNA PERSONA TROVATA!");
        break;
      }

      printf("\n%s %s RIMOSSO!", removed->name, removed->last_name);

      print_list();
      break;
  }
}

int main() {
    int action;
 
    do
    {
      action = -1;
      system("clear");

      printf("__________ MENU __________\n\n");
      printf("1. Inserisci una persona\n");
      printf("2. Cerca delle persone\n");
      printf("3. Rimuovi una persona\n");
      printf("0. Esci\n");
      printf("__________________________\n");

      action = get_int("SELEZIONARE UN OPERAZIONE");

      switch(action)
      {
        case 1:
          ask_person(MODE_INSERT);
          break;
        case 2:
          ask_person(MODE_FIND);
          break;
        case 3:
          ask_person(MODE_REMOVE);
          break;
      }

      if(action < 0 || action > 3)
      {
        printf("\nOPERAZIONE NON VALIDA!");
        action = 1;
      }

      if(action != 0)
      {
        pause();
      }
    } while (action > 0);

    printf("\nADDIO!");
    return action;
}

Alcuni screenshot dell'esecuzione:

1615376215342.png
1615376257499.png
1615376286741.png

1615376315289.png
1615376599919.png
 
Banner pubblicitario per Bright Data su Inforge.net azienda di vendita Proxy, Data Collector e Content Unlocker
DOWNLOAD

Sax3r28

Utente Gold
8 Aprile 2016
625
310
248
Ultima modifica:
@Sax3r28

Perchè non stai "includendo" il namespace, dovresti fare using namespace std; oppure quando definisci la stringa usare std::. Quindi ad esempio std::string nome;. ;)
In C++ per distruggere la memoria allocata esistono i distruttori. Per vedere come si utilizzano https://en.cppreference.com/w/cpp/language/destructor
Ho provato a metterlo sia dentro lo struct che fuori, sotto gli include, ma continuava questi errori:
expected nsted-name-specifier before namespace
'string' does not name a type

Questo funziona se scritto a sé
C++:
int main()
{
    using namespace std;

    string prova="ciao";
    printf("%s",prova.c_str());
}
Crea la string, la stampa e tutto bene, nell'altro codice invece non ne voleva sapere.

Per il distruttore ho controllato anche delle slide mie e ho trovato qualcosa, ma così a prima vista non ci sto capendo molto(e nell'esempio la creazione del vettore è sempre a lunghezza definita, quindi non mi aiuta molto). Praticamente basta creare questo ~nomeClasse e metterci dentro delete [] nomearray;? Questo poi scala gli elementi in automatico o va fatto in seguito?
Un'altra cosa che mi è venuta in mente adesso vedendo tutti sti *, usando i puntatori non serve passare le variabili alle funzioni giusto?
Poi fai attenzione ad un'altra cosa: stai usando un array di oggetti di tipo elenco, quindi quando elimini una persona... dovresti trovare un modo per "compattare" il tuo array, così da non avere buchi.
Per quello ho spizzicato file che scrissi quando ancora andavo a scuola :rofl: e ho trovato questo
C++:
void azzera(int v[], int k)
{
    int *p;
    p= &v[0];
    for(int i=0;i<k;i++)
    {
        p= &v[i];
        *p=0;
    }
}
Può servirmi? O serve qualcosa che proprio pulisce dov'è stato allocato il valore e scala tutto di una posizione?
Anche nei case 2 e 3, attenzione: dovresti verificare il valore inserito, altrimenti andresti fuori dai limiti dell'array.
Un while input<0 && input >x(che dovrebbe essere sì dinamico ma sto pian piano sbloccando tutti i ricordi) può bastare?
Ultima cosa: l'elenco di persone non dovrebbe avere una lunghezza definita. Prova a modificare l'algoritmo così da accettare più di 10 persone. ;)
Sempre spulciando ho trovato questo, potrebbe andare? Ovviamente ritoccandolo per adattarlo alle richieste.
Anche se ora che lo leggo bene anche questo è a lunghezza definita. Probabilmente è pure una roba semplice da scrivere per fare sto struct dinamico, ma proprio non mi viene in mente.
C++:
struct elemento *crea_lista()
{
   struct elemento *p, *punt;
   int i, n;
   printf("\n Specificare il numero di elementi: ");
   scanf("%d", & n);
   if(n==0)
   {
   p = NULL; // lista vuota
   }
   else
   {
      /* creazione primo elemento */
    p = (struct elemento *)malloc(sizeof(struct elemento));
    printf("\nInserisci il primo valore: ");
    scanf("%d", & p->inf);
    punt = p;




// CREAZIONE ELEMENTI SUCCESSIVI
      for(i=2; i<=n; i++)
      {
         punt->pun = (struct elemento *)malloc(sizeof(struct elemento));
         punt = punt->pun;
         printf("nInserisci il %d elemento: ", i);
         scanf("%d", & punt->inf);
      } // chiudo il for
      punt->pun = NULL; // marcatore fine lista
   } // chiudo l'if-else
   return(p);
} // chiudo la funzione

Ovviamente @Not an engineer se puoi indirizzarmi pure te :frog-good:
 
  • Mi piace
Reactions: Valley

demtor

Utente Emerald
1 Giugno 2015
750
909
418
Pubblico la mia soluzione too (fatta un po' di fretta)

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

#define SIZE 30

typedef struct Persona
{
    char name[SIZE];
    char last_name[SIZE];
    unsigned int age;

    struct Persona* next;
} Persona;


void printPersona(Persona* node)
{
    if (node == NULL)
        return;

    printf(
        "Name: %s, Last Name: %s, Age: %u\n",
        node->name,
        node->last_name,
        node->age
    );
}

void printPersonaList(Persona* head)
{
    printf("\nBEGIN LIST\n");
    while (head != NULL)
    {
        printPersona(head);
        head = head->next;
    }
    printf("END LIST\n\n");
}

void freePersona(Persona* node)
{
    free(node);
}

void freePersonaList(Persona* head)
{
    while (head != NULL)
    {
        Persona* temp = head;
        head = head->next;

        freePersona(temp);
    }
}

Persona* insert(Persona** head, char name[], char last_name[], int age)
{
    Persona* newNode = malloc(sizeof(Persona));

    strcpy(newNode->name, name);
    strcpy(newNode->last_name, last_name);
    newNode->age = age;
    newNode->next = NULL;

    // forse c'è un modo migliore per farlo ma non ho voglia di pensarci
    if (*head == NULL || (*head)->age < newNode->age)
    {
        newNode->next = *head;
        *head = newNode;
    }
    else
    {
        Persona* previous = *head;
        Persona* current = (*head)->next;

        while (current != NULL) {
            if (current->age < newNode->age) {
                previous->next = newNode;
                newNode->next = current;
                break;
            }

            previous = current;
            current = current->next;
        }

        // tail insert
        if (newNode->next == NULL)
            previous->next = newNode;
    }

    return newNode;
}

Persona* searchByName(Persona* head, char name[])
{
    while (head != NULL) {
        if (strcmp(name, head->name) == 0)
            break;

        head = head->next;
    }

    return head;
}

void deleteByName(Persona** head, char name[])
{
    if (*head == NULL)
        return;

    if (strcmp(name, (*head)->name) == 0) {
        Persona* temp = *head;
        *head = (*head)->next;

        freePersona(temp);
    } else {
        Persona* previous = *head;
        Persona* current = (*head)->next;

        while (current != NULL && strcmp(name, current->name) != 0) {
            previous = current;
            current = current->next;
        }

        if (current) {
            previous->next = current->next;
            freePersona(current);
        }
    }
}

int main()
{
    Persona* head = NULL;
    Persona* temp = NULL;

    temp = insert(&head, "nome1", "cognome1", 15);
    printPersona(temp);

    temp = insert(&head, "nome2", "cognome2", 24);
    printPersona(temp);

    temp = insert(&head, "nome3", "cognome3", 17);
    printPersona(temp);

    char nome4[] = "nome4";
    temp = insert(&head, nome4, "cognome4", 13);
    printPersona(temp);

    printPersonaList(head);

    temp = searchByName(head, "nome3");
    printPersona(temp);

    temp = searchByName(head, "nome0"); // invalid name
    printPersona(temp);

    deleteByName(&head, "nome4");
    deleteByName(&head, "nome2"); // delete HEAD
    deleteByName(&head, "nome0"); // invalid name;

    printPersonaList(head);

    freePersonaList(head);

    return 0;
}

Output:

1615384856394.png
 

DispatchCode

Moderatore
24 Maggio 2016
392
263
193
@Dazorn
Ben fatto. Ma giusto per cercare il pelo nell'uovo, ti segnalo un paio di cose.
  1. Guardando il codice non mi è sembrato di aver visto l'inserimento con ordinamento
  2. Non liberi mai la memoria allocata, nè sulle stringhe nè rispetto agli elementi della lista
  3. usi system("clear"); che non è portabile (ma in effetti non ci sono molte alternative valide)


@Sax3r28
Prendendo sempre il codice che hai pubblicato ieri, questo funziona:

C++:
class elenco
{
        std::string nome;
        std::string cognome;
        short eta;
        public:
        void inserisci();
        void visualizza();
        void cancella();
};

Comunque se usi C++, puoi usarlo "fino in fondo" ;)
Quindi ad esempio scrivendo:
C++:
using namespace std;

int main()
{
string prova="ciao";
cout << prova;
}

Per il distruttore ho controllato anche delle slide mie e ho trovato qualcosa, ma così a prima vista non ci sto capendo molto(e nell'esempio la creazione del vettore è sempre a lunghezza definita, quindi non mi aiuta molto). Praticamente basta creare questo ~nomeClasse e metterci dentro delete [] nomearray;? Questo poi scala gli elementi in automatico o va fatto in seguito?

Ti faccio un esempio con una classe simile alla tua (premetto di non conoscere bene C++ e di non usarlo da qualche anno):
C++:
#include <iostream>

class Person {
    private:
        std::string name;
        std::string last_name;
        int age;
        
    public:
        Person(std::string name, std::string last_name, int age) { 
            this->name = name;
            this->last_name = last_name;
            this->age = age;
        }
    
        void printPerson() {
            std::cout << this->name << " " << this->last_name << " " << age << std::endl;
        }
};

int main() {
    Person **person = new Person*[10]; // Ho scelto 10 elementi
    
    for(int i=0; i<10; i++) {
        person[i] = new Person("Name" , "Last Name", i+1);
    }
    
    for(int i=0; i<10; i++) {
        person[i]->printPerson();
    }
    return 0;
}

Un altro esempio:
C++:
#include <iostream>

class Person {
    private:
        std::string name;
        std::string last_name;
        int age;
        
    public:
        Person() {}
        
        Person(std::string name, std::string last_name, int age) { 
            this->name = name;
            this->last_name = last_name;
            this->age = age;
        }
    
        void printPerson() {
            std::cout << this->name << " " << this->last_name << " " << age << std::endl;
        }
};

int main() {
    Person *person = new Person[10]; // Ho scelto 10 elementi
    
    for(int i=0; i<10; i++) {
        person[i] = Person("Name" , "Last Name", i+1);
    }
    
    for(int i=0; i<10; i++) {
        person[i].printPerson();
    }
    return 0;
}

Una dimensione iniziale dovrai comunque darla in quanto l'array è statico, come in C (e non solo); dovrai ridimensionarlo tu "manualmente".

Normalmente in C++ per cose come queste usi i vector, non gli array (il vector viene ridimensionato in automatico "internamente"). Quindi volendo potresti anche usare un vector; ovviamente sarebbe più semplice rispetto a una soluzione in C dove è necessario gestire anche le riallocazioni. ;)
Questo è un esempio con un vector:
C++:
#include <iostream>
#include <vector>

class Person {
    private:
        std::string name;
        std::string last_name;
        int age;
        
    public:
        Person(std::string name, std::string last_name, int age) { 
            this->name = name;
            this->last_name = last_name;
            this->age = age;
        }
    
        void printPerson() {
            std::cout << this->name << " " << this->last_name << " " << age << std::endl;
        }
};

int main() {
    std::vector<Person> person;
    
    for(int i=0; i<10; i++) {
        person.push_back(Person("Name" , "Last Name", i+1));
    }
    
    for(int i=0; i<10; i++) {
        person[i].printPerson();
    }
    return 0;
}

Ti ho fatto fare un pò di confusione io, mea culpa. Se usi un array, non puoi rimpicciolirlo eliminando un elemento.
L'operatore delete a cui fai riferimento libera (dealloca) la memoria; prima di questo però viene invocato il distruttore, se è definito (e se si tratta di una classe).

Un'altra cosa che mi è venuta in mente adesso vedendo tutti sti *, usando i puntatori non serve passare le variabili alle funzioni giusto?

Non ho capito bene che intendi...

Un while input<0 && input >x(che dovrebbe essere sì dinamico ma sto pian piano sbloccando tutti i ricordi) può bastare?

Certo ;)

In merito all'altra questione: se vuoi usare C++, allora usa direttamente vector e amen, a mio avviso è meglio se non vai a "mischiare" le cose.

@demtor
Ho guardato solo velocemente la tua soluzione (non ho più tempo), ma direi sia ben fatta. ;)



Vedo che tutti quanti avete usato bene o male una lista... nessuno ha voglia di provare altre soluzioni?
 
DOWNLOAD
Banner pubblicitario per Bright Data su Inforge.net azienda di vendita Proxy, Data Collector e Content Unlocker