PDA

Visualizza la versione completa : [C] Matrice di stringhe


andry85
30-09-2007, 16:30
Ciao. Dovrei allocare dinamicamente una matrice di stringhe. In pratica conosco il numero di righe e di colonne (passati da tastiera )della matrice, e da queste due informazioni devo appunto allocare la matrice.
Sarà un problema banale, ma sto avendo un po' di diffocoltà, forse dovuta alla confusione che ho in testa.
Grazie a tutti!

:)

andbin
30-09-2007, 17:04
Originariamente inviato da andry85
Ciao. Dovrei allocare dinamicamente una matrice di stringhe. In pratica conosco il numero di righe e di colonne (passati da tastiera )della matrice, e da queste due informazioni devo appunto allocare la matrice.
Sarà un problema banale, ma sto avendo un po' di diffocoltà, forse dovuta alla confusione che ho in testa.È una matrice bidimensionale, quindi.

In tal caso devi usare un puntatore char ***matrice; (si, hai letto bene, puntatore a puntatore a puntatore a char)

Per allocare la matrice si fa (ometto per brevità il controllo delle allocazioni, che va sempre fatto):


matrice = (char***) malloc (sizeof (char**) * num_righe);

for (i = 0; i < num_righe; i++)
matrice[i] = (char**) malloc (sizeof (char*) * num_colonne);

Dopodiché, l'espressione matrice[r][c] è un puntatore a char, a cui puoi assegnare l'indirizzo di una stringa (che dovrà essere opportunamente già allocata da qualche parte).

andry85
30-09-2007, 18:29
AH ok, allora l'avevo quasi azzeccata l'implementazione.
Poichè leggo le stringhe da un file, avevo pensato di fare così:



for(i=0;i<righe;i++){
for(j=0; j<colonne; j++){
fscanf(fp,"%s",stringa);
matrice[i][j] = stringa;
}
}

Il fatto è che non capisco bene perchè, quando tento di fare una stampa di prova alla fine:


for(i=0;i<righe;i++)
for(j=0; j<colonne; j++)
printf("%s \n", matrice[i][j]);

mi stampa sempre l'ultimo elemento letto.

oregon
30-09-2007, 18:49
Originariamente inviato da andry85
AH ok, allora l'avevo quasi azzeccata l'implementazione.

Quasi ...



Poichè leggo le stringhe da un file, avevo pensato di fare così:

No ... hai pensato male ... se non vuoi usare la stringa temporanea, puoi scrivere direttamente



fscanf(fp,"%s", matrice[i][j]);


altrimenti devi scrivere



strcpy(matrice[i][j], stringa);


perche', come scrivi tu, assegni solamente il valore del puntatore della stringa temporanea ai puntatori della matrice ...

Nota bene: sia stringa che gli elementi matrice[i][j] devono puntare ad uno spazio allocato, staticamente per stringa, dinamicamente per matrice[i][j] ... (come ti aveva ricordato andbin) ...



Il fatto è che non capisco bene perchè, quando tento di fare una stampa di prova alla fine:


Il fatto e' che non hai per nulla chiaro il concetto di stringa per C e del puntatore a stringa ...

andry85
01-10-2007, 16:06
Oregon, se chiedo aiuto qui vuol dire che ho delle difficoltà, perchè sono cose che sto imparando ora. Quindi, non mi sembra il caso che tu dia un giudizio alla mia capacità di programmazione in C, perchè a quello ci pensano i miei prof che sono già abbastanza pignoli.

andry85
01-10-2007, 16:23
No ... hai pensato male ... se non vuoi usare la stringa temporanea, puoi scrivere direttamente



fscanf(fp,"%s", matrice[i][j]);


altrimenti devi scrivere



strcpy(matrice[i][j], stringa);




Sia una che l'altra generano degli errori durante l'esecuzione.

andbin
01-10-2007, 16:30
Originariamente inviato da andry85
Sia una che l'altra generano degli errori durante l'esecuzione. Forse non ti è chiaro un concetto che invece è fondamentale. Il codice che ho postato io all'inizio serve solo ed esclusivamente per allocare la matrice di puntatori alle stringhe. Non alloca lo spazio per i caratteri delle stringhe. A questo ci devi pensare tu.

andry85
01-10-2007, 16:58
Originariamente inviato da andbin
Forse non ti è chiaro un concetto che invece è fondamentale. Il codice che ho postato io all'inizio serve solo ed esclusivamente per allocare la matrice di puntatori alle stringhe. Non alloca lo spazio per i caratteri delle stringhe. A questo ci devi pensare tu.


Adesso ho capito l'errore che facevo. In pratica ogni elemento della matrice puntava alla variabile stringa, a questa variabile assegnavo un valore diverso ogni volta che leggevo una stringa nuova, ma l'indirizzo era lo stesso. Io invece devo allocare uno spazio per ogni stringa che leggo.



char *stringa;

for(i=0;i<righe;i++){
for(j=0; j<colonne; j++){
stringa = (char*)malloc(10*sizeof(char)); /* qui alloco lo spazio per la stringa letta */
fscanf(fp,"%s",stringa);
matrice[i][j] = stringa;


printf("%s ", matrice[i][j]);
}


Detto questo come potrei usare la soluzione qui sotto??


fscanf(fp,"%s",matrice[i][j]);

oregon
01-10-2007, 17:07
Originariamente inviato da andry85
Adesso ho capito l'errore che facevo. In pratica ogni elemento della matrice puntava alla variabile stringa, a questa variabile assegnavo un valore diverso ogni volta che leggevo una stringa nuova, ma l'indirizzo era lo stesso. Io invece devo allocare uno spazio per ogni stringa che leggo.


Infatti, mi sembrava di averti scritto ...



Nota bene: sia stringa che gli elementi matrice[i][j] devono puntare ad uno spazio allocato, staticamente per stringa, dinamicamente per matrice[i][j] ... (come ti aveva ricordato andbin) ...


... ma e' evidente che non hai letto completamente la risposta (ne' quella mia ne' quella di andbin) ...



Detto questo come potrei usare la soluzione qui sotto??

Devi allocare lo spazio per le stringhe!

Quindi una malloc per ogni elemento

matrice[i][j]

andbin
01-10-2007, 17:09
Originariamente inviato da andry85
Detto questo come potrei usare la soluzione qui sotto??


fscanf(fp,"%s",matrice[i][j]);
Se a matrice[i][j] hai già assegnato un puntatore ad una area di memoria sì, certo che lo puoi fare.
Nel tuo codice sopra l'uso della variabile 'stringa' non sarebbe nemmeno necessario, basterebbe fare:


matrice[i][j] = (char*) malloc (........);

if (matrice[i][j] != NULL)
fscanf(fp,"%s",matrice[i][j]);

Loading