Puntatori: array di dimensione variabile di stringhe di dimensione nota

di il
29 risposte

Puntatori: array di dimensione variabile di stringhe di dimensione nota

Ciao a tutti,
vi chiedo di avere pazienza per il quesito che vi sottopongo. Probabilmente già discusso, ma argomento che non sono riuscito a estrapolare dai tantissimi post.
Come ho indicato, avrei necessità di gestire un array di stringhe - il cu numero non è noto - e le cui stringhe anch'esse hanno domensione non fissa.

Devo usare un puntatore a puntatore? Ma non mi è chiaro poi come riservare (allocare la memoria).

Un esempio potrebbe essere quello in cui da console si chiede una lista, il cui numero non è nosto a priori di nomi e via via immagazzinarli in un array di stringhe. Devo utilizzare delle stringhe temporanee e poi allocare un array in maniera dinamica?

Vi chiedo ancora scusa e vi porgo i miei ringraziamenti.

29 Risposte

  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    Con un puntatore doppio allochi un vettore di puntatori a char.

    Usi ogni puntatore per allocare lo spazio di ogni stringa
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    oregon ha scritto:


    Con un puntatore doppio allochi un vettore di puntatori a char.

    Usi ogni puntatore per allocare lo spazio di ogni stringa
    Ciao Oregon,
    grazie mille per la tua risposta… Sono davvero ancora molto a digiuno, intuisco qualcosa del genere:

    char **arrayStringhe;

    Poi raccoglo N stringhe (char *) e poi devo calcolare la loro dimensione e allocare arrayStringhe?
    A quel punto ogni locazione (indice) di arrayStringhe lo devo valorizzare con i vari char* che ho precedentemente raccolto.
    Scusami, confermarmi se l'intuizione è sbagliata e magari chiarire la mia grossa lacuna con un esempio di codice.

    Grazie di mille.
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    Per 3 stringhe da 80 caratteri (compreso terminatore)
    
    	char **arrayStringhe;
    	int n = 3;
    	int i;
    	arrayStringhe = (char **)malloc(n * sizeof(char *));
    	for(i=0; i<n; i++)
    		arrayStringhe[i] = (char *)malloc(80 * sizeof(char));
    
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    @deckard invece che a caccia di replicanti e di post su un forum, dovresti andare a caccia sul libro di testo delle informazioni che ti servono

    Su che libro stai studiando?
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    migliorabile ha scritto:


    @deckard invece che a caccia di replicanti e di post su un forum, dovresti andare a caccia sul libro di testo delle informazioni che ti servono

    Su che libro stai studiando?
    Ciao migliorabile,
    hai perfettamente ragione, infatti questa mattina mi dovrebbe arrivare "Il linguaggio C. Principi di programmazione e manuale di riferimento" Di Brian W. Kerningan, Dennis M. Ritichie. Il "bianco" il mio originale di tanti anni fa non lo trovo più.

    Tuttavia, se la mia mente non erra, ed è probabile che stia sbagliando non ricordo che nella sezione puntatori trattasse la questione che ho esposto.

    Ora rispondo all'esempio di Oregon. Mi torna quasi tutto, eccezion fatta per una questione. Purtroppo ho messo, per non volontà mia, nin stanby l'uso del C da diversi anni e mi sono dimenticato un po' di cose. Devo far veloce perché poi devo riprendere il C++ a manetta. Scusatemi e siete davvero gentili.
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    ... eccezion fatta per una questione ...
    Ovvero?
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    oregon ha scritto:


    Per 3 stringhe da 80 caratteri (compreso terminatore)
    
    	char **arrayStringhe;
    	int n = 3;
    	int i;
    	arrayStringhe = (char **)malloc(n * sizeof(char *));
    	for(i=0; i<n; i++)
    		arrayStringhe[i] = (char *)malloc(80 * sizeof(char));
    
    Gentilissimo Oregon,
    come già scrivevo in un post ad un altro amico che mi ha scritto in merito, sto provvedendo a recuperare un buon libro, mi dovrebbe arrivare oggi il K&R, anche se tanti anni fa - non lo trovo più - non mi pare trattasse, nell'ambito dei puntatori, tale aspetto.

    Il tuo codice mi è piuttosto chiero adesso. Unica perplessità, se io mi trovo in una situazione "dinamica" in cui il numero di "record" (righe, la prima dimensione dell'array bidimensionale) non è noto a priori dovrei ridimensionare tale dimensione. Di seguito ti porto un banale caso, per intenderci meglio sulla situazione che porto a titolo di esempio:
    
        char *list[4];
        int righe = 0;
        
        while(1==1)
        {
            list[righe] = malloc(80*sizeof(char));
            printf("Nominativo: ");
            gets(list[righe]);
            if (list[righe][0] == 'exit')
            {
                printf("Uscita...");
                break;
            }
            righe++;
            if (righe == 4)
            {
                break;
            }
    
        }
    
    Superata la riga (indice uguale a 3) teoricamente dovrei riallocare la dimensione delle righe del mio puntatore a puntatore (corretto?)
    A tal fine, poste vere le mie assunzioni, ho tentato di estendere il frammento di codice nel seguente modo:
    
        char *list[4];
        char *temp;
        int righe = 0;
    
        while(1==1)
        {
            list[righe] = malloc(80*sizeof(char));
            printf("Nominativo: ");
            gets(list[righe]);
            if(list[righe][0] == 'exit')
            {
                printf("EOF...");
                break;
            }
    
            righe++;
    
            if((righe % 4)==0)
            {
                printf("Ridimensiono le righe...\n");
                temp = realloc(*list, sizeof(*list)*2);
                *list = temp;
                printf("Nuova dimensione %d\n", sizeof(*list));
            }
        }
    
    Ma ahimé dopo pochi nuovi inserimenti, dalla stampata a video della stringa "Ridimensiono le righe…" il programma va in segmentation fault.

    Chiedo ancora scusa per il mio basso livello di conoscenza. Spero mi arrivi il libro quanto prima, anche se a mente non mi parte fosse tratta questo aspetto sul K&R

    Ancora grazie infinite.
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    Il mio codice è diverso dal tuo. Lo hai letto?
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    Ciao Oregon,
    sì l'ho letto. Tu in effetti dichiari esplicitamente char **arrayStringhe (puntatore a puntatore). Poi riservi la memoria per 4 righe, che dovrebbe essere equivalente a char list[4]. Tuttavia io ho scritto char *list[4] che quindi dovrebbe essere un puntatore a puntatore. L'errore, devo dedure, ponendo attenzione sulla tua osservazione è che ho staticamente definito la dimensione delle righe e un successiva espansione (riallocare la memoria) genera errore?
    Grazie per la discussione che stai intrattenendo con me, davvero stimolante e proficua. Ti ringrazio, inoltre, per il tempo che mi stai offrendo. Provo a scrivere usando il tuo formalismo e riallocare la memoria con l'approccio, forse non elegante, che ho scritto nel mio frammento di codice che ho riportato. Ti aggiorno sull'esito; se sto sbagliando a interpretare la tua osservazione avvertimi prima!!!
    Grazie ancora!
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    È proprio sbagliato lo approccio.
    vuoi qualcosa di 'intelligente'?
    Perché in C quello che vuoi non si può fare, nel senso che non ci sono costrutti per strutture dinamiche che 'magicamente' aumentino di capacità.
    qualora ti servissero (cosa frequentissima) la logica prevede di creare una libreria che 'nasconda' al complessità, mediante liste, array ridimensionati automaticamente o quello che ti pare.

    Concetto praticamente identico a quello che faresti in C++ con 'similoggetti'.

    Pertanto per una gestione affidabile in C mai e poi mai affrontare `a casaccio ', cioè situazioni complesse scritte al volo.
    anche per uno davvero esperto il rischio di errore è alto
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    Nota di servizio: nel tuo caso, normalmente, si opera con liste di stringhe, qualora si voglia enfatizzare la dinamicità.
    vettori riallocati se e solo se le prestazioni sono fondamentali e il ridimensionare raro o rarissimo
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    Puoi usare il codice che ti ho mostrato e non il tuo, servendoti della realloc dove serve. Fai attenzione e usa il codice per imparare. Per cose serie usa gli oggetti appositi della libreria c++
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    +m2+ ha scritto:


    È proprio sbagliato lo approccio.
    vuoi qualcosa di 'intelligente'?
    Perché in C quello che vuoi non si può fare, nel senso che non ci sono costrutti per strutture dinamiche che 'magicamente' aumentino di capacità.
    qualora ti servissero (cosa frequentissima) la logica prevede di creare una libreria che 'nasconda' al complessità, mediante liste, array ridimensionati automaticamente o quello che ti pare.

    Concetto praticamente identico a quello che faresti in C++ con 'similoggetti'.

    Pertanto per una gestione affidabile in C mai e poi mai affrontare `a casaccio ', cioè situazioni complesse scritte al volo.
    anche per uno davvero esperto il rischio di errore è alto
    Ciao +m2+,
    grazie anche a te per il tuo intervento. Con l'umiltà del caso, comprendi bene il senso e il tono di quanto scrivo, sono consapevole che il C non consente di usufruire di costrutti che consentano automaticamente l'ampliamento della dimensione. Proprio per questo vorrei entrare nel dettaglio a basso livello (ne ho bisogno). Ma non capisco cosa vuoi dire con
    È proprio sbagliato lo approccio.
    . Il tentativo è comprendere i meccanismi di allocazione e riallocazione della memoria per potermi scrivere un libreria ad hoc.

    Non a caso questo tentativo di comprendere, a più basso livello, è e vuole essere propedeutico a passare poi a C++. In quanto C e C++ saranno entrambi per me essenziali nelle attività future.
    Nel complesso concordo che le cose non devono essere fatte a casaccio, semplicemente il codice che vedi sono frammenti di codice di semplici studi. Non rappresentano un codice reale.

    Grazie
  • Re: Puntatori: array di dimensione variabile di stringhe di dimensione nota

    oregon ha scritto:


    Puoi usare il codice che ti ho mostrato e non il tuo, servendoti della realloc dove serve. Fai attenzione e usa il codice per imparare. Per cose serie usa gli oggetti appositi della libreria c++
    Grazie Oregon,
    sto usando il tuo codice, ma ho ancora qualche difficoltà in fase di riallocazione… Insisto, nel caso, proverò a chiederti ancora aiuto. Ti ringrazio davvero. Sono consapevole che il C++, passo successivo, consente con più semplicità gestire tali situazioni. Ma per le attività che dovrò svolgere ho bisogno di passare da un linguaggio all'altro a seconda del contesto (C, piuttosto che C++). Anche +m2+ mi faceva osservare questo. Ma avendo bisogno - a seconda del contesto - di dover usare C piuttosto che C++ e viceversa vorrei studiare fino ad arrivare al più basso livello di utilizzo. Con tutta l'umiltà e la consapevolezza della difficoltà.

    Secondo me sto sbagliando a passare i riferimenti alla realloc…

    Ti tengo informato. Ancora grazie infinite.
Devi accedere o registrarti per scrivere nel forum
29 risposte