PDA

View Full Version : Memorizzare stringhe in una matrice


hasmet
01-10-2008, 15:53
Ho ricevuto all'università una esercitazione che non riesco proprio a fare, o perlomeno avrei una tattica ma vorrei sapere voi cosa ne pensate e se è fattibile. Allora io ho un documento come questo:


2 2
paperino pluto
topolino pippo


I 2 2 sono le dimensioni di una matrice 2x2 al cui interno devo memorizzare le parole sulle righe successive. Però se io faccio una matrice mat[2][2] in teoria posso memorizzare due parole da due lettere. Come faccio a memorizzare una parola intera in un blocco???
Avevo pensato a assegnare un puntatore a ogni parola imagazzinata e poi mettere il puntatore nella matrice,e ho provato a fare questo programma, ma non gira :cry: :cry:
#include <stdio.h>
#include <stdlib.h>
#define MAX 256
FILE *ptr1;
void riempi_matrice(char **matr,int r,int c);
int main()
{
FILE *ptr2;
char s1[MAX],s2[MAX];
int r,c;
char **mat;
//prendo il nome del file in lettura
printf("Salve utente, inserisci il nome del file in lettura-->");
scanf("%s",s1);
while((ptr1=fopen(s1,"r"))==NULL){
printf("\nNome file sbagliato, reinserire-->");
scanf("%s",s1);
}
printf("\nOra inserisci il nome del file in scrittura-->");
scanf("%s",s2);
ptr2=fopen(s2,"w");
//prendo i due numeri a inizio file
fscanf(ptr1,"%d %d",&r,&c);
riempi_matrice(mat,r,c);
return 0;
}

void riempi_matrice(char **matr,int r,int c){
int i,j;
char *parola,temp; //parola è un puntatore, temp una stringa di appoggio
//alloco dinamicamente la matrice
matr=(char **)calloc(r,sizeof(char *));
for(i=0;i<c;i++){
matr[i]=(char *)calloc(c,sizeof(char));
}
for(i=0;i<r;i++){
for(j=0;j<c;j++){
fscanf(ptr1,"%s",&temp);
parola=&temp;
matr[i][j]= *parola;
}
}
//cicli per la stampa della matrice
for(i=0;i<r;i++){
for(j=0;j<c;j++){
parola=&matr[i][j];
temp=*parola;
printf("%s\n",);
}
}
return;
}

IceCoder
01-10-2008, 18:10
dunque, nel primo ciclo for di riempi_matrice() non la condizione non dovrebbe essere i < r?

e poi temp non è una stringa ma un carattere singolo, una stringa è un array di caratteri.

hasmet
01-10-2008, 18:12
dunque, nel primo ciclo for di riempi_matrice() non la condizione non dovrebbe essere i < r?

e poi temp non è una stringa ma un carattere singolo, una stringa è un array di caratteri.

Si è vero adesso ho corretto, ma come potrei fare a memorizzare una stringa su un puntatore????

IceCoder
01-10-2008, 18:18
Si è vero adesso ho corretto, ma come potrei fare a memorizzare una stringa su un puntatore????

io farei cosi:



char *str = (char *)malloc(256); //creo una stringa da 256 caratteri che viene puntata da str

fscanf(file, "%s", str); //non metto & perchè str è un puntatore

mat[i][j] = str; //il puntatore mat[i][j] ora punta alla stringa creata



che ne dici?

hasmet
01-10-2008, 18:22
io farei cosi:



char *str = (char *)malloc(256); //creo una stringa da 256 caratteri che viene puntata da str

fscanf(file, "%s", str); //non metto & perchè str è un puntatore

mat[i][j] = str; //il puntatore mat[i][j] ora punta alla stringa creata



che ne dici?

Ok, però se io devo memorizzare più stringhe può funzionare??? Nel senso, se io faccio questo procedimento per più di una stringa, alla seconda stringa non rischio di sovrascrivere str e poi tutti i puntatori alla fine mi puntano alla medesima stringa???

IceCoder
01-10-2008, 18:28
Ok, però se io devo memorizzare più stringhe può funzionare??? Nel senso, se io faccio questo procedimento per più di una stringa, alla seconda stringa non rischio di sovrascrivere str e poi tutti i puntatori alla fine mi puntano alla medesima stringa???

no perchè la funzione malloc restituisce un puntatore, e quindi tu sovrascrivi il puntatore (che alla fine dei conti è un numero).

quando sovrascrivi il puntatore, str non punterà più alla stringa di prima ma alla nuova stringa creata.

volendo potresti ottimizzare il tuo codice eliminando la stringa temporanea utilizzando malloc() direttamente su mat[i][j], però non so se il tuo esercizio ti obblighi ad usare un puntatore temporaneo.

