PDA

View Full Version : [C] Problema: la procedura non cambia la variabile


ciccionamente90
14-12-2009, 21:26
Innanzitutto vi metto il programma completo se volete vederlo:

#include <stdio.h>
#define MAX_LUNG_STRING 100
#define MAX_AR 100

//procedure
void inserimento(int nAR);
void visualizza(int nAR);
void rimuovi(int nAR);
void leggi(int nAR);

//Variabili e strutture
char temp='Z';
int nAR=0;

//Data di pubblicazione: ordinamento date
typedef struct {
int giorno;
int mese;
int anno;
} tipo_data;

//Ultimo typedef (struct: articolo)
typedef struct {
char titolo[MAX_LUNG_STRING];
char autore[MAX_LUNG_STRING];
char giornale[MAX_LUNG_STRING];
char pagina[MAX_LUNG_STRING];
tipo_data data;
unsigned giudizio;
char argomento[MAX_LUNG_STRING];
char note[MAX_LUNG_STRING];
} articolo;

articolo archivio[MAX_AR];

main(){

//Programma

while(temp!='Q'&&temp!='q'){
printf("----------------------------------------\n = Inserire un nuovo articolo\n[L] = Leggere un articolo\n[R] = Rimuovere un articolo\n[V] = Consulta la lista\n[Q] = Chiudi\n----------------------------------------\n");
scanf("%c*%c", &temp);

switch(temp){
//codice nel caso in cui "temp" valga "I" o "i"
case 'I':{
inserimento(nAR);
nAR++;
break;
}
case 'i':{
inserimento(nAR);
nAR++;
break;
}

//codice nel caso in cui "temp" valga "R" o "r"
case 'R':{
rimuovi(nAR);
break;
}
case 'r':{
rimuovi(nAR);
break;
}

//codice nel caso in cui "temp" valga "R" o "r"
case 'L':{
leggi(nAR);
break;
}
case 'l':{
leggi(nAR);
break;
}

//codice nel caso in cui "temp" valga "V"
case 'V':{
visualizza(nAR);
break;
}
case 'v':{
visualizza(nAR);
break;
}

////
default:
{
//Qualsiasi altro caso
break;
}
}
}


}

//VISUALIZZA LISTA
void visualizza(int nAR){
printf("(%d) Lista articoli:\n",nAR);
printf("|---------------------------------------------------------------------------|\n");
printf("Nr. \t Titolo \t Autore \t Giornale \n");
printf("|---------------------------------------------------------------------------|\n");
printf(">nAR: %d<\n",nAR);

int i=0;
for(i=0;i<nAR;i++){
printf("n.%d \t %s \t %s \t %s\n",(i),archivio[i].titolo,archivio[i].autore,archivio[i].giornale);
}

printf("|---------------------------------------------------------------------------|\n");
}

//INSERIMENTO
void inserimento(int nAR){
printf("\n(%d)Inserire titolo (max %d caratteri, senza spazi): ",nAR, MAX_LUNG_STRING);
scanf("%s", &archivio[nAR].titolo);
printf("\n(%d)Inserire autore (max %d caratteri, senza spazi): ",nAR, MAX_LUNG_STRING);
scanf("%s", &archivio[nAR].autore);
printf("\n(%d)Inserire giornale (max %d caratteri, senza spazi): ",nAR, MAX_LUNG_STRING);
scanf("%s", &archivio[nAR].giornale);
printf("\n(%d)Inserire pagina/e del giornale (in cui si irova l'articolo): ",nAR);
scanf("%s", &archivio[nAR].pagina);
printf("\n(%d)Inserire giorno: ",nAR);
scanf("%d", &archivio[nAR].data.giorno);
printf("\n(%d)Inserire mese: ",nAR);
scanf("%d", &archivio[nAR].data.mese);
printf("\n(%d)Inserire anno: ",nAR);
scanf("%d", &archivio[nAR].data.anno);
printf("\n(%d)Inserisci un giudizio (da 1 a 10): ",nAR);
scanf("%u",&archivio[nAR].giudizio);
printf("\n(%d)Inserisci gli argomenti trattati (max %d caratteri, senza spazi): ",nAR, MAX_LUNG_STRING);
scanf("%s", &archivio[nAR].argomento);
printf("\n(%d)Note (max %d caratteri, senza spazi): ",nAR, MAX_LUNG_STRING);
scanf("%s", &archivio[nAR].note);
}


