PDA

View Full Version : [C] Esercizio su array di struct che non mi funziona... :-/


Free/Sbin
07-07-2006, 11:38
Ciao,
vi chiedo ancora un aiutone...Lunedi ho l'esame di laboratorio di programmazione e sono un po' nel panico...vi prego di aiutarmi se potete....

L'esercizio è questo:

scrivere un programma che faccia uso di un array di strutture, ogi struttura rappresenta un utente e contiene i campi: nome, cognome, età.

Il programma deve poter inserire un utente se c'è ancora spazio libero nell'array e visualizzare la lista degli utenti....dà qualche errore in fase di compilazione. La prima parte dell'esame è su carta....mi potete dare anche un giudizio su com'è scritto il codice secondo voi?se l'organizzazioni in funzioni che ho fatto va bene o se fà pietà?insomma secondo voi con un esercizio del genere che voto mi avreste dato? hehe

Gl errori sono:

[root@dhcppc0 ripasso]# cc struct2.c -o struct2
struct2.c: In function ‘set_zero’:
struct2.c:64: error: syntax error before ‘;’ token
struct2.c:96: error: ‘name’ undeclared (first use in this function)
struct2.c:96: error: (Each undeclared identifier is reported only once
struct2.c:96: error: for each function it appears in.)
struct2.c:109: warning: ‘return’ with a value, in function returning void
struct2.c: In function ‘read_list’:
struct2.c:123: error: syntax error before ‘;’ token
[root@dhcppc0 ripasso]#

Alcuni proprio non me li spiego...perchè le variabili le HO DICHIARATE..disperazione :-/


Il codice è:


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

struct utente{
char nome[15];
char cognome[15];
int age;
};

typedef struct utente utente; // Crea l'alias utente del tipo di dato struct utente

void set_zero(utente *); // Riceve il puntatore ad un'array di strutture, non ritorna alcun valore
int is_empty(utente *); // Riceve il puntatore ad un'array di strutture e ritorna un valore intero
int insert_user(utente *); // Riceve il puntatore ad un'array di strutture e ritorna un valore intero
void read_list(utente *); // Riceve il puntatore ad un'array di strutture, non ritorna alcun valore

int main(){

int i = 0;
int a = 0;
utente vett[100]; // Dichiara un vettore di 100 strutture di tipo utente

set_zero(vett); // Setta a 0 la lista di utenti

printf("\n1 per inserire un nuovo utente\n2 per visuallizzare la lista utenti\3 per terminare\n\n");
scanf("%d", &i);

while(i != 3){

if(i = 1){ // Se i uguale ad 1 prova ad inserire un utente nell'array di strutture
a = insert_user(vett); // Passa il vettore alla funzione
if(a = -1)
printf("Utente non inserito, lista piena, non c'è più spazio disponibile\n\n");
else
printf("Utente inserito nella lista\n\n");
printf("Inserire un nuovo valore: ");
}

else if(i = 2){ // Leggi la lista
read_list(vett); // Passa il vettore alla funzione

printf("Inserire un nuovo valore: ");
}

else{
printf("Scelta errata, inserire un valore corretto: ");
printf("Inserire un nuovo valore: ");
}
scanf("%d", &i);
}

return 0;
}

/* La funzione set_zero setta a 0 l'età degli utenti, quando un utente ha età settata a 0 significa che la
locazione è libera, riceve il puntatore al primo elemento della lista */

void set_zero(utente *array){

int i;
for(i=0; i<100; i++)
// Inserisci 0 nel campo age della locazione array + elemento corrente dell'array di strutture
(array+i)->age = 0;
return (void);
}

/* La funzione is_empty riceve il puntatore al primo elemento dell'array di strutture, ritorna -1 se l'array di
strutture è pieno o l'indice della prima locazione libera se non è ancora pieno *(

int is_empty(utente *array){

int val = -1; // Inizialmente setta a -1 il valore di val
int i = 0;

// Finchè non ha scorso tutta la lista o finchè il valore di val corrisponde a -1 scorri l'array
for(i=0; i<100 || val==-1; i++){
if((array+i).age == 0) // Se la locazione corrente è libera
val = i; // Setta val alla locazione corrente libera

return(val); // Ritorna val: -1 se la lista è piena o prima locazione libera
}

/* La funzione insert_user inserisce se possibile un nuovo utente nel vettore di strutture e ritorna il valore -1
se l'array di strutture è pieno e non è riuscita ad inserire l'utente */

