Esercizio C: array di strutture allocate dinamicamente

di il
19 risposte

Esercizio C: array di strutture allocate dinamicamente

Testo:
Scrivere un programma C che legga da un file di testo "persone.txt" tutti i dati contenuti all'interno, che sono del tipo "nome cognome eta" come nel seguente esempio:

Matteo Pupo 20
Asdrubale Pinco 16
Genoveffa Croce 25
Steve Jobs 56
Mario Rossi 14

Il programma deve creare un array di strutture (allocato dinamicamente con la dimensione necessaria) e successivamente deve stampare a video l'array di strutture così creato, infine deve stampare a video il nome, il cognome ed età della persona, o delle persone se sono più di una, di età massima.
Si assuma che di alcune persone si possa essere ignota l'eta, nel qual caso il dato memorizzato deve essere pari al valore "1000".

Il file txt è il seguente
Matteo Pupo 20
Asdrubale Pinco 16
Genoveffa Croce 25
Steve Jobs 56
Mario Rossi 14
struct:

struct persona{
  char nome[LEN + 1];
  char cognome[LEN + 1];
  int eta;
  struct persona *next;
};
main:

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

//definizioni di tipo
#define NOME_FILE "persone.txt"
#define ETA_MANCANTE 1000
#define LEN 22

struct persona{
  char nome[LEN + 1];
  char cognome[LEN + 1];
  int eta;
  struct persona *next;
};

struct persona *list = NULL;  //creo una lista


//prototipi di funzione
void riempilista(struct persona** list, FILE* in);
void stampalista(struct persona* list);
//int etamassina(struct persona* list);
//void cercostampo(struct persona* list, int etamax);

int main(int argc, char *argv[])
{

    FILE *in; // dichiaro un puntatore a file
  //  int etamax;

    in = fopen(NOME_FILE, "r"); //apro il file in lettura binaria

    if(in == NULL) // controllo apertura file
    {
        printf("Il file %s non può essere aperto!\n", NOME_FILE);
        exit(EXIT_FAILURE);
    }
    else  // il file si è aperto correttamente
    {
        riempilista(&list, in);
        stampalista(list);

/*        printf("\n\nLe persone con eta' massima sono: \n");
        etamax = etamassina(list);
        cercostampo(list, etamax);*/
        fclose(in);
    }
    return 0;
}
Funzione riempilista:

void riempilista(struct persona** list, FILE* in)
{
    struct persona *new_node; // creo un nuovo nodo

    *list = malloc(sizeof(struct persona)); // alloco la memoria dinamicamente per il nuovo nodo

    new_node = *list;

    char str[LEN * 3];
    char* token;

    do
    {
        //leggo i dati e li salvo nella lista
        fgets(str, sizeof(str), in);

        //suddivido la stringa in parole
        token = strtok(str, " ");
        printf("La stringa è': %s\n", token);
        strcpy(new_node->nome, token);

        token = strtok(NULL, " ");
        printf("La stringa è': %s\n", token);
     //   strcpy(new_node->cognome, token);

        token = strtok(NULL, " ");
        printf("La stringa è': %s\n", token);
        //controllo se il campo eta è vuoto
//        if(isspace(token))
//            new_node->eta = 1000;
//        else
        //    new_node->eta = atoi(token);


        if(feof(in))
            new_node->next = NULL;
        else
        {
            new_node->next = malloc(sizeof(struct persona));
            new_node = new_node -> next;
        }
    }while(!feof(in));

}
Funzione stampa lista:

void stampalista(struct persona* list)
{
    printf("_______________________________");

    while (list != NULL)
    {
        printf("%s %s %d\n", list->nome, list->cognome, list->eta);
        list = list -> next;
    }
}

ho inserito le stringhe :
printf("La stringa è': %s\n", token);
per verificare se il token andava bene.. è sembra che funzioni...
ma non appena decommento la seconda copia di stringa:
strcpy(new_node->cognome, token);
se eseguo il programma mi esce la scritta
"Segmentation fault (core dumped)" e devo chiudere l'applicazione.
Non so in cosa sbaglio..
Grazie per gli eventuali aiuti