//LETTURA
void leggi(int nAR){

//visualizzazione lista inseriti +init
visualizza(nAR);
int index=0;

//inserimento indice dell'articolo da stampare
printf("\nInserisci il numero dell'articolo da visualizzare: ");
scanf("%d", &index);

//stampa
printf("\n>> Articolo numero %d\n", index);
printf("Titolo: %s\n",archivio[index].titolo);
printf("Autore: %s\n",archivio[index].autore);
printf("Giornale: %s\n",archivio[index].giornale);
printf("Pagina/e: %d\n", archivio[index].pagina);
printf("Data: %d/%d/%d\n", archivio[index].data.giorno, archivio[index].data.mese, archivio[index].data.anno);
printf("Giudizio: %d/10\n", archivio[index].giudizio);
printf("Arggomento/i: %s\n",archivio[index].argomento);
printf("Note: %s\n",archivio[index].titolo);
}

//RIMOZIONE
void rimuovi(int nAR){

//visualizzazione lista inseriti +init
visualizza(nAR);
int index=0;
int x=0;

//inserimento indice dell'articolo da azzerare
printf("(%d) Inserire il numero identificativo dell'articolo da rimuovere:\n",nAR);
scanf("%d", &index);

//azzeramento
archivio[index].titolo[0] ='\0';
archivio[index].autore[0] ='\0';
archivio[index].giornale[0] ='\0';
archivio[index].pagina[0] ='\0';
archivio[index].data.giorno =0;
archivio[index].data.mese =0;
archivio[index].data.anno =0;
archivio[index].giudizio =0;
archivio[index].argomento[0]='\0';
archivio[index].note[0]='\0';

for(x=0;x<MAX_AR;x++){
if(archivio[x].titolo[0] =='\0'){
archivio[x]=archivio[x+1];
archivio[x+1].titolo[0] ='\0';
archivio[x+1].autore[0] ='\0';
archivio[x+1].giornale[0] ='\0';
archivio[x+1].pagina[0] ='\0';
archivio[x+1].data.giorno =0;
archivio[x+1].data.mese =0;
archivio[x+1].data.anno =0;
archivio[x+1].giudizio =0;
archivio[x+1].argomento[0]='\0';
archivio[x+1].note[0]='\0';
nAR--;
}
}
}

Qui invece metto solo la parte utile per la comprensione del mio quesito:
#include <stdio.h>
#define MAX_LUNG_STRING 100
#define MAX_AR 100

//procedure
...
void rimuovi(int nAR);


//Variabili e strutture
char temp='Z';
int nAR=0;

//Data di pubblicazione: ordinamento date
...

//Ultimo typedef (struct: articolo)
typedef struct {
char titolo[MAX_LUNG_STRING];
char autore[MAX_LUNG_STRING];
char giornale[MAX_LUNG_STRING];
char pagina[MAX_LUNG_STRING];
tipo_data data;
unsigned giudizio;
char argomento[MAX_LUNG_STRING];
char note[MAX_LUNG_STRING];
} articolo;

articolo archivio[MAX_AR];

main(){...qui si "attiva" (tra le altre) la procedura di rimozione...}

//RIMOZIONE
void rimuovi(int nAR){

//visualizzazione lista inseriti +init
visualizza(nAR);
int index=0;
int x=0;

//inserimento indice dell'articolo da azzerare
printf("(%d) Inserire il numero identificativo dell'articolo da rimuovere:\n",nAR);
scanf("%d", &index);

//azzeramento
archivio[index].titolo[0] ='\0';
archivio[index].autore[0] ='\0';
archivio[index].giornale[0] ='\0';
archivio[index].pagina[0] ='\0';
archivio[index].data.giorno =0;
archivio[index].data.mese =0;
archivio[index].data.anno =0;
archivio[index].giudizio =0;
archivio[index].argomento[0]='\0';
archivio[index].note[0]='\0';

for(x=0;x<MAX_AR;x++){
if(archivio[x].titolo[0] =='\0'){
archivio[x]=archivio[x+1];
archivio[x+1].titolo[0] ='\0';
archivio[x+1].autore[0] ='\0';
archivio[x+1].giornale[0] ='\0';
archivio[x+1].pagina[0] ='\0';
archivio[x+1].data.giorno =0;
archivio[x+1].data.mese =0;
archivio[x+1].data.anno =0;
archivio[x+1].giudizio =0;
archivio[x+1].argomento[0]='\0';
archivio[x+1].note[0]='\0';
nAR--;
}
}
}