int insert_user(utente *array){

char name[15];
char surname[15];
int age;

int locazione = is_empty(array); // Metti in locazione il valore della prima locazione libera

if(locazione != -1){ // Se può inserire un valore nell'array di strutture (la lista non è piena)
printf("Inserire il nome: ");
scanf("%c", name);
// Copia il nome inserito nel campo nome della struttura alla corretta locazione nell'array
strcpy((array+locazione)->nome, name);
printf("Inserisci il cognome: ");
scanf("%c", surname);
// Copia il cognome inserito nel campo cognome della struttura alla corretta locazione nell'array
strcpy((array+locazione)->cognome, surname);
printf("Inserire l'età: ");
scanf("%d", &age);
// Copia l'età inserita nel campo age della struttura alla corretta locazione nell'array)
(array+locazione)->age = age;
}

return(locazione); // Ritorna -1 se la lista è piena, altro se ha effettuato l'inserimento
}


void read_list(utente *array){

int i;
// Leggi dall'array finchè ci sono ancora locazioni o finchè la locazione trovata non è vuota (age == 0)
for(i=0; i<100 || (array+i)->age != 0; i++){
printf("Nome utente %d: %c\n",i, (array+i)->nome);
printf("Cognome utente %d: %c\n",i, (array+i)->cognome);
printf("Età utente %d: %c\n", i, (array+i)->age);
}

return (void);
}


Mille grazie

trallallero
07-07-2006, 11:56
cosí velocemente noto che:

1) se una funzione torna void non serve "return (void)"
se vuoi uscire prima dalla funzione fai return;

2)

printf("Nome utente %d: %c\n",i, (array+i)->nome);

per stampare una stringa serve il "%s" non "%c" ;)

3)

scanf("%c", name);

stesso discorso del "%s"

ma la funzione is_empty non c'é ;)

Fenomeno85
07-07-2006, 12:23
dopo mangiato proverò a guardarlo ... ma sei sicuro che puoi scrivere in quel modo il typedef? mi sembra strano che puoi chiamare la stessa cosa utente utente

~§~ Sempre E Solo Lei ~§~

trallallero
07-07-2006, 12:31
ma sei sicuro che puoi scrivere in quel modo il typedef? mi sembra strano che puoi chiamare la stessa cosa utente utente
si é giusto ;)
il compilatore capisce questo:
typedef struct utente utente;

Free/Sbin
07-07-2006, 12:36
si é giusto ;)
il compilatore capisce questo:
typedef struct utente utente;

si infatti quel typedef non fà altro che dire che il tipo di dato struct utente da ora in poi si può anche chiamare semplicemente come utente...è solo una cosa di comodità per evitare dis crivere struct utente e usare un nome di tipo di dato più simile ad int e a char...grazie dopo pranzo proverò le modifiche che mi hai detto...che scemo che sono....

mmm nel complesso come logica e organizzazione delle funzioni per te com'è fatto?mi avrebbe promossuto secondo te? :D

trallallero
07-07-2006, 13:07
si infatti quel typedef non fà altro che dire che il tipo di dato struct utente da ora in poi si può anche chiamare semplicemente come utente...è solo una cosa di comodità per evitare dis crivere struct utente e usare un nome di tipo di dato più simile ad int e a char...grazie dopo pranzo proverò le modifiche che mi hai detto...che scemo che sono....

mmm nel complesso come logica e organizzazione delle funzioni per te com'è fatto?mi avrebbe promossuto secondo te? :D
si penso. Se sei all'esame finale di un corso C di 6 mesi ti avrei bocciato, se sei all'inizio va piú che bene :D

Fenomeno85
07-07-2006, 13:11
devo controllare ... non mi sembra ansi c89 ... mi sembra più c++ ... in c le struct non andavano per forza sotto typedef struct .... ?? :wtf:

