Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it L'avatar di zaltar
    Registrato dal
    Nov 2001
    Messaggi
    796

    Array di puntatori in Turbo C++

    La consegna è:

    "Scrivere un programma che generi e visualizzi 10 stringhe di caratteri aventi le seguenti caratteristiche:

    -ciascuna stringa è composta da un carattere ripetuto un certo numero di volte. Il carattere da utilizzare e il numero di ripetizioni sono inseriti dall'utente.

    Il main gestisce solo un array di puntatori a carattere. La memoria necessaria per contenere le singole stringhe deve essere allocata al momento della dichiarazione della lunghezza delle stesse."

    In pratica il programma deve fare una roba del genere:
    "Inserisci un carattere:" -> L'utente esegue.
    "Quante volte vuoi ripeterlo?" -> L'utente specifica.
    "La stringa è: xxx" -> a seconda dell'inserimento.
    Questo blocco si ripete per ogni elemento dell'array (10 volte).

    Il problema è questo:
    Riesco a sviluppare il programma in modo tale che l'inserimento dell'utente avvenga una volta, facendo poi apparire una stringa ossia trasportando il risultato nel primo elemento dell'array oppure trasportandolo indiscriminatamente in tutti gli elementi ottenendo
    un array avente 10 elementi (o quello che è) tutti uguali alla stringa composta dal carattere x inserito dall'utente ripetuto n volte come specificato dall'utente.
    Purtroppo però impostando un ciclo FOR per ripetere il blocco in modo da avere in ciascun elemento dell'array una stringa diversa va tutto quanto alla malora.

    Aiutatemi!

  2. #2
    Saro` stupido ma non ho capito molto. Cioe`, la traccia l`ho capita ma non i tuoi errori.. Spiega cosa intendi per 'va tutto alla malora'..

    Per ora quindi non ti dico come si fa perche` non servirebbe a nulla. Chiarisci meglio il tuo problema cosi` risolviamo.

    Ciao.

  3. #3
    Utente di HTML.it L'avatar di zaltar
    Registrato dal
    Nov 2001
    Messaggi
    796

    Va tutto alla malora ossia..

    ...dovrebbe funzionare il seguente codice, ma sorpresa sorpresa dà errori assurdi e naturalmente solo in esecuzione:

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


    void main() {
    #define dim 10

    typedef char *puntatore;
    puntatore p, q, vett[dim];
    char a;
    int n, i, cont=0;

    clrscr();
    for (cont=0; cont<dim; cont++) {
    printf("\nInserisci un carattere: ");
    scanf("%c", &a);
    fflush(stdin);
    printf("\nQuante volte vuoi ripeterlo? ");
    scanf("%d", &n);
    fflush(stdin);
    p=malloc((n+1)*sizeof(char));
    q=p;
    for (i=0; i<n; i++) {
    *q=a;
    q=q+1;
    }
    *q='\0';
    strcpy(vett[cont], p);
    printf("\nStringa %d: %s.", cont+1, vett[cont]);
    free(q);
    free(p);
    }

    } /* Fine del programma */


    Un mio amico ha invece sviluppato questo codice, che a sentir lui va che è un piacere, ma devo ancora provarlo:

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

    /*dichiarazioni*/

    /*prototipi*/
    char* inserisci (char,int);
    /*funzioni*/
    char* inserisci (char lettera, int numero)
    {
    int i;
    char *punta;
    punta=malloc((numero+1)*sizeof(char));
    for(i=0; i<numero; i++)
    {
    *(punta+i)=lettera;
    }
    *(punta+numero)='\0';
    return(punta);
    }
    /*principale*/
    void main()
    {
    int num,cont=0;
    char *punt[10],carat;
    clrscr();
    while (cont<10)
    {
    printf("\nInserisci il carattere: ");
    fflush(stdin)
    ;
    scanf("%c",&carat);
    printf("\nInserisci il numero di iterazioni: ");
    scanf("%d", &num);
    punt[cont]=inserisci (carat,num);
    cont++;
    }
    while (cont>0)
    {
    printf("\n inizio la stampa delle stringe");
    printf("\n %s ",(punt[(cont-1)]));
    cont--;
    }
    } /* Fine Programma */

    Francamente a me sembra che facciano esattamente la stessa cosa, solo in maniere diverse, allora come si spiega l'inghippo?

  4. #4
    Utente di HTML.it L'avatar di zaltar
    Registrato dal
    Nov 2001
    Messaggi
    796

    Ulteriori Dettagli

    Ho notato che solitamente vengono date nulle le Stringhe 4 e 10.
    Tutto ciò non ha senso... ho anche provato a sostituire il ciclo for del mio programma con un corrispondente while, in pratica risulta:
    while (cont<dim) {
    ---codice---
    cont++;
    }
    Tanto per essere chiaro, ma sono certo che lo sapevi. :gren:

  5. #5
    Ci sono un paio di errori.

    1) Deallochi due volte la stessa zona di memoria:

    codice:
    p=malloc((n+1)*sizeof(char));
    q=p;
    ...
    free(q);
    free(p);
    2) Copi una stringa su un puntatore per il quale non hai allocato memoria:

    codice:
    strcpy(vett[cont], p);
    'vett' e` un array di puntatori, e se scrivi all`indirizzo di tali puntatori, che in questo caso non sono ne` allocati ne` inizializzati .. beh, dovresti sapere cosa succede, anzi, l`hai visto con i tuoi occhi.

    Soluzioni:

    1) Naturalmente o deallochi 'p' o 'q', ma non entrambi perche` puntano alla stessa zona di memoria.

    2) Se vuoi solo stampare la stringa, allora l`array di puntatori e` superfluo, basta che stampi 'p' invece di 'vett[ cont ]' che non si sa cosa contenga; se invece vuoi mantenere le stringhe nell`array di puntatori, invece di strcpy() devi fare cosi`:

    codice:
    vett[ cont ] = p; /* o q, e` uguale */
    In modo che vett[ cont ] punti alla memoria allocata. In questo caso pero` free() devi chiamarlo alla fine del programma, altrimenti l`uso dell`array e` completamente superfluo (come sopra).

    Per chiarimenti sono qui.

    Ciao.

  6. #6
    Utente di HTML.it L'avatar di zaltar
    Registrato dal
    Nov 2001
    Messaggi
    796

    L'array è obbligatorio...

    ...quindi anche se effettivamente non serve a livello pratico è richiesto dalla consegna, le cui direttive sono insindacabili.

    Per quanto riguarda la dritta n°1 non ero tanto sicuro che funzionasse in questa maniera l'uso dell'Heap. :tongue:
    Avevo il dubbio che assegnando p a q venisse implicitamente allocata di nuovo memoria, comunque ora ho capito.

    La seconda dritta è stata superflua, ma molto apprezzata ugualmente , mi ero già accorto nel frattempo dell'errore fatto con strcpy, comunque non è la stessa cosa assegnare a vett[cont] p o q, infatti p punta ancora all'inizio della stringa, mentre q punta alla fine. Al limite si potrebbe usare q-n.

    Sistemando il programma utilizzando vett[cont]=p piuttosto di strcpy sembra che giri, tuttavia dopo aver stampato a video la decima ed ultima stringa correttamente viene visualizzato anche il messaggio "Null pointer assingnement".
    Forse è questione di deallocazione, provo a spostare free(p) alla fine e ti faccio sapere.
    Ciao.

  7. #7
    Yesse, sul fatto di 'q' dimenticavo che poi lo modificavi.

    Nel ciclo non devi liberare nulla, ne` 'p' ne` tantomeno 'q', mentre alla fine cmq non devi liberare 'p', ma gli elementi di 'vett'.

    L`incomprensione sulla memoria allocata per un puntatore e` dovuta principalmente ad un fatto: bisogna ricordarsi che un puntatore non contiene memoria, quindi assegnazioni di puntatori portano a "memoria condivisa". Stacci attento perche` e` un argomento fonte di numerosi grattacapi, sia in C che in C++. :master: E se ora puo` sembrare una cosa semplice .. in programmi grossi sono problemi che fanno sputare sangue.

    Ciao.

    P.S.: bisogna ammettere che la versione del tuo amico e` piu` elegante, :tongue: a parte un uso abbondante di asterischi.. Inoltre, per copiare n caratteri uguali in un array (stringa in questo caso) puoi usare memset() e mettere il solito '\0' alla fine, cosi` fai pure il fiQo col prof. :adhone:

  8. #8
    Utente di HTML.it L'avatar di zaltar
    Registrato dal
    Nov 2001
    Messaggi
    796

    Problema risolto

    Ieri sera ho finito il programma. :adhone:
    Oltre all'accorgimento di sostituire l'istruzione "strcpy(vett[cont], p)" con "vett[cont]=p" è stato sufficiente deallocare la memoria alla fine del programma anzichè alla fine del ciclo.
    Mi è rimasto un dubbio a livello teorico però...
    ad ogni iterazione del ciclo viene eseguita l'allocazione di memoria per la stringa, questa memoria viene riutilizzata ad ogni iterazione? Sempre la stessa memoria? Allora se non si assegna a qualcosa come vett[cont] l'elaborazione della stringa, tale elaborazione si perde... giusto? Quindi è sufficiente inserire free(p) alla fine del programma e viene deallocata tutta la memoria utilizzata... se ho capito bene. :quipy:
    Ah, senti... com'è la storia di memset? :sexpulp:

  9. #9
    No no .. non e` assolutamente la stessa!

    memset() imposta N bytes ad un certo valore. Quindi invece di:

    codice:
    q=p;
    for (i=0; i<n; i++) {
    *q=a;
    q=q+1;
    }
    *q='\0';
    Potresti fare:

    codice:
    ...
    memset( p, a, n );
    p[ n ] = '\0';
    ...
    E` molto piu` fiQo .. :sexpulp:

    Ciao.

  10. #10
    Utente di HTML.it L'avatar di zaltar
    Registrato dal
    Nov 2001
    Messaggi
    796

    Malloc e Memset

    Effettivamente memset dà un tocco professionale che non guasta affatto, anzi...
    Però il mio dubbio riguarda malloc:
    quando ad ogni iterazione viene eseguita l'istruzione "p=malloc((n+1)*sizeof(char))" si alloca ogni volta nuova memoria oppure è sempre la stessa che una volta allocata viene riutilizzata ad ogni iterazione?
    Da quello che ho capito la seconda opzione è quella corretta, anche perchè altrimenti non si giustifica il fatto che basti free(p) per deallocare tutta la memoria utilizzata.
    Ciao.

    P.S. Aggiungo il codice definitivo del programma così ci capiamo meglio.

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

    void main() {
    typedef char *puntatore; /* Dichiarazione di un tipo puntatore a carattere. */
    puntatore p, q, vett[10]; /* Dichiarazione di 2 puntatori e di 1 vettore di puntatori. */
    char a; /* a deve contenere l'input carattere. */
    int n, i, cont=0; /* n deve contenere il numero di ripetizioni. */
    /* i e cont sono contatori. */
    clrscr(); /* Pulisce lo schermo. */
    while (cont<10) { /* il ciclo scandisce l'intero array. */
    printf("\nInserisci un carattere: ");
    scanf("%c", &a); /* Si inserisce il carattere. */
    fflush(stdin); /* Si ripulisce la liberia Standard Input (Tastiera) */
    printf("\nQuante volte vuoi ripeterlo? ");
    scanf("%d", &n); /* Si specifica quante volte ripetere il carattere. */
    fflush(stdin);
    p=malloc((n+1)*sizeof(char)); /* Si alloca memoria per la stringa da creare */
    /* prevedendo anche lo spazio occupato dal */
    /* terminatore. */
    q=p; /* L'indirizzo del primo carattere della stringa, */
    /* contenuto in p, viene assegnato a q. */
    for (i=0; i<n; i++) { /* Manipolando q, il carattere immesso viene ripetuto */
    *q=a; /* n volte. */
    q=q+1;
    }
    *q='\0'; /* L'ultimo carattere della stringa creata deve */
    /* essere il terminatore "\0". */
    vett[cont]=p; /* L'elemento corrente dell'array punta al principio */
    /* della stringa, infatti p contiene ancora l'indirizzo */
    /* corrispondente. */
    printf("\nStringa %d: %s.", cont+1, vett[cont]); /* Visualizza i risultati. */
    cont++; /* S'incrementa il contatore per scandire l'array */
    }
    free(p); /* Si dealloca la memoria. */

    } /* Fine del programma */

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 © 2024 vBulletin Solutions, Inc. All rights reserved.