Newsgroup: it.comp.lang.c
Titolo: Aiuto su uno stupidissimo programmino in C

Intanto scusate la lunghezza del post ma rischio l'esaurimento nervoso!
Dovrei fare il seguente programma in C:
Acquisire da standard input N elementi (con N costante pari a 5) di tipo 
ContoCorrente:
typedef struct {
char CC[5];
char Descrizione[20];
int Valore; } ContoCorrente;
e memorizzarli nel file binario Conto.dat .
Visualizzare, per ogni valore di CC il saldo del conto, ottenuto come 
somma algebrica delle operazioni eseguite sul conto (campo Valore della 
struttura ContoCorrente).
Esempio:
CC Descrizione Valore
A1 Op. 1 -200
A2 Op. 2 190
A3 Op. 3 50
A2 Op. 4 -40
A1 Op. 5 220
Il Risultato Sarà:
CC Saldo
A1 20
A2 150
A3 50
Fino all'acquisizione e memorizzazione non ci sono problemi, ma per la 
stampa del saldo non ci salto fuori!icon_dho.gif Ho scritto questo ciclo:
/*Stampa saldo*/
for(i=0;i<N;i++){
fread(&conto,sizeof(ContoCorrente),1,conti);
printf("\nConto: %s",conto.CC);
strcpy(nome,conto.CC);
movimenti=conto.Valore;
while(fread(&conto,sizeof(ContoCorrente),1,conti)>0)
if(strcmp(nome,conto.CC)==0) movimenti=movimenti+conto.Valore;
printf("Valore: %d",movimenti);
fseek(conti,sizeof(ContoCorrente)*i,SEEK_SET);
}
ma non si accorge se di un conto corrente ha già stampato il saldo e 
compe output ottengo questo:
Conto: A1 Valore: 20
Conto: A1 Valore: 20
Conto: A2 Valore: 150
Conto: A3 Valore: 50
Conto: A2 Valore: -40
Dov'è l'inghippo ? Un 1.000.000 di grazie a chi mi darà una mano!
Fox

 }
Scusa, ma prima di scrivere questo lungo post,
hai provato a rileggere il programma che hai scritto ?
Ti sembra che abbia senso ?
Qui non e' questione di abilita' di programmazione o
conoscenza del linguaggio C, ma di buon senso.
Se tu devi accumulare le operazioni rispetto ad ogni CC,
e se il tuo file che leggi non e' ordinato rispetto a CC
(cosi' come si deduce dall'esempio), allora devi implementare
un metodo che tenga traccia dei risultati parziali dei vari
CC e fare la stampa solo alla fine. Quindi hai ovviamente bisogno
di memorizzare questi dati da qualche parte. Non puoi avere solo
la variabile conto: se stai accumulando le operazioni di A1 e in
mezzo leggi un A2, perdi traccia di A1.
Allora.
Ti crei una struttura dati dove memorizzare i dati:
siccome al massimo sono 5 avrai al massimo 5 diversi CC:
va bene la struttura che hai gia', quindi la
struttura ContoCorrente:
ContoCorrente Saldo[N];
a questo punto fai il tuo ciclo e operi in questo
tieni un contatore, diciamo ix, inizialmente uguale a zero
che ti dice quanti diversi CC hai letto.
poi:
for (i=0; i<N; i++){
leggi un record dal file nella posizione Saldo[ix];
a questo punto vai a vedere se il CC di Saldo[ix]
era gia' presente in un CC di un Saldo[j] con j<ix:
se ne trovi uno tale che Saldo[j].CC == Saldo[ix].CC,
allora avevi gia' letto un CC con quel codice e devi
accumulare il valore quindi fai Saldo[j].Valore += Saldo[ix].valore;
e NON incrementi ix, perche' non hai visto un nuovo CC.
Se invece NON trovi un j tale che Saldo[j].CC == Saldo[ix].CC,
allora devi tenere il record appena letto, e questo lo
fai semplicemente incrementando ix:   ix++;
Quando finisci questo ciclo su i,
avrai in ix il numero di CC diversi che hai letto,
e in Saldo[0 .. ix-1].Valore i valori di saldo per i vari
CC che devi stampare.
Ciao,
g.
PS. questo e' un esercizio di programmazione, non un programma
vero, I suppose...

 
Si è un esercizio di un esame di laboratorio che secondo il prof andava 
fatto in un'ora!Proverò come dici!
Grazie!
Fox

 Ti sembra che abbia senso ?
Avevi ragione!Non aveva senso! :P
Ecco come lo ho corretto e ora mi funziona!Ero proprio gnucco!
/*Stampa saldo, div mi dice quanti diversi CC ho letto*/
div=1;
for(i=0;i<N;i++){	
	fread(&conto,sizeof(ContoCorrente),1,conti);
	saldo[i]=conto;
	trovato=0;
	for(j=0;j<i && !trovato;j++)
		if(strcmp(saldo[j].CC,saldo[i].CC)==0)
			{
			saldo[j].Valore=saldo[i].Valore+saldo[j].Valore;
			trovato=1;
			}
		if(trovato==0) div++;
	}
for(i=0;i<div-1;i++){
	printf("\nConto: %s",saldo[i].CC);
	printf("Valore: %d",saldo[i].Valore);
}

     saldo[i]=conto;
qui fai l'errore. in pratica te li salvi sempre tutti.
Ma poi incrementi div solo quando il CC e' nuovo.
Questo non ha senso. Infatti se in sequenza hai
A1 A1 A1 A2 A3
me li vai a salvare in saldo[0],[1],[2],[3],[4],
il div ti passa da 1 a 4 (incrementato per il primo A1,
poi per A2 poi per A3) poi
quando stampi i valori alla fine fai un ciclo
da 0 a div-1 cioe' per i=0,1,2 e mi stampi solo
3 copie del CC A1....
Devi fare come ti ho detto io:
div=0; // all'inizio (visto che non hai visto nulla!)
salvi in saldo[div] e non in saldo[i] // altrimenti li salvi tutti
incrementi div se non trovi, in questo modo tra 0 e div-1 ci
vanno solo CC unici e non ripetuti come adesso.
Al lavoro !!
ciao.
g.

 g.
Ho provato a fare come dici tu e secondo me ci sono riuscito!Funziona!
Ecco il codice:
/*Stampa saldo*/
div=0;
fread(&conto,sizeof(ContoCorrente),1,conti);
saldo[div]=conto;
while(fread(&conto,sizeof(ContoCorrente),1,conti)>0){
	find=0;
	for(i=0;i<=div && !find;i++){	
		if(strcmp(saldo[div].CC,conto.CC)==0){
		saldo[div].Valore=saldo[div].Valore+conto.Valore;
		find=1;
		}
	else {div++;saldo[div]=conto;}
		}
	}
Ciao e grazie per l'aiuto!
Fox