~§~ Sempre E Solo Lei ~§~

Free/Sbin
07-07-2006, 13:17
si penso. Se sei all'esame finale di un corso C di 6 mesi ti avrei bocciato, se sei all'inizio va piú che bene :D

bingo azzolinaaa :cry:

trallallero
07-07-2006, 13:24
bingo azzolinaaa :cry:
eh ? :what:

Free/Sbin
07-07-2006, 13:43
esame lunedi :eek:

AngeL)
07-07-2006, 17:41
premetto di non conoscere struct,typedef e classi,
ma perche hai fatto

struct utente {...};
typedef struct utente utente;

se poteva fare

typedef struct utente{...} utente;

?

Free/Sbin
07-07-2006, 17:57
premetto di non conoscere struct,typedef e classi,
ma perche hai fatto

struct utente {...};
typedef struct utente utente;

se poteva fare

typedef struct utente{...} utente;

?

semplice: il mio primo professore di programmazione faceva così e io faccio così, conosco anche il modo da te elencato ma per mio gusto personale preferisco scrivere prima la struttura e poi dichairare l'alias col tyoedef...secondo me è più leggibile anche se uso una riga di codice in più....poi non sò...è solo una mia opinione che potrebbe non essere approvata dal 99% dei programmatori professionisti...il giorno che trovderò una valida ragione (e se c'è datemela) per preferire l'altro metodo userò quello :)

Free/Sbin
07-07-2006, 18:03
Allora ora la lista degli errori si è abbastanza ridotta...quegli errori del %c %s che deficiente...scrivendo veloce non ho pensato...però dopo aver passato 3 giorni a scrivere funzioni operanti sulle stringhe son cose che ho chaire hehehe solo distrazione e la storia del return (void)...vabbè non toccando compilatore da 6 mesi su alcuen cose sono un po' arruginito e mi sembrava che se una funzione ritorni void andasse specificato come se riceve void (int main(void) )

Il problema concettuale serio credo sia questo errore:
[root@localhost ripasso]# cc struct2.c -o struct2
/tmp/ccUPeT3s.o(.text+0x185): In function `insert_user':
struct2.c: undefined reference to `is_empty'
collect2: ld returned 1 exit status
[root@localhost ripasso]#

Credo che mi sfugga qualcosa sulla visibilità delle funzioni....ahime...cioè la funzione esiste, il prototipo è stato dichiarato all'inizio insieme agli altri prototipi e il corpo stà sotto insieme agli altri corpi di funzione....c'è qualcosa che mi sfugge...è come se la funzione insert_user() che la richiama non riuscisse a vederla...come mai?

Questo è il codice modificato:


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

struct utente{
char nome[15];
char cognome[15];
int age;
};

typedef struct utente utente; // Crea l'alias utente del tipo di dato struct utente

void set_zero(utente *); // Riceve il puntatore ad un'array di strutture, non ritorna alcun valore
int is_empty(utente *); // Riceve il puntatore ad un'array di strutture e ritorna un valore intero
int insert_user(utente *); // Riceve il puntatore ad un'array di strutture e ritorna un valore intero
void read_list(utente *); // Riceve il puntatore ad un'array di strutture, non ritorna alcun valore

int main(){

int i = 0;
int a = 0;
utente vett[100]; // Dichiara un vettore di 100 strutture di tipo utente

set_zero(vett); // Setta a 0 la lista di utenti

printf("\n1 per inserire un nuovo utente\n2 per visuallizzare la lista utenti\3 per terminare\n\n");
scanf("%d", &i);

while(i != 3){

if(i = 1){ // Se i uguale ad 1 prova ad inserire un utente nell'array di strutture
a = insert_user(vett); // Passa il vettore alla funzione
if(a = -1)
printf("Utente non inserito, lista piena, non c'è più spazio disponibile\n\n");
else
printf("Utente inserito nella lista\n\n");
printf("Inserire un nuovo valore: ");
}

else if(i = 2){ // Leggi la lista
read_list(vett); // Passa il vettore alla funzione

printf("Inserire un nuovo valore: ");
}

else{
printf("Scelta errata, inserire un valore corretto: ");
printf("Inserire un nuovo valore: ");
}
scanf("%d", &i);
}

return 0;
}

