Vettore di stringhe in C

di il
6 risposte

Vettore di stringhe in C

Salve a tutti ragazzi, piccola premessa, sono nuovo, quindi chiedo venia nel caso infranga qualche regola del regolamento che ho appena finito di leggere...

Detto ciò; mi servirebbe una mano a capire qual è il problema in questo programma.
In pratica quello che dovrebbe fare è, con una funzione allocare memoria a dei puntatori di puntatori,
con un'altra funzione mi stampa i contenuti.

Il problema sorge quando si va a fare la stampa, infatti è proprio lì che crasha il programma...

Mi potreste aiutare a capire dove ho sbagliato? Magari se ho sbagliato qualcosa con i puntatori...
Premetto, la logica che ho usato è stata:

char **v = (char**) calloc(3, sizeof(char*));
for (i = 0; i < 3; i++)
{
*(v + i) = (char*) calloc(21, sizeof(char)); //dove 21 è 20 caratteri + '\0' carattere terminatore
}

Di seguito il codice per intero:

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

// Da eliminare, utile per debug
#define N 3

void fillV(char **v, int n);
void printV(char **v, int n);

int main(void)
{
	char **str = NULL;

//	fillV(str, N); 	//La funzione fillV pare funzionare

//	printf(*str);
//	printV(str, N); //printV ci avvisa della stampa in corso ma manda in crash il programma

	system("PAUSE");
	return EXIT_SUCCESS;
}

/*
 * La funzione fillV ha come parametri **v che è un vettore di stringhe (char**)
 * Il secondo parametro ci dice quante stringhe verranno occupate per il vettore
 * e con le rispettiva funzione calloc gli assegno n indirizzi che puntano a stringhe di 20 caratteri ciascuno
 * dopodiché prendo in input da tastiera la stringa da inserire in ogni stringa allocata
 * terminata la funzione avvertiamo del riempimento completato del vettore di stringhe
 */
void fillV(char **v, int n)
{
	int i = 0;
	v = (char**) calloc(n, sizeof(char*));

	printf("Riempimento di un vettore con %i stringhe\n\n", n);
	while (i < n)
	{
		*(v + i) = (char*) calloc(21, sizeof(char));
		printf("Stringa N.%i: ", i + 1);
		scanf("%s", *(v + i));
		i++;
	}
	printf("\nRiempimento completato\n");
	return;
}

/*
 * La funzione printV ha come parametri **v, il solito vettore di stringhe
 * e n che ci dice di quante stringhe è composto. Dopodiché grazie ad
 * una variabile i, cicliamo il vettore di stringhe per stamparle una ad una
 * utilizzando la sintassi per deferenziare i puntatori (di puntatori)
 */
void printV(char **v, int n)
{
//	char *tmp = (char*) malloc(100 * sizeof(char));
	int i = 0;
	printf("\nStampa di un vettore di stringhe\n");
	while (i < n)
	{
		printf("%s", *(v + i));
//		snprintf(tmp, 15, "%s\n", *(v + i));
		i++;
	}
	return;
}

6 Risposte

  • Re: Vettore di stringhe in C

    Proporrei una soluzione come segue:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define N 3
    
    char ** fillV(int n);
    void printV(char **v, int n);
    
    int main(void)
    {
    
       char **str;
       str = fillV(N); 
       printV(str, N);
    
       return EXIT_SUCCESS;
    }
    
    
    char ** fillV(int n)
    {
       int i = 0;
       char **v;
       v = calloc(n, sizeof(char*));
    
       printf("Riempimento di un vettore con %i stringhe\n\n", n);
       while (i < n)
       {
          v[i] = calloc(21, sizeof(char));
          printf("Stringa N.%i: ", i + 1);
          scanf("%s", v[i]);
          i++;
       }
       printf("\nRiempimento completato\n");
       return v;
    }
    
    
    void printV(char **v, int n)
    {
       int i = 0;
       printf("\nStampa di un vettore di stringhe\n");
       while (i < n)
       {
          printf("%s\n", v[i]);
          i++;
       }
    
       return;
    }
  • Re: Vettore di stringhe in C

    Randomizzatore ha scritto:


    Il problema sorge quando si va a fare la stampa
    Ma la causa è nella funzione di riempimento.

    Quando passi un argomento che deve essere modificato, lo devi fare per puntatore.
    Dato che anche il doppio puntatore v dovrà essere modificato, questo dovrà essere passato come un triplo puntatore.

    Dunque dovrai modificare
    
    void fillV(char ***v, int n);
    
    
    int main(void)
    {
    	char **str = NULL;
    
    	fillV(&str, N); 	
    
    
    void fillV(char ***v, int n)
    {
    	int i = 0;
    	*v = (char**) calloc(n, sizeof(char*));
    
    	printf("Riempimento di un vettore con %i stringhe\n\n", n);
    	while (i < n)
    	{
    		*(*v + i) = (char*) calloc(21, sizeof(char));
    		printf("Stringa N.%i: ", i + 1);
    		scanf("%s", *(*v + i));
    		i++;
    	}
    	printf("\nRiempimento completato\n");
    	return;
    }
    
  • Re: Vettore di stringhe in C

    oregon ha scritto:


    Randomizzatore ha scritto:


    Il problema sorge quando si va a fare la stampa
    Ma la causa è nella funzione di riempimento.

    Quando passi un argomento che deve essere modificato, lo devi fare per puntatore.
    Dato che anche il doppio puntatore v dovrà essere modificato, questo dovrà essere passato come un triplo puntatore.

    Dunque dovrai modificare
    
    void fillV(char ***v, int n);
    
    
    int main(void)
    {
    	char **str = NULL;
    
    	fillV(&str, N); 	
    
    
    void fillV(char ***v, int n)
    {
    	int i = 0;
    	*v = (char**) calloc(n, sizeof(char*));
    
    	printf("Riempimento di un vettore con %i stringhe\n\n", n);
    	while (i < n)
    	{
    		*(*v + i) = (char*) calloc(21, sizeof(char));
    		printf("Stringa N.%i: ", i + 1);
    		scanf("%s", *(*v + i));
    		i++;
    	}
    	printf("\nRiempimento completato\n");
    	return;
    }
    
    Ringrazio vuott e oregon.

    Ma in particolare, oregon, ero curioso della tua alternativa. Mi potresti spiegare il perché di questa soluzione?

    Perché dando un puntatore di puntatori per valore non funzionava, mentre dandolo per riferimento mi ha dato l'output richiesto?
  • Re: Vettore di stringhe in C

    Te l'ho spiegato prima.

    Se tu volessi passare un int da modificare all'interno di una funzione, come faresti?
  • Re: Vettore di stringhe in C

    Non esiste il passaggio per riferimento in C! Viene passato tutto per valore, perciò per modificare una variabile occorre fornire alla funzione l'indirizzo di tale variabile. A tale fine si usa un puntatore che ovviamente viene passato per valore. Da ciò si capisce facilmente che per alterare il valore di un puntatore occorre passare il suo indirizzo e da qui il motivo dei vari livelli di indirezione.
  • Re: Vettore di stringhe in C

    Quindi dando solamente il puntatore di puntatori, quando la funzione termina ho perso tutta la memoria allocata?
Devi accedere o registrarti per scrivere nel forum
6 risposte