19 Risposte

  • Re: Esercizio C: array di strutture allocate dinamicamente

    Mah ... ho compilato ed eseguito e non ho avuto errori ... la visualizzazione dei dati era corretta.

    Non ho visto il codice ma se stai compilando con DevC++/mingw ti consiglio prima di provare con un altro compilatore.
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Utilizzo Codeblocks, questo codice non da errore, perchè è commentato..
    Nel momento in cui decommenti la seconda riga
    strcpy(new_node->cognome, token);

    dovrebbe dar l'errore che ho segnalato
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Ho eliminato il commento da quella riga e anche da quella dell'età ... il risultato è corretto

    La stringa Þ': Matteo
    La stringa Þ': Pupo
    La stringa Þ': 20

    La stringa Þ': Asdrubale
    La stringa Þ': Pinco
    La stringa Þ': 16

    La stringa Þ': Genoveffa
    La stringa Þ': Croce
    La stringa Þ': 25

    La stringa Þ': Steve
    La stringa Þ': Jobs
    La stringa Þ': 56

    La stringa Þ': Mario
    La stringa Þ': Rossi
    La stringa Þ': 14
    _______________________________Matteo Pupo 20
    Asdrubale Pinco 16
    Genoveffa Croce 25
    Steve Jobs 56
    Mario Rossi 14

    A parte CodeBlocks (che è l'IDE) stai usando mingw come compilatore? Come ti dicevo, prova ad usarne un altro.
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Ho riscritto il codice su windows... su linux dava quel problema... ora funziona.. solo una cosa se non chiedo troppo...
    dovrei fare il controllo nel caso manca l'età porla uguale a 1000.. ma non sto riuscendo.. forse sto sbagliando il controllo..
    
    void riempilista(struct persona** list, FILE* in)
    {
        struct persona *new_node; // creo un nuovo nodo
    
        *list = malloc(sizeof(struct persona)); // alloco la memoria dinamicamente per il nuovo nodo
    
        new_node = *list;
    
        char str[LEN * 3];
        char* token;
    
        do
        {
            //leggo i dati e li salvo nella lista
            fgets(str, sizeof(str), in);
    
            //suddivido la stringa in parole
            token = strtok(str, " ");
            printf("La stringa e': %s\n", token);
            strcpy(new_node->nome, token);
    
            token = strtok(NULL, " ");
            printf("La stringa e': %s\n", token);
            strcpy(new_node->cognome, token);
    
            token = strtok(NULL, " ");
            printf("La stringa e': %s\n", token);
            //controllo se il campo eta è vuoto
            if(strcmp(token, " ") == 0)
                new_node->eta = 1000;
            else
                new_node->eta = atoi(token);
    
    
            if(feof(in))
                new_node->next = NULL;
            else
            {
                new_node->next = malloc(sizeof(struct persona));
                new_node = new_node -> next;
            }
        }while(!feof(in));
    
    }
    
    Ovviamente ho provato a togliere un età nel file txt
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Non è chiaro ... è nel file che c'è scritto 1000 ?
  • Re: Esercizio C: array di strutture allocate dinamicamente

    No.. L'esercizio richiede che nel caso l'età mancasse io devo inserire il valore 1000..
    Quindi per esempio se modifico il file txt togliendo su Giuseppe verdi l'età.. Io devo porla uguale a 1000
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Allora devi leggere il token e controllare che inizi per cifra o per lettera ...
  • Re: Esercizio C: array di strutture allocate dinamicamente

    E' proprio quello che non sto riuscendo a fare ..
    ho provato con :
    
    token = strtok(NULL, " ");
    printf ("La stringa e': %s\n", token);
    new_node->eta = atoi(token);
    
    //controllo se il campo è vuoto
    
    if(!isdigit(new_node-eta))
         new_node->eta = 1000;
    
    
    ma non funziona.. sapresti indicarmi che funzione dovrei utilizzare?
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Devi eseguire la atoi solo se il primo carattere è una cifra, altrimenti metti il valore a 1000.
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Mettendo questo controllo
    token = strtok(NULL, " ");
    printf("La stringa e': %s\n", token);

    //controllo se il campo eta è vuoto
    if(isalpha(token))
    new_node->eta = atoi(token);
    else
    new_node->eta = 1000;
    La funziona stampalista mi stampa tutti valori a 1000.
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Puoi scrivere

    if(token)
    new_node->eta = atoi(token);
    else
    new_node->eta = 1000;
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Avevo provato anche con questo codice...

    Ora l'ho rimesso al posto del mio controllo... solo che al posto dell'eta mancante mi inserisce uno 0 invece del valore 1000 ..
  • Re: Esercizio C: array di strutture allocate dinamicamente

    Ma come è scritto il file di testo ?
  • Re: Esercizio C: array di strutture allocate dinamicamente

    E' scritto su un semplice file .txt.

    Questi sono i dati :
    
    Matteo Pupo 20
    Asdrubale Pinco 16
    Genovella Croce 
    Steve Jobs 56
    Mario Rossi 14
    
    Su genovella ho tolto l'eta.
Devi accedere o registrarti per scrivere nel forum
19 risposte