/* La funzione set_zero setta a 0 l'età degli utenti, quando un utente ha età settata a 0 significa che la
locazione è libera, riceve il puntatore al primo elemento della lista */

void set_zero(utente *array){

int i;
for(i=0; i<100; i++)
// Inserisci 0 nel campo age della locazione array + elemento corrente dell'array di strutture
(array+i)->age = 0;

}

/* La funzione is_empty riceve il puntatore al primo elemento dell'array di strutture, ritorna -1 se l'array di
strutture è pieno o l'indice della prima locazione libera se non è ancora pieno *(

int is_empty(utente *array){

int val = -1; // Inizialmente setta a -1 il valore di val
int i = 0;

// Finchè non ha scorso tutta la lista o finchè il valore di val corrisponde a -1 scorri l'array
for(i=0; i<100 || val==-1; i++){
if((array+i).age == 0) // Se la locazione corrente è libera
val = i; // Setta val alla locazione corrente libera

return(val); // Ritorna val: -1 se la lista è piena o prima locazione libera
}

/* La funzione insert_user inserisce se possibile un nuovo utente nel vettore di strutture e ritorna il valore -1
se l'array di strutture è pieno e non è riuscita ad inserire l'utente */

int insert_user(utente *array){

char name[15];
char surname[15];
int age;

int locazione = is_empty(array); // Metti in locazione il valore della prima locazione libera

if(locazione != -1){ // Se può inserire un valore nell'array di strutture (la lista non è piena)
printf("Inserire il nome: ");
scanf("%s", name);
// Copia il nome inserito nel campo nome della struttura alla corretta locazione nell'array
strcpy((array+locazione)->nome, name);
printf("Inserisci il cognome: ");
scanf("%s", surname);
// Copia il cognome inserito nel campo cognome della struttura alla corretta locazione nell'array
strcpy((array+locazione)->cognome, surname);
printf("Inserire l'età: ");
scanf("%d", &age);
// Copia l'età inserita nel campo age della struttura alla corretta locazione nell'array)
(array+locazione)->age = age;
}

return(locazione); // Ritorna -1 se la lista è piena, altro se ha effettuato l'inserimento
}


void read_list(utente *array){

int i;
// Leggi dall'array finchè ci sono ancora locazioni o finchè la locazione trovata non è vuota (age == 0)
for(i=0; i<100 || (array+i)->age != 0; i++){
printf("Nome utente %d: %s\n",i, (array+i)->nome);
printf("Cognome utente %d: %s\n",i, (array+i)->cognome);
printf("Età utente %d: %d\n", i, (array+i)->age);
}


}

slartibartfast
07-07-2006, 18:24
Allora, ci sono due errori di battitura:

nella riga 68 hai chiuso il commento con *( invece che con */
in riga 81 non hai chiuso l'if

slartibartfast
07-07-2006, 18:34
sempre nella funzione is_empty hai usato il punto al posto della -> per la struttura ;)

slartibartfast
07-07-2006, 18:53
minghia quanti errori :sofico:

in main negli if hai usato il simbolo di assegnazione '=' invece che di comparazione '=='
adesso l'inserimento funziona, devo ancora indagare sulla visualizzazione...

Andlea
07-07-2006, 19:03
le condizioni nel for per la visualizzazione vanno in AND

slartibartfast
07-07-2006, 19:12
esatto, anche nel ciclo for nella funzione is_empty, ora funzica ;)

Free/Sbin
07-07-2006, 19:45
esatto, anche nel ciclo for nella funzione is_empty, ora funzica ;)

mmm questo capita a scrivere codice alle 2 di notte dopo essere tornati dal pub, l'ho fatto l'altra sera e oggi ci stò rimettendo mano, non è che potresti passarmi il listato corrretto

Grazie

slartibartfast
07-07-2006, 20:32
ecco qua
#include <stdio.h>
#include <string.h>

struct utente{
char nome[15];
char cognome[15];
int age;
};

typedef struct utente utente; // Crea l'alias utente del tipo di dato struct utente

void set_zero(utente *); // Riceve il puntatore ad un'array di strutture, non ritorna alcun valore
int is_empty(utente *); // Riceve il puntatore ad un'array di strutture e ritorna un valore intero
int insert_user(utente *); // Riceve il puntatore ad un'array di strutture e ritorna un valore intero
void read_list(utente *); // Riceve il puntatore ad un'array di strutture, non ritorna alcun valore

int main(){

int i = 0;
int a = 0;
utente vett[100]; // Dichiara un vettore di 100 strutture di tipo utente

set_zero(vett); // Setta a 0 la lista di utenti

printf("\n1 per inserire un nuovo utente\n2 per visuallizzare la lista utenti\3 per terminare\n\n");
scanf("%d", &i);

while(i != 3){

if(i == 1){ // Se i uguale ad 1 prova ad inserire un utente nell'array di strutture
a = insert_user(vett); // Passa il vettore alla funzione
if(a == -1)
printf("Utente non inserito, lista piena, non c'è più spazio disponibile\n\n");
else
printf("Utente inserito nella lista\n\n");
printf("Inserire un nuovo valore: ");
}

else if(i == 2){ // Leggi la lista
read_list(vett); // Passa il vettore alla funzione

printf("Inserire un nuovo valore: ");
}

else{
printf("Scelta errata, inserire un valore corretto: ");
printf("Inserire un nuovo valore: ");
}
scanf("%d", &i);
}

return 0;
}

/* La funzione set_zero setta a 0 l'età degli utenti, quando un utente ha età settata a 0 significa che la
locazione è libera, riceve il puntatore al primo elemento della lista */

void set_zero(utente *array){

int i;
for(i=0; i<100; i++)
// Inserisci 0 nel campo age della locazione array + elemento corrente dell'array di strutture
(array+i)->age = 0;

}

/* La funzione is_empty riceve il puntatore al primo elemento dell'array di strutture, ritorna -1 se l'array di
strutture è pieno o l'indice della prima locazione libera se non è ancora pieno */

int is_empty(utente *array){

int val = -1; // Inizialmente setta a -1 il valore di val
int i = 0;

// Finchè non ha scorso tutta la lista o finchè il valore di val corrisponde a -1 scorri l'array
for(i=0; i<100 && val==-1; i++){
if((array+i)->age == 0) // Se la locazione corrente è libera
val = i; // Setta val alla locazione corrente libera
}
return(val); // Ritorna val: -1 se la lista è piena o prima locazione libera
}

/* La funzione insert_user inserisce se possibile un nuovo utente nel vettore di strutture e ritorna il valore -1
se l'array di strutture è pieno e non è riuscita ad inserire l'utente */

int insert_user(utente *array){

char name[15];
char surname[15];
int age;

int locazione = is_empty(array); // Metti in locazione il valore della prima locazione libera

if(locazione != -1){ // Se può inserire un valore nell'array di strutture (la lista non è piena)
printf("Inserire il nome: ");
scanf("%s", name);
// Copia il nome inserito nel campo nome della struttura alla corretta locazione nell'array
strcpy((array+locazione)->nome, name);
printf("Inserisci il cognome: ");
scanf("%s", surname);
// Copia il cognome inserito nel campo cognome della struttura alla corretta locazione nell'array
strcpy((array+locazione)->cognome, surname);
printf("Inserire l'età: ");
scanf("%d", &age);
// Copia l'età inserita nel campo age della struttura alla corretta locazione nell'array)
(array+locazione)->age = age;
}

return(locazione); // Ritorna -1 se la lista è piena, altro se ha effettuato l'inserimento
}


void read_list(utente *array){

int i;
// Leggi dall'array finchè ci sono ancora locazioni o finchè la locazione trovata non è vuota (age == 0)
for(i=0; i<100 && (array+i)->age != 0; i++){
printf("Nome utente %d: %s\n",i, (array+i)->nome);
printf("Cognome utente %d: %s\n",i, (array+i)->cognome);
printf("Età utente %d: %d\n", i, (array+i)->age);
}


}