Newsgroup: it.comp.lang.c
Titolo: problemi puntatori a struture

Sto cercando di capire le strutture e i puntatori alle strutture.
Sto cercando di scrivere un esercizio che mi legge delle stringhe da un file
e le va a memorizzare in un array di 
strutture.la
 struct pippo e' combosta
da un int e da un puntatore a char.Dichiaro un array di 4  strutture di
questo tipo pluto.
Le varie operazioni compiute sull'array sono fatte tramite un puntatore a
struct, gzimo, il quale punta all'array.
Il programma legge dal file se legge un numero lo memorizza nell'elemento di
tipo int della struct altrimenti lo memorizza nell'elemento char.
Il programma poteva anche far a meno dei puntatori ma, a me serve di capire
come questi funzionano con le strutture.
Il problema e' che il programma memorizza sempre nello stesso elemento
dell'array di struct cioe' ne usa uno solo.
Di sotto riporto il codice e' un po' lungo, spero di essere stato il piu'
chiaro possibile.
Grazie a 
tutti.se
 sto' imparando il linguaggio c e' anche grazie a voi.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<conio.h>
#include <ctype.h>
/* Legge righe da file */
#define MAX_BUF 255
struct pippo {
   char *name;
   int   numero;
};
int main(void)
{
   struct pippo pluto[4];/*Dichiaro un array di struct di tipo pippo*/
   FILE *pf;
   char *filename="d:/pippo.lon"; /*Il file a tre stringhe e un numero*/
   char buffer[MAX_BUF];
   int n,r;
   struct pippo *gzimo; /*Dichiaro un puntatore ad una struct di tipo
pippo*/
   r=0;
   if((pf=fopen(filename,"r"))==NULL) Se pf e' NULL restituisci error
     printf("Error open file\n");
   while (!feof(pf)) Finche' non e' raggiunta la fine del file
   {
      fgets(buffer,MAX_BUF,pf);  Chiama fgets che memorizza la righa letta
in buf
      if(buffer && buffer[strlen(buffer)-1]=='\n') /*Controllo se fgets
aggiunge in "\n" */
      {
        buffer[strlen(buffer)-1]='\0'; /*Se lo ha aggiunto lo sostituisco
con lo string terminator*/
      }
      r++; /*Contatore di record file*/
      gzimo=pluto;/*gzimo punta al primo elemento dell'array di struct
pluto*/
      switch(r) {
         case 1: /*Caso primo record del file*/
           if(buffer[0]>='0' && buffer[0]<='9')  /*Se il primo char e' una
cifra*/
           {
              gzimo->numero=atoi(buffer); /*Memorizza numero nel primo
elemento dell'array di struct pluto*/
           }
           else
           {
             gzimo->name=(char*)malloc(strlen(buffer)+1); /*Altrimenti
memorizzalo nel 2 della struct pluto name*/
             gzimo->name=buffer;
           }
             break;
         case 2:
           gzimo++; /*Ora gzimo punta all'elemento successivo dell'array
struct pluto*/
           if(buffer[0]>='0' && buffer[0]<='9')
           {
             gzimo->numero=atoi(buffer);
           }
           else
           {
             gzimo->name=(char*)malloc(strlen(buffer)+1);
             gzimo->name=buffer;
           }
             break;
           case 3:
           gzimo++;
           if(buffer[0]<='0' && buffer[0]<='9')
             gzimo->numero=atoi(buffer);
           else
           {
             gzimo->name=(char*)malloc(strlen(buffer)+1);
             gzimo->name=buffer;
           }
               break;
           case 4:
           gzimo++;
           if(buffer[0]>='0' && buffer[0]<='9')
             gzimo->numero=atoi(buffer);
           else
           {
             gzimo->name=(char*)malloc(strlen(buffer)+1);
             gzimo->name=buffer;
           }
             break;
           default:
             break;
        } /*Fine switch*/
   }  /*Fine while*/
   n=0;
   gzimo=pluto; /*gzimo punta a pluto*/
   for(n=0;n<=3;n++)
   {
     printf("%s\n",pluto->name);
     printf("%d\n",pluto->numero);
     gzimo++;/*Tramite il puntatore gzimo scorro l'array di struct pluto*/
   }
   fclose(pf);
   getch();
   return 0;
}

    }
Qui nelle printf devi usare gzimo->name e gzimo->numero, visto che
stai usando gzimo per scandire l'array. Altrimenti scrivi sempre e
solo il primo elemento di pluto....
Ultima cosa: Tu a seconda se leggi un numero o una stringa lo memorizzi
nel campo apposito, e va bene. Pero' bisogna anche che tu memorizzi 
qualcosa nel campo inutilizzato (tipo uno 0 per l'int e un bel NULL
(o 0) per la stringa, altrimenti quando dopo vai a stampare stampi
sia delle cose che hai trovato nel file, sia del ciarpame, cosa che nel 
caso degli interi e' veniale, ma stampando una stringa con un puntatore
a caso puoi far piantare il programma. (Magari alcuni compilatori
inizializzano tutto a zero, ma non penso sia il comportamento
standard.)
Scusa se mi permetto di darti un consiglio: io ho imparato a programmare
(in FORTRAN e ALGOL) 25 anni fa, quando ancora un calcolatore non 
l'avevo e eseguivo i programmi "a mano" sulla carta per pura passione. 
Perche' quando  qualcosa non ti funziona non provi a seguire passo passo
il tuo  programma (facendoti una bella tabellina delle variabili) ?
Alternativamente puoi imparare ad usare un debugger, cosa che ti
tornera' sempre utile. ciao.
g.

 tornera' sempre utile. ciao.
E se proprio non ti va un debugger, impara a usare le printf per stampare 
valori e indirizzi delle variabili (in pratica un debugger molto grezzo 
implementato in casa). Il debugger ti e' utile per debuggare qualcosa che 
gia' pare funzionare, il metodo delle printf serve quando stai creando 
qualcosa e ti serve un test semplice e immediato.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 g.
Si infatti devo imparare ad usarlo sai percaso una guida per qullo della
borland?
Fin'ora non sono riuscito a trovare niente.
Quella del foglietto di carta e' una splendita idea.
Vorrei dire una cosa a mox: Io uso sempre la printf per vedere il valore
delle variabili, solo che non era il caso di postare l'esercizio in quel
modo, cosě le ho tolte.
Ciao

>NULL.
Ripensandoci, forse il senso voleva essere questo: (c'e' un * in piu')
if(*buffer && buffer[strlen(buffer)-1]=='\n')
il senso e' che se *buffer (ovvero buffer[0]) e' nullo
(perche' la stringa per qualche motivo e' lunga 0),
allora facendo il test sul primo carattere eviti di fare il
controllo buffer[strlen(buffer)-1]=='\n' che sarebbe sbagliato
in quanto andrebbe a testare buffer[-1].
Come ben saprai, in C se c'e qualcosa del tipo
if (COND1 && COND2) allora se COND1 e' falsa allora COND2
non viene nemmeno valutata, perche' inutile.
ciao,
g.