Visualizzazione dei risultati da 1 a 9 su 9

Discussione: Char x char... S x s

  1. #1

    Char x char... S x s

    Salve, non riesco a fare una cosa(fosse una sola...). Mettiamo che abbia una stringa in input formata da N parole di M lettere. Vorrei creare un array dinamico che riallochi memoria per ogni diversa parola ogni volta che incontro uno spazio nella stringa, e allo stesso tempo voglio riallocare spazio dinamicamente per ogni singolo char che leggo.
    Quindi: alloco char per char, e quando finisce la parola, alloco spazio per quella parola intera letta come stringa. Vorrei capire bene come funzionano i puntatori a puntatori, malloc e realloc.

    Io ho immaginato un punt di punt con un doppio ciclo for: quello interno che rialloca i char e quello esterno le stringhe(parola), ma anche fosse giusta l'idea non riesco a scriverlo. Una guida?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Quote Originariamente inviata da caramelleamare Visualizza il messaggio
    Io ho immaginato un punt di punt con un doppio ciclo for: quello interno che rialloca i char e quello esterno le stringhe(parola), ma anche fosse giusta l'idea non riesco a scriverlo. Una guida?
    Parliamo di C, giusto?

    Perché non parti da compiti più semplici per capire meglio i puntatori?

    Guide specifiche non hanno senso ... basta un capitolo di un libro sui puntatori
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Si C.
    Guida nel senso di una mano. Cose più semplici mi riescono più o meno, volevo vedere di capire questo schema complicato per avere uno schema di ragionamento al quale fare riferimento. Poi non riesco a mettere da parte un progetto! Le guide che trovo si fermano a un certo punto della spiegazione, e io non riesco a fare il passo successivo da solo, lo volevo vedere illustrato una volta.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Quote Originariamente inviata da caramelleamare Visualizza il messaggio
    Si C.
    Guida nel senso di una mano. Cose più semplici mi riescono più o meno, volevo vedere di capire questo schema complicato per avere uno schema di ragionamento al quale fare riferimento. Poi non riesco a mettere da parte un progetto! Le guide che trovo si fermano a un certo punto della spiegazione, e io non riesco a fare il passo successivo da solo, lo volevo vedere illustrato una volta.
    Prova ad iniziare a scrivere da solo la prima parte, quella che separa le parole e alloca lo spazio per ognuna. Lascia perdere la seconda, per ora.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Riguardo alla realloc(), vi sono effettivamente tre cose fondamentali che devi sapere subito:

    1) Non va usata e devi dimenticarti anche della sua esistenza.

    2) Non va usata e devi dimenticarti anche della sua esistenza.

    3) Non va usata e devi dimenticarti anche della sua esistenza.


    Escludendo le funzioni hard I/O bound (es. lettura/scrittura su supporti di massa, I/O su filestream di sistema che corrispondono a socket TCP/IP, linee e bus seriali, etc), la realloc() è la funzione in assoluto potenzialmente più inefficiente e disastrosa dal punto di vista prestazionale dell'intera libreria standard. Nessun principiante dovrebbe sognarsi di usarla, men che meno con una densità elevata di chiamate in un singolo programma. E anche i professionisti devono ricorrervi con estrema parsimonia.

    Dunque, segui l'ottimo consiglio del nostro oregon, accetta la stringa di partenza in un unico buffer di ampie dimensioni, allocato staticamente, e poi divertiti a reinventare una strtok() fatta in casa per separare le varie parole, allocando dinamicamente lo spazio per ciascuna di esse.
    Ultima modifica di M.A.W. 1968; 30-11-2014 a 01:46
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  6. #6
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Prova ad iniziare a scrivere da solo la prima parte, quella che separa le parole e alloca lo spazio per ognuna. Lascia perdere la seconda, per ora.
    Ok, scriverò questa parte di codice appena posso e poi la posterò.

  7. #7
    Quote Originariamente inviata da M.A.W. 1968 Visualizza il messaggio
    Riguardo alla realloc(), vi sono effettivamente tre cose fondamentali che devi sapere subito:

    1) Non va usata e devi dimenticarti anche della sua esistenza.

    2) Non va usata e devi dimenticarti anche della sua esistenza.

    3) Non va usata e devi dimenticarti anche della sua esistenza.


    Escludendo le funzioni hard I/O bound (es. lettura/scrittura su supporti di massa, I/O su filestream di sistema che corrispondono a socket TCP/IP, linee e bus seriali, etc), la realloc() è la funzione in assoluto potenzialmente più inefficiente e disastrosa dal punto di vista prestazionale dell'intera libreria standard. Nessun principiante dovrebbe sognarsi di usarla, men che meno con una densità elevata di chiamate in un singolo programma. E anche i professionisti devono ricorrervi con estrema parsimonia.

    Dunque, segui l'ottimo consiglio del nostro oregon, accetta la stringa di partenza in un unico buffer di ampie dimensioni, allocato staticamente, e poi divertiti a reinventare una strtok() fatta in casa per separare le varie parole, allocando dinamicamente lo spazio per ciascuna di esse.
    Si, sapevo che la realloc è da cestinare, ma non me ne frega niente della qualità del programma adesso. Lo faccio per un discorso di comprensione dell'utilizzo, con cicli su cilci, puntatori etc. Quando quello che dovrò programmare avrà un senso mi ricorderò delle tre regole fondamentali da te esposte, sperando di ricordarle tutte perché sono davvero molto articolate.

  8. #8
    Quote Originariamente inviata da caramelleamare Visualizza il messaggio
    Quando quello che dovrò programmare avrà un senso mi ricorderò delle tre regole fondamentali da te esposte, sperando di ricordarle tutte perché sono davvero molto articolate.
    Come già ebbe a dire un giovane e burlone fisico statistico su un altro forum, quelle regole puoi sempre fartele tatuare su un avambraccio, così da risparmiare sinapsi, usandole invece per memorizzare i contenuti di questi testi, dei quali tali regole sono un minimale frammento.

    Riguardo ai puntatori, potrebbe anche interessarti studiare questo sempreverde esempio, che illustra una silloge di tecniche di buona programmazione ed engineering coerente, MISRA/C compatibile, pur mantenendo uno stile ampiamente accettabile didatticamente.
    codice:
    /*
    ** alloc_example.c
    **
    ** Esempi di allocazione con passaggio di puntatori a vari livelli
    ** di indirezione.
    **
    */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <assert.h>
    
    #define DIM (6)
    
    /********************************************************************/
    
    #ifdef ALLOC_FAIL_01
      #pragma message("Compilazione di TEST con ALLOC_FAIL_01 abilitato.")
    #endif
    
    #ifdef ALLOC_FAIL_02
      #pragma message("Compilazione di TEST con ALLOC_FAIL_02 abilitato.")
    #endif
    
    #ifdef ALLOC_FAIL_03
      #pragma message("Compilazione di TEST con ALLOC_FAIL_03 abilitato.")
      #ifdef TEST_AT
        #undef TEST_AT
      #endif
      #define TEST_AT (r-3)
    #endif
    
    #ifdef ALLOC_FAIL_04
      #pragma message("Compilazione di TEST con ALLOC_FAIL_04 abilitato.")
    #endif
    
    #ifdef ALLOC_FAIL_05
      #pragma message("Compilazione di TEST con ALLOC_FAIL_05 abilitato.")
      #ifdef TEST_AT
        #undef TEST_AT
      #endif
      #define TEST_AT (2)
    #endif
    
    #ifdef ALLOC_FAIL_06
      #pragma message("Compilazione di TEST con ALLOC_FAIL_06 abilitato.")
    #endif
    
    #ifdef ALLOC_FAIL_07
      #pragma message("Compilazione di TEST con ALLOC_FAIL_07 abilitato.")
    #endif
    
    #ifdef ALLOC_FAIL_08
      #pragma message("Compilazione di TEST con ALLOC_FAIL_08 abilitato.")
      #ifdef TEST_AT
        #undef TEST_AT
      #endif
      #define TEST_AT (r-1)
    #endif
    
    #ifdef ALLOC_FAIL_09
      #pragma message("Compilazione di TEST con ALLOC_FAIL_09 abilitato.")
      #ifdef TEST_AT
        #undef TEST_AT
      #endif
      #define TEST_AT (c-3)
    #endif
    
    /********************************************************************/
    
    typedef enum {FALSE, TRUE} boole_t;
    
    typedef struct
    {
        char    *myString;
        size_t  myStrLen;
        int     iVal;
    } myStruct_t;
    
    boole_t alloc_vector(int **v, const size_t s);
    boole_t alloc_string(char **st, size_t *s);
    boole_t alloc_string_vect(char ***m, const size_t r, size_t *c);
    boole_t alloc_string_matrix(char ****m, const size_t r, const size_t c, size_t *le);
    boole_t alloc_struct_vect(myStruct_t **ms, const size_t s, size_t *le);
    boole_t alloc_struct_matrix(myStruct_t ***ms, const size_t r, const size_t c, size_t *le);
    
    /********************************************************************/
    /********************************************************************/
    
    int main(void)
    {
        boole_t status = FALSE;
        size_t i;
        char ***ma = NULL;
        char **m = NULL;
        char *s = NULL;
    
        myStruct_t *ms = NULL;
        int *v = NULL;
        size_t vDim = 0;
    
        puts("Esempi di allocazione indiretta con passaggio di\n"
             "puntatori a vari livelli di indirezione.\n");
    
        puts("1) Allocazione stringa singola.");
        status = alloc_string(&s, &vDim);
        if(status)
        {
            printf("   Dimensione....: %d\n"
                   "   Contenuto.....: [%s]\n", vDim, s);
            free(s);
        }
        else
        {
            puts(">>> Errore di allocazione!");
        }
    
        puts("\n2) Allocazione vettore di stringhe.");
        status = alloc_string_vect(&m, DIM, &vDim);
        if(status)
        {
            printf("   Dimensione....: %d\n"
                   "   Contenuti.....:\n", vDim);
    
            for(i = 0; i < DIM; ++i)
            {
                printf("     m[%d]: \"%s\"\n", i, m[i]);
                free(m[i]);
            }
            free(m);
        }
        else
        {
            puts(">>> Errore di allocazione!");
        }
    
        puts("\n3) Allocazione vettore di strutture.");
        status = alloc_struct_vect(&ms, DIM, &vDim);
        if (status)
        {
            puts("   Contenuti.....:");
            for(i = 0; i < DIM; ++i)
            {
                printf("     ms[%d].myString.....: \"%s\"\n"
                       "     ms[%d].myStrLen.....: %d\n"
                       "     ms[%d].iVal.........: %d\n",
                       i, ms[i].myString,
                       i, ms[i].myStrLen,
                       i, ms[i].iVal);
    
                free(ms[i].myString);
            }
            free(ms);
        }
        else
        {
            puts(">>> Errore di allocazione!");
        }
    
        puts("\n4) Allocazione vettore di interi.");
        status = alloc_vector(&v, DIM);
        if (status)
        {
            puts("   Contenuti.....:");
            for(i = 0; i < DIM; ++i)
            {
                printf("     v[%d] = %d\n", i, v[i]);
            }
            free(v);
        }
        else
        {
            puts(">>> Errore di allocazione!");
        }
    
        puts("\n5) Allocazione matrice di stringhe.");
        status = alloc_string_matrix(&ma, DIM, DIM, &vDim);
        if (status)
        {
            puts("   Contenuti.....:");
            for(i = 0; i < DIM; ++i)
            {
                size_t j;
                for (j = 0; j < DIM; ++j)
                {
                    printf("     ma[%d][%d] = \"%s\"\n", i, j, ma[i][j]);
                    free(ma[i][j]);
                }
                puts("");
                free(ma[i]);
            }
            free(ma);
        }
        else
        {
            puts(">>> Errore di allocazione!");
        }
    
        return status ? EXIT_SUCCESS : EXIT_FAILURE;
    }
    
    /********************************************************************/
    /********************************************************************/
    boole_t alloc_string(char **st, size_t *s)
    {
        const char *string = "Stringa di prova.";
    
        assert(NULL != s);
    
        *s = strlen(string) + 1;
    
    #ifdef ALLOC_FAIL_01
        *st = NULL;
        fprintf(stderr, "- simulazione errore di allocazione stringa.\n");
    #else
        *st = (char *)malloc((*s) * sizeof(char));
    #endif
    
        if (NULL != *st)
        {
            strcpy(*st, string);
        }
    
        return (boole_t)(NULL != *st);
    }
    
    /********************************************************************/
    boole_t alloc_string_vect(char ***m, const size_t r, size_t *c)
    {
        const char *string = "Stringa_";
        boole_t retval = FALSE;
    
        assert(NULL != c);
        assert(r > 1);
    
        *c = strlen(string) + 3;
    
    #ifdef ALLOC_FAIL_02
        *m = NULL;
        fprintf(stderr, "- simulazione errore di allocazione vettore.\n");
    #else
        *m = (char **)malloc(r * sizeof(char *));
    #endif
    
        if (NULL != *m)
        {
            size_t i;
            retval = TRUE;
    
            for(i = 0; i < r; ++i)
            {
                char *p;
                p = (char *)malloc(*c * sizeof(char));
    
    #ifdef ALLOC_FAIL_03
                if (TEST_AT == i)
                {
                    free(p);
                    p = NULL;
                    fprintf(stderr, "- simulazione errore di allocazione elemento %d\n", i);
                }
    #endif
                if (NULL != p)
                {
                    sprintf(p, "%s%02d", string, i +1);
                    (*m)[i] = p;
                }
                else
                {
                    do
                    {
                        --i;
                        free((*m)[i]);
                        fprintf(stderr, "- deallocazione elemento %d\n", i);
                    } while(i);
                    free(*m);
    
                    retval = FALSE;
                    break;
                }
            }
        }
    
        return retval;
    }
    
    /********************************************************************/
    boole_t alloc_struct_vect(myStruct_t **ms, const size_t r, size_t *le)
    {
        const char *string = "Stringa-in-struct_";
        boole_t retval = FALSE;
    
        assert(NULL != le);
        assert(r > 1);
    
        *le = strlen(string) +3;
    
    #ifdef ALLOC_FAIL_04
        *ms = NULL;
        fprintf(stderr, "- simulazione errore di allocazione vettore.\n");
    #else
        *ms = (myStruct_t *)malloc(r * sizeof(myStruct_t));
    #endif
    
        if (NULL != *ms)
        {
            size_t i;
            retval = TRUE;
    
            for(i = 0; i < r; ++i)
            {
                char *p;
    
                p = (char *)malloc((*le) * sizeof(char));
    
    #ifdef ALLOC_FAIL_05
                if (TEST_AT == i)
                {
                    free(p);
                    p = NULL;
                    fprintf(stderr, "- simulazione errore di allocazione elemento %d\n", i);
                }
    #endif
    
                if(NULL != p)
                {
                    sprintf(p, "%s%02d", string, i);
                    ((*ms)[i]).myString = p;
                    ((*ms)[i]).myStrLen = strlen(p);
                    ((*ms)[i]).iVal = i;
                }
                else
                {
                    while (i--)
                    {
                        free((*ms)[i].myString);
                        fprintf(stderr, "- deallocazione elemento %d\n", i);
                    }
                    free(*ms);
                    retval = FALSE;
                    break;
                }
            }
        }
    
        return retval;
    }
    
    /********************************************************************/
    boole_t alloc_vector(int **v, const size_t s)
    {
        boole_t retval = FALSE;
        size_t i;
    
        assert(s > 1);
    
    #ifdef ALLOC_FAIL_06
        *v = NULL;
        fprintf(stderr, "- simulazione errore di allocazione vettore.\n");
    #else
        *v = (int *)malloc(s * sizeof(int));
    #endif
    
        if (NULL != *v)
        {
            for(i = 0; i < s; ++i)
            {
                (*v)[i] = i;
            }
    
            retval = TRUE;
        }
    
        return retval;
    }
    
    /********************************************************************/
    boole_t alloc_string_matrix(char ****m, const size_t r,
                                const size_t c, size_t *le)
    
    {
        const char *string = "Testo_";
        boole_t retval = FALSE;
    
        assert(NULL != le);
        assert(r > 1);
        assert(c > 1);
    
        *le = strlen(string) + 6;
    
    #ifdef ALLOC_FAIL_07
        *m = NULL;
        fprintf(stderr, "- simulazione errore di allocazione matrice.\n");
    #else
        *m = (char ***)malloc(r * sizeof(char **));
    #endif
    
        if (NULL != *m)
        {
            size_t i, j;
            retval = TRUE;
    
            for(i = 0; i < r; ++i)
            {
                char **p;
                p = (char **)malloc(c * sizeof(char *));
    
    #ifdef ALLOC_FAIL_08
                if (TEST_AT == i)
                {
                    free(p);
                    p = NULL;
                    fprintf(stderr, "- simulazione errore di allocazione riga %d\n", i);
                }
    #endif
                if (NULL != p)
                {
                    (*m)[i] = p;
    
                    for (j = 0; j < c; ++j)
                    {
                        char *q;
                        q = (char *)malloc((*le) * sizeof(char));
    
    #ifdef ALLOC_FAIL_09
                        if ((TEST_AT == j) && (TEST_AT == i))
                        {
                            free(q);
                            q = NULL;
                            fprintf(stderr, "- simulazione errore di allocazione"
                                    " elemento %d, riga %d\n", j, i);
                        }
    #endif
    
                        if (NULL != q)
                        {
                            sprintf(q, "%s%02d_%02d", string, i +1, j +1);
                            (*m)[i][j] = q;
                        }
                        else
                        {
                            while (j--)
                            {
                                free((*m)[i][j]);
                                fprintf(stderr, "- deallocazione elemento %d\n", j);
                            }
                            free((*m)[i]);
                            retval = FALSE;
                            break;
                        }
                    }
                }
                else
                {
                    retval = FALSE;
                }
    
                if (!retval)
                {
                    size_t k;
                    for (k = 0; k < i; ++k)
                    {
                        fprintf(stderr, "- riga %d:\n", k);
                        if (NULL != (*m)[k][0])
                        {
                            for (j = 0; j < c; ++j)
                            {
                                free((*m)[k][j]);
                                fprintf(stderr, "  - deallocazione elemento %d\n", j);
                            }
                        }
                        free((*m)[k]);
                        fprintf(stderr, "  - deallocazione riga %d\n", k);
                    }
                    free(*m);
                    break;
                }
            }
        }
        return retval;
    }
    
    /********************************************************************/
    boole_t alloc_struct_matrix(myStruct_t ***ms, const size_t r,
                                const size_t c, size_t *le)
    {
        return TRUE;
    }
    
    /********************************************************************/
    /* EOF: alloc_example.c                                             */
    /********************************************************************/


    E' inoltre caldamente consigliato l'uso di Valgrind, o equivalentemente di DrMemory, quando si giocherella con puntatori assortiti e allocazione dinamica.
    Ultima modifica di M.A.W. 1968; 30-11-2014 a 15:41 Motivo: mistype
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  9. #9
    Grazie mille, ottimo anche il link con i manuali. Guarderò il codice nei prossimi e vedo se ci capisco qualcosa.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.