Se avete dato un'occhiata alla versione completa avrete notato che è un programma per la creazione di archivi. Il programma funziona, ma nella procedura di rimozione ho aggiunto questa parte:
for(x=0;x<MAX_AR;x++){
if(archivio[x].titolo[0] =='\0'){
archivio[x]=archivio[x+1];
archivio[x+1].titolo[0] ='\0';
archivio[x+1].autore[0] ='\0';
archivio[x+1].giornale[0] ='\0';
archivio[x+1].pagina[0] ='\0';
archivio[x+1].data.giorno =0;
archivio[x+1].data.mese =0;
archivio[x+1].data.anno =0;
archivio[x+1].giudizio =0;
archivio[x+1].argomento[0]='\0';
archivio[x+1].note[0]='\0';
nAR--;
questo dovrebbe servire per farl "slittare" le posizioni degli articoli all'indietro quando un articolo dell'archivio viene rimosso. Questo lo fa vedendo se il titolo è presente (se è vuoto procede con la sovrascrittura, svuotando quello successivo che si comporta ugualmente con quello dopo ancora e così via). L'unico problema è che quel [I]nAR--; non funziona!!! Non so perché, ma non va a scalare il numero su cui va a riferirsi l'array.

Quindi vi chiedo, come faccio a far funzionare quel nAR--? Non funziona neppure mettendo nAR=nAR-1... come vedrete la variabile è stata dichiarata fuori dal main... mah...

Chiedete pure ;)

wingman87
14-12-2009, 23:06
Ciao, nAR non lo stai usando per indicizzare l'array (almeno così mi sembra) e in ogni caso è il parametro della funzione, quindi anche se ne hai dichiarato un altro fuori quest'ultimo non verrà preso in considerazione.

ciccionamente90
14-12-2009, 23:13
ciao, grazie!
nAR indica la posizione del successivo articolo che si andrà ad inserire, per questo quando viene inserito un nuovo articolo, alla fine nAR si incrementa di uno. Quando "scalo" gli articoli (e quindi l'ultimo rimane vuoto) anche nAR dovrebbe decrementarsi di uno (così che il successivo articolo vada nel primo spazio vuoto, ovvero l'ultimo "scalato").

Non capisco cosa intendi dire quando dici che se ne ho dichiarato un'altro fuori, questo non verrà preso in considerazione...

wingman87
14-12-2009, 23:21
Perché sei in una situazione di questo tipo:


int var;

int main(){
var=0;
myFunc(12); //12 è un numero qualunque
printf("%d\n",var); //stamperà 0
}

void myFunc(int var){
var=1;
}
in myFunc il var cui viene assegnato 1 non è quello dichiarato prima del main ma è il parametro della funzione.

ciccionamente90
14-12-2009, 23:28
ma io la variabile l'ho posta uguale a 0 fuori da ogni funzione: viene prima del main...

EDIT: forse ho capito cosa intendi, magari devo fare int var=0 (o int nAR=0) all'interno del main...

wingman87
14-12-2009, 23:32
ma io la variabile l'ho posta uguale a 0 fuori da ogni funzione: viene prima del main...
Il punto non è questo, è che la funzione rimuovi l'hai dichiarata così:
void rimuovi(int nAR){
...
}

Quindi ogni riferimento che fai alla variabile nAR all'interno di rimuovi è un riferimento al parametro che ti ho evidenziato, e non alla variabile nAR che hai dichiarato prima del main

ciccionamente90
14-12-2009, 23:36
ah, io credevo che lavorasse con lo stesso nAR... quindi come faccio a fargli modificare la variabile nAR che si trova fuori? Lascio le parentesi vuote?

wingman87
15-12-2009, 00:05
Direi che è la soluzione più saggia, infatti non usi mai il valore passato come parametro (a parte per quel decremento che però tu vuoi si riferisca al nAR dichiarato fuori).

!fazz
15-12-2009, 08:35
usa int &nAR al posto di int nAR

passaggio per riferimento invece che a valore

ciccionamente90
15-12-2009, 10:31
grazie, oggi provo e vi faccio sapere se funge :)

cionci
15-12-2009, 12:41
Devi passare per indirizzo ;)

int *nAR

Poi dopo devi sostituire *nAR dove utilizzi nAR.
Quando richiami la funzione devi passare l'indirizzo di nAR, cioè &nAR.