[C] salvare una struttura in un vettore

kokoko1
Ciao ragazzi. come da titolo non mi è ben chiaro se è possibile, e se in caso affermativo, come salvare una struttura dati in un vettore.
Vi posto il codice su cui stavo lavorando:
#include <stdio.h>
#include <stdlib.h>
#define DIM 20

struct persona {
       int eta;
       int matricola;
       } pers;
       struct persona pers2;
main()
{
     int v[DIM];
     int i;

       printf("eta: ");
       scanf("%d", &pers.eta);
       printf("matricola: ");
       scanf("%d", pers.matricola);
       printf("eta: ");
       scanf("%d", &pers2.eta);
       printf("matricola: ");
       scanf("%d", pers2.matricola);
      
       system("PAUSE");
       return 0;
       }

Sapendo che una struttura è "una collezione finita di variabili identificata da un nomeVariabile", in questo caso "pers" e "pers2", ho pensato che fosse lecito e, dunque possibile, salvare ogni struttura in un vettore, v[0] v[1]...., come fosse una "semplice" variabile, utilizzando un ciclo for, ma credo che il mio pensiero faccia acqua perchè ho avuto problemi nell'operazione.
Spero possiate chiarirmi questi dubbi e risolvere il problema. Vi ringrazio.

Risposte
_overflow_1
Ciao!!!

Certo che puoi farlo, non devi far altro che dichiarare un vettore di tipo struct persona, ti propongo un esempio:


#include <stdio.h>
#include <stdlib.h>
#define DIM 4

struct persona {
    int eta;
    int matricola;
};

int main()
{
    struct persona v[DIM];
    int i;

    //acquisizione
    for(i=0; i<DIM; i++){
        printf("eta: ");
        scanf("%d", &v[i].eta);
        printf("matricola: ");
        scanf("%d", &v[i].matricola);
    }

    //stampa
    printf("\n\nStampa dei valori appena inseriti: \n\n");
    for(i=0; i<DIM; i++){
        printf("\neta: %d", v[i].eta);
        printf("\nmatricola: %d\n\n", v[i].matricola);
    }

    system("PAUSE");
    return 0;
}


Se c'è qualcosa che non ti è chiara, chiedi pure.

kokoko1
"_overflow_":
Ciao!!!

Certo che puoi farlo, non devi far altro che dichiarare un vettore di tipo struct persona, ti propongo un esempio:


#include <stdio.h>
#include <stdlib.h>
#define DIM 4

struct persona {
    int eta;
    int matricola;
};

int main()
{
    struct persona v[DIM];
    int i;

    //acquisizione
    for(i=0; i<DIM; i++){
        printf("eta: ");
        scanf("%d", &v[i].eta);
        printf("matricola: ");
        scanf("%d", &v[i].matricola);
    }

    //stampa
    printf("\n\nStampa dei valori appena inseriti: \n\n");
    for(i=0; i<DIM; i++){
        printf("\neta: %d", v[i].eta);
        printf("\nmatricola: %d\n\n", v[i].matricola);
    }

    system("PAUSE");
    return 0;
}


Se c'è qualcosa che non ti è chiara, chiedi pure.

Ti ringrazio per l'intervento, il codice è molto chiaro, ma mi sfugge il motivo per cui hai cancellato il nomeVariabile "pers" nella struct persona. Non è necessario?
Inoltre, eseguendo il programmino, vedo che acquisisce la struttura uno dietro l'altra per l'intera dimensione del vettore, questo presumo sia dovuto al ciclo for. Mi spiego meglio: dopo aver inserito la prima età e matricola passa subito alla successiva e così via... Non esiste un modo per acquisire una struttura per volta?
Ti dico questo perchè avevo intenzione di inserire questa funzione in un menù, quindi sarebbe comoda l'acquisizione "per volta".
Grazie per la disponibilità.

_overflow_1
In pratica tu avevi dichiarato la variabile in modo globale, che è una cosa sconsigliata per una buona programmazione (principio del minor privilegio).
Poi in quel modo dichiaravi solo UNA variabile di tipo struct persona e non un vettore come era tua intenzione.

Invece per acquisire una struttura per volta (se ho ben inteso quello che vuoi fare) puoi creare una funzione ad hoc. verrebbe fuori una cosa del genere:

void acquisisci(struct persona *v, int i)
{
    if(i<DIM){
        printf("eta: "); 
        scanf("%d", &v[i].eta); 
        printf("matricola: "); 
        scanf("%d", &v[i].matricola);
    }
    else{
        printf("\nImpossibile inserire elemento il vettore è pieno);
    }
}


La funzione non l'ho provata ma dovrebbe andare. In pratica gli passi il vettore di struct e l'indice della posizione in cui vuoi inserire i nuovi valori.
A questo punto puoi chiamare la funzione quante volte vuoi ricordandoti di aggiornare l'indice di volta in volta.
Nella funzione ho fatto quel controllo perché potrebbe essere che la i (ovvero l'indice) sfori la dimensione del vettore causando un buffer overflow.
Se c'è qualcosa che ti sfugge chiedi pure.

kokoko1
"_overflow_":
In pratica tu avevi dichiarato la variabile in modo globale, che è una cosa sconsigliata per una buona programmazione (principio del minor privilegio).
Poi in quel modo dichiaravi solo UNA variabile di tipo struct persona e non un vettore come era tua intenzione.

Invece per acquisire una struttura per volta (se ho ben inteso quello che vuoi fare) puoi creare una funzione ad hoc. verrebbe fuori una cosa del genere:

void acquisisci(struct persona *v, int i)
{
    if(i<DIM){
        printf("eta: "); 
        scanf("%d", &v[i].eta); 
        printf("matricola: "); 
        scanf("%d", &v[i].matricola);
    }
    else{
        printf("\nImpossibile inserire elemento il vettore è pieno);
    }
}


La funzione non l'ho provata ma dovrebbe andare. In pratica gli passi il vettore di struct e l'indice della posizione in cui vuoi inserire i nuovi valori.
A questo punto puoi chiamare la funzione quante volte vuoi ricordandoti di aggiornare l'indice di volta in volta.
Nella funzione ho fatto quel controllo perché potrebbe essere che la i (ovvero l'indice) sfori la dimensione del vettore causando un buffer overflow.
Se c'è qualcosa che ti sfugge chiedi pure.

Sei stato chiaro, comunque utilizzando questa funzione, dopo aver eseguito il programmino, passa direttamente alla fase di stampa, stampandomi direttamente a video le quattro strutture con valori numerici casuali :?
Forse ho sbagliato qualcosa io nel fare la chiamata a funzione? Ti posto il codice:
#include <stdio.h>
#include <stdlib.h>
#define DIM 4

struct persona {
    int eta;
    int matricola;
};

int main()
{
    struct persona v[DIM];
    int i;

    //acquisizione
    void acquisisci(struct persona *v, int i); //chiamata a funzione

    //stampa
    printf("\n\nStampa dei valori appena inseriti: \n\n");
    for(i=0; i<DIM; i++){
        printf("\neta: %d", v[i].eta);
        printf("\nmatricola: %d\n\n", v[i].matricola);
    }

    system("PAUSE");
    return 0;
} 

void acquisisci(struct persona *v, int i)
{
    if(i<DIM){
        printf("eta: ");
        scanf("%d", &v[i].eta);
        printf("matricola: ");
        scanf("%d", &v[i].matricola);
    }
    else{
        printf("\nImpossibile inserire elemento il vettore è pieno");
    }
} 

_overflow_1
Beh a dire il vero hai sbagliato più di qualche cosa.
Non hai creato il prototipo della funzione, non hai inizializzato i a zero, hai sbagliato il passaggio dei parametri e hai sbagliato la chiamata della funzione...
Hai combinato un bel casino insomma :mrgreen:

ti faccio vedere come avresti dovuto fare:


#include <stdio.h>
#include <stdlib.h>
#define DIM 4

struct persona {
    int eta;
    int matricola;
};

void acquisisci(struct persona *v, int i);

int main()
{
    struct persona v[DIM];
    int i=0, ris, k;

    do{
        acquisisci(v, i); //chiamata a funzione
        i++;
        printf("\n\nSi vuole inserire un' altra persona? se si premere 1, altrimenti 0: ");
        scanf("%d", &ris);
    }while(ris!=0);
    //stampa
    printf("\n\nStampa dei valori appena inseriti: \n\n");
    for(k=0; k<i; k++){
        printf("\neta: %d", v[k].eta);
        printf("\nmatricola: %d\n\n", v[k].matricola);
    }

    system("PAUSE");
    return 0;
}

void acquisisci(struct persona *v, int i)
{
    if(i<DIM){
        printf("\nInserimento %d persona...\n\n", i+1);
        printf("eta: ");
        scanf("%d", &v[i].eta);
        printf("\nmatricola: ");
        scanf("%d", &v[i].matricola);
    }
    else{
        printf("\nImpossibile inserire elemento il vettore \212 pieno");
    }
}


Per aggiungere più di 4 persone devi cambiare il valore DIM. Per il resto pensi funzioni tutto bene.

kokoko1
"_overflow_":
Beh a dire il vero hai sbagliato più di qualche cosa.
Non hai creato il prototipo della funzione, non hai inizializzato i a zero, hai sbagliato il passaggio dei parametri e hai sbagliato la chiamata della funzione...
Hai combinato un bel casino insomma :mrgreen:

ti faccio vedere come avresti dovuto fare:


#include <stdio.h>
#include <stdlib.h>
#define DIM 4

struct persona {
    int eta;
    int matricola;
};

void acquisisci(struct persona *v, int i);

int main()
{
    struct persona v[DIM];
    int i=0, ris;

    do{
        acquisisci(v, i); //chiamata a funzione
        i++;
        printf("\n\nSi vuole inserire un' altra persona? se si premere 1, altrimenti 0: ");
        scanf("%d", &ris);
    }while(ris!=0);
    //stampa
    printf("\n\nStampa dei valori appena inseriti: \n\n");
    for(i=0; i<DIM; i++){
        printf("\neta: %d", v[i].eta);
        printf("\nmatricola: %d\n\n", v[i].matricola);
    }

    system("PAUSE");
    return 0;
}

void acquisisci(struct persona *v, int i)
{
    if(i<DIM){
        printf("\nInserimento %d persona...\n\n", i+1);
        printf("eta: ");
        scanf("%d", &v[i].eta);
        printf("\nmatricola: ");
        scanf("%d", &v[i].matricola);
    }
    else{
        printf("\nImpossibile inserire elemento il vettore \212 pieno");
    }
}


Per aggiungere più di 4 persone devi cambiare il valore DIM. Per il resto pensi funzioni tutto bene.

Ho combinato un casino veramente XD
Comunque il codice adesso funziona, ma rimane un problema. Cioè se riempio tutto il vettore non ci sono problemi di stampa, mentre se inserisco ad esempio solo 2 strutture, mi stampa quelle inserite, ma in più me ne stampa altre 2 con valori numerici casuali. A cosa può essere dovuto?

_overflow_1
Ho modificato il codice di sopra, era logico che avresti dovuto cambiare il ciclo for per la stampa che non doveva più essere da 0 a DIM-1 ma da 0 a i-1.
Comunque ti consiglio di ripetere un po' questi argomenti, prova a fare qualche altro esercizio simile.

kokoko1
"_overflow_":
Ho modificato il codice di sopra, era logico che avresti dovuto cambiare il ciclo for per la stampa che non doveva più essere da 0 a DIM-1 ma da 0 a i-1.
Comunque ti consiglio di ripetere un po' questi argomenti, prova a fare qualche altro esercizio simile.

Hai ragione. Comunque si, in questi giorni sto prendendo argomenti vari e sto esercitandomi anche guardando esempi sul web e anche grazie a questo forum che devo dire, è molto utile. Ti ringrazio ancora, ciao! :-)

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.