mi sento di dirti di fare piu domande che puoi se non ti è chiaro qualcosa riguardo i puntatori. sono una risorsa chiave del C. Una volta che capisci come funzionano ti risolvono tantissimi problemi e te ne innamori :D

hasmet
01-10-2008, 18:39
no perchè la funzione malloc restituisce un puntatore, e quindi tu sovrascrivi il puntatore (che alla fine dei conti è un numero).

quando sovrascrivi il puntatore, str non punterà più alla stringa di prima ma alla nuova stringa creata.

volendo potresti ottimizzare il tuo codice eliminando la stringa temporanea utilizzando malloc() direttamente su mat[i][j], però non so se il tuo esercizio ti obblighi ad usare un puntatore temporaneo.

mi sento di dirti di fare piu domande che puoi se non ti è chiaro qualcosa riguardo i puntatori. sono una risorsa chiave del C. Una volta che capisci come funzionano ti risolvono tantissimi problemi e te ne innamori :D

Di sicuro domani che avrò l'esercitazione mi prendo un esercitatore e lo tempesto di domande :D :D
Ti faccio solo più un'ultima domandina, io ho adattato il codice così
#include <stdio.h>
#include <stdlib.h>
#define MAX 256
FILE *ptr1;
void riempi_matrice(char **matr,int r,int c);
int main()
{
FILE *ptr2;
char s1[MAX],s2[MAX];
int r,c;
char **mat;
printf("Salve utente, inserisci il nome del file in lettura-->");
scanf("%s",s1);
while((ptr1=fopen(s1,"r"))==NULL){
printf("\nNome file sbagliato, reinserire-->");
scanf("%s",s1);
}
printf("\nOra inserisci il nome del file in scrittura-->");
scanf("%s",s2);
ptr2=fopen(s2,"w");
fscanf(ptr1,"%d %d",&r,&c);
riempi_matrice(mat,r,c);
return 0;
}
void riempi_matrice(char **matr,int r,int c){
int i,j;
char *parola;
parola=(char *)malloc(256*sizeof(char));
matr=(char **)calloc(r,sizeof(char *));
for(i=0;i<r;i++){
matr[i]=(char *)calloc(c,sizeof(char));
}
for(i=0;i<r;i++){
for(j=0;j<c;j++){
fscanf(ptr1,"%s",parola);
//QUI MI DA' UN WARNING
matr[i][j]=parola;
//QUI MI DA' UN ALTRO WARNING,è una printf di controllo
printf("%s\n",matr[i][j]);
}
}
return;
}
Alle due righe dove mi dà i warning poi mi dà un segmentation fault e mi esce dal prog, cosa devo correggere secondo te per farlo andare??? Ti ringrazio davvero per l'enorme aiuto che mi stai dando, ti prometto che è l'ultima domandina :D :D Grazie mille ancora

IceCoder
01-10-2008, 18:46
Alle due righe dove mi dà i warning poi mi dà un segmentation fault e mi esce dal prog, cosa devo correggere secondo te per farlo andare??? Ti ringrazio davvero per l'enorme aiuto che mi stai dando, ti prometto che è l'ultima domandina :D :D Grazie mille ancora

scusa ma quali warning ti da??

prova a debuggare, quali sono i valori di i e j al momento del crash?

tra due minuti scappo che sono in ritardo, se non risponde nessun'altro lo faccio io quando torno :D

IceCoder
01-10-2008, 18:50
ehi ho notato un'altra cosa.

parola=(char *)malloc(256*sizeof(char));

lo devi mettere nel ciclo, prima di fscanf, altrimenti avrai una matrice di parole uguali :D

EDIT:

in oltre questo ciclo:


for(i=0;i<r;i++){
matr[i]=(char *)calloc(c,sizeof(char));
}



non serve, perchè altrimenti creeresti chissà quante variabili inutili che non verranno mai scaricate dal tuo programma.
in oltre, se allochi memoria nel programma (tipo usando malloc()) è cosa buona e giusta liberarla a fine programma con la funzione free() o simili (ma se non te la senti ancora, non complicarti la vita ;))

hasmet
01-10-2008, 18:52
scusa ma quali warning ti da??

prova a debuggare, quali sono i valori di i e j al momento del crash?

tra due minuti scappo che sono in ritardo, se non risponde nessun'altro lo faccio io quando torno :D

Allora le variabili i e j sono 0 e 0.
Per la seconda cosa io devo per forza usare una matrice per memorizzare le parole, è obbligatorio per il programma

gugoXX
01-10-2008, 20:12
Una variabile di tipo
char**
Equivale ad una matrice bidimensionale la cui cella e' un char singolo
(Oppure un'array la cui cella e' una stringa, ovvero un char*)

Per una matrice bidimensionale la cui cella sia una stringa, hai bisogno di un
char***

qwerty86
01-10-2008, 21:39
Ragazzi scusate ma creare una matrice di stringhe ??

qwerty86
01-10-2008, 21:40
Ragazzi scusate ma creare una matrice di stringhe ??

mi rispondo da solo . Non mi ero accorto che si parlava di C.

Vincenzo1968
02-10-2008, 00:03
Forse ti può essere utile un esempio di allocazione/deallocazione dinamica della matrice tridimensionale:


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

int main()
{
char ***myArray;

int i, j;

int righe = 2, colonne = 2, len_string = 32;

// Allochiamo
myArray = (char***)malloc(righe*sizeof(char**));
if( NULL == myArray )
{
printf("Errore nell'allocazione della memoria.\n");
return -1;
}
for ( i = 0; i < righe; ++i )
{
myArray[i] = (char**)malloc(colonne*sizeof(char*));
if( NULL == myArray[i] )
{
printf("Errore nell'allocazione della memoria.\n");
return -1;
}
for( j = 0; j < colonne; ++j)
{
myArray[i][j] = (char*)malloc(len_string);
if( NULL == myArray[i][j] )
{
printf("Errore nell'allocazione della memoria.\n");
return -1;
}
}
}

strcpy(myArray[0][0], "Pippo");
strcpy(myArray[0][1], "Topolino");
strcpy(myArray[1][0], "Paperino");
strcpy(myArray[1][1], "Pluto");

printf("\n");

for( i = 0; i < righe; ++i)
{
for(int j = 0; j < colonne; ++j)
{
printf("myArray[%d][%d] -> %s\n", i, j, myArray[i][j]);
}
}

printf("\n");

// Deallochiamo
for( i = 0; i < righe; ++i)
{
for( j = 0; j < colonne; ++j)
{
free(myArray[i][j]);
}
free(myArray[i]);
}
free(myArray);

return 0;
}

gugoXX
02-10-2008, 00:08
Forse ti può essere utile un esempio di allocazione/deallocazione dinamica della matrice tridimensionale:

... cutcut ...

char ***myArray;


... cutcut ...



Ecco li' il char***
Un po' arrugginito di C speravo di non aver preso una cantonata.


Ciao Vincenzo. Quanto tempo...

Vincenzo1968
02-10-2008, 00:19
Ohé Gugo,

ciao :) Come stai?

P.S.
Quando ti decidi a postare un altro bel contest?

gugoXX
02-10-2008, 00:32
Ohé Gugo,

ciao :) Come stai?

P.S.
Quando ti decidi a postare un altro bel contest?

Eh, appena al lavoro saro' un po' tranquillo.
Parecchi terremoti in questi giorni, ma penso che si sia vicini alla luce.

hasmet
02-10-2008, 14:00
Forse ti può essere utile un esempio di allocazione/deallocazione dinamica della matrice tridimensionale:


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

int main()
{
char ***myArray;

int i, j;

int righe = 2, colonne = 2, len_string = 32;

// Allochiamo
myArray = (char***)malloc(righe*sizeof(char**));
if( NULL == myArray )
{
printf("Errore nell'allocazione della memoria.\n");
return -1;
}
for ( i = 0; i < righe; ++i )
{
myArray[i] = (char**)malloc(colonne*sizeof(char*));
if( NULL == myArray[i] )
{
printf("Errore nell'allocazione della memoria.\n");
return -1;
}
for( j = 0; j < colonne; ++j)
{
myArray[i][j] = (char*)malloc(len_string);
if( NULL == myArray[i][j] )
{
printf("Errore nell'allocazione della memoria.\n");
return -1;
}
}
}

strcpy(myArray[0][0], "Pippo");
strcpy(myArray[0][1], "Topolino");
strcpy(myArray[1][0], "Paperino");
strcpy(myArray[1][1], "Pluto");

printf("\n");

for( i = 0; i < righe; ++i)
{
for(int j = 0; j < colonne; ++j)
{
printf("myArray[%d][%d] -> %s\n", i, j, myArray[i][j]);
}
}

printf("\n");

// Deallochiamo
for( i = 0; i < righe; ++i)
{
for( j = 0; j < colonne; ++j)
{
free(myArray[i][j]);
}
free(myArray[i]);
}
free(myArray);

return 0;
}


Eh si alla fin fine ho risolto con una matrice di stringhe, grazie 1000 per l'aiuto