[C] passaggio a funzione di una stringa dinamica

di il
9 risposte

[C] passaggio a funzione di una stringa dinamica

Salve sto riscontrando un problema in cui non vengo a capo, forse inesperienza. Sto scrivendo un programma che crea due insiemi finiti di vocali. il programma funzionava, fino a quando non ho deciso di creare delle funzioni per eliminare la ridondanza all'interno del codice. Utilizzando il debugger vedo come la funzione è corretta ma tornando nel chiamante, in questo caso la main il valore non viene conservato, come se la stringa fosse stata passata per valore e non per indirizzo come desideravo. Vi mostro il codice:

/* definizione funzione */
void inserisci_sequenze(int lunghezza_max_sequenza,
int num_sequenze,
int cont,
int copia_cont,
int i,
int j,
int esito_lettura,
int continua,
char *sequenza);
{
/*richiesta sequenza e validazioni */
do
{
printf("\nInserisci la sequenza %d rispettando la lunghezza scelta: ",
cont);
scanf("%ms",
&sequenza);
esito_lettura = strlen(sequenza);
for (j = 0;
(esito_lettura <= lunghezza_max_sequenza && sequenza[j] != '\0');
j++)
{
if (sequenza[j] == 'a' || sequenza[j] == 'e' || sequenza[j] == 'i' || sequenza[j] == 'o' || sequenza[j] == 'u')
continua = 1;
else
{
continua = 0;
printf("Sequenza di simboli non valida, riprova!");
}
}
}
while (continua == 0);
}

/* nel chiamante l'invocazione..*/
inserisci_sequenze(lunghezza_max_sequenza,
num_sequenze,
cont,
copia_cont,
i,
j,
esito_lettura,
continua,
sequenza);

la stringa sequenza è stata dichiarata inizialmente con char *sequenza ed è stata allocata dinamicamente prima della chiamata a funzione. cosa sto sbagliando esattamente?

9 Risposte

  • Re: [C] passaggio a funzione di una stringa dinamica

    Ciao, dovresti postare il codice utilizzando i tag "code" (pulsante </> dell'editor completo), altrimenti non si capisce nulla.
  • Re: [C] passaggio a funzione di una stringa dinamica

    La riga
    [CODE] scanf("%ms",&sequenza); gli sta dando l'indirizzo del puntatore non del contenuto.
    [CODE] scanf("%s",sequenza);
  • Re: [C] passaggio a funzione di una stringa dinamica

    
    /* definizione della funzione */
    void inserisci_sequenze(int   lunghezza_max_sequenza,
                            			 int   num_sequenze,
                            			 int   cont,
                            			 int   copia_cont,
                        			         int   i,
                       			         int   j,
                           			        int   esito_lettura,
                          			        int   continua,
                            		       char *sequenza);
    
     /*richiesta sequenza e validazioni */
        do
        {
            printf("\nInserisci la sequenza %d rispettando la lunghezza scelta:   ",
                   cont);
            scanf("%ms",
                  sequenza);
            esito_lettura = strlen((char *) sequenza);
            for (j = 0, continua = 0;
                 (esito_lettura <= lunghezza_max_sequenza && sequenza[j] != '\0');
                 j++)
            {
                if (sequenza[j] == 'a' || sequenza[j] == 'e' || sequenza[j] == 'i' || sequenza[j] == 'o' || sequenza[j] == 'u')
                    continua = 1;
                else
                {
                    continua = 0;
                    printf("Sequenza di simboli non valida, riprova!");
                }
            }
        }
        while (continua == 0);
    
    ho provato a togliere la & dalla scanf ma in questo modo mi segnala un warning e non entra nella condizione del for
  • Re: [C] passaggio a funzione di una stringa dinamica

    Vero il for l'avevo cambiato, non ho capito cosa deve fare la funzione, prova a controllare
    [CODE] void inserisci_sequenze(int lunghezza_max_sequenza, int num_sequenze, int cont, int copia_cont, int i, int j, int esito_lettura, int continua, char *sequenza) { /*richiesta sequenza e validazioni */ do { printf("\nInserisci la sequenza %d rispettando la lunghezza scelta: ", cont); scanf("%s", &sequenza); esito_lettura = strlen(sequenza); for (j = 0; (esito_lettura <= lunghezza_max_sequenza && sequenza[j] != '\0'); j++) { if (sequenza[j] == 'a' || sequenza[j] == 'e' || sequenza[j] == 'i' || sequenza[j] == 'o' || sequenza[j] == 'u') continua = 1; else { continua = 0; printf("Sequenza di simboli non valida, riprova!"); } } } while (continua == 0); }
  • Re: [C] passaggio a funzione di una stringa dinamica

    La funzione in poche parole l' ho creata per rendere il codice meno ridondante, dato che lo scopo del programma è quello di creare due linguaggi finiti di simboli (e questi simboli sono delle vocali), dopo aver allocato dinamicamente 2 matrici e char *sequenza che mi serve, come si vede dalla funzione, per effettuare delle validazioni su di essa e se corretta nel main viene memorizzata all'interno della matrice. il codice funziona perche inizialmente era tutto contenuto nella main, quindi l'errore presumo sia nel passaggio della stringa sequenza nella funzione. all' interno durante l'esecuzione il codice viene eseguito correttamente ma nel main il suo valore non ritorna, facendo fallire cosi il resto del programma.
  • Re: [C] passaggio a funzione di una stringa dinamica

    Da come lo descrivi, sembra che tu debba usare un doppio puntatore nel prototipo.
    In ogni caso, la chiamata scanf non va bene.
    Per un buffer di 100, puoi scrivere
    
    scanf("%99s", sequenza);
    
    oppure
    
    fgets(sequenza, 100, stdin);
    
  • Re: [C] passaggio a funzione di una stringa dinamica

    Anche in questo modo il risultato non cambia, e la stringa sequenza torna a 0 nel main. in più mi segnala tanti warning quante sono le volte che utilizzo l array perche in quel modo c'è un puntatore di troppo... ci sarà qualche errore nel passaggio che non capisco...
  • Re: [C] passaggio a funzione di una stringa dinamica

    Allora devi mostrare il programma che hai scritto, se vuoi una mano

    Volendo potresti risolvere così
    
    #include <stdio.h>
    #include <stdlib.h>
    
    char *acquisisci(int max){
        char OK, *ptr, *str = (char *)malloc(max + 2);
        if(max > 0 && str != NULL)
         do{
            printf("Inserisci la stringa di vocali (max %d caratteri): ", max);
            fgets(str, max + 2, stdin);
            for(OK = 1, ptr = str; *ptr && *ptr != '\n'; ptr++)
                if(*ptr != 'A' && *ptr != 'E' && *ptr != 'I' && *ptr != 'O' && *ptr != 'U' 
                    && *ptr != 'a' && *ptr != 'e' && *ptr != 'i' && *ptr != 'o' && *ptr != 'u'){
                    OK = 0;
                    printf("La stringa non va bene!\n");
                    break;
                }
         }while(!OK);
        return str;
    }
    
    int main(){
        char *s = acquisisci(100);
        printf("Stringa acquisita : %s", s);
        return 0;
    }
    
  • Re: [C] passaggio a funzione di una stringa dinamica

    /**********************************************************************/
    /* programma che calcola unione e differenza tra due linguaggi finiti */
    /**********************************************************************/
    
    /*****************************/
    /* inclusione delle librerie */
    /*****************************/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /*****************************************/
    /* definizioni delle costanti simboliche */
    /*****************************************/
    
    #define SIMBOLI 6
    
    /********************************/
    /* dichiarazione delle funzioni */
    /********************************/
    
    void richiedi_allocazione_linguaggio(int  esito_lettura,
                                         int *num_sequenze,
                                         int *lunghezza_max_sequenza);
    void inserisci_sequenze(int   lunghezza_max_sequenza,
                            int   num_sequenze,
                            int   cont,
                            int   copia_cont,
                            int   i,
                            int   j,
                            int   esito_lettura,
                            int   continua,
                            char *sequenza);
    void modifica_allocazione(int  esito_lettura,
                              int *continua);
    
    /******************************/
    /* definizione delle funzioni */
    /******************************/
    
    /* definizione della funzione main */
    int main(void)
    {
        /* dichiarazione delle variabili locali alla funzione */
        char   alfabeto[SIMBOLI] = {"aeiou"},      /* input: alfabeto di simboli da tenere in considerazione */
             **linguaggio_1,                       /* input: primo linguaggio finito di simboli finiti */
             **linguaggio_2,                       /* input: secondo linguaggio finito di simboli finiti */
              *sequenza;                           /* lavoro: contenitore della sequenza finita prima delle validazioni */ 
        int    num_sequenze,                       /* lavoro: numero di sequenze che l'utente vorrà inserire */
               lunghezza_max_sequenza,             /* lavoro: lunghezza di simboli che una sequenza può contenere */
               sequenza_trovata,                   /* lavoro: parametro per la validazione della sequenza */
               esito_lettura = 0,                  /* lavoro: parametro per la validazione degli input */
               cont = 1,                           /* lavoro: contatore */
               copia_cont,                         /* lavoro: copia della variabile cont */
               continua,                           /* lavoro: indice di proseguimento*/
               i,                                  /* lavoro: indice di scorrimento dell'array */
               copia_i,                            /* lavoro: copia della variabile i */
               j;                                  /* lavoro: indice di scorrimento dell'array */
        
        /*stampa dell'alfabeto utilizzabile per la creazione dei linguaggi */
        printf("Utilizza l'alfabeto {%s} per la creazione di 2 linguaggi.\n",
               alfabeto);
    
        /* richiesta all'utente dei dati per l'allocazione del linguaggio */
    
        richiedi_allocazione_linguaggio( esito_lettura,
                                        &num_sequenze,
                                        &lunghezza_max_sequenza);
    
        /* allocazione dinamica delle stringhe */
    
        linguaggio_1 = (char **)calloc(num_sequenze,
                                       sizeof(char*));
        for (i = 0;
             (i < num_sequenze); 
             i++)
            linguaggio_1[i] = (char *)calloc(lunghezza_max_sequenza, 
                                             sizeof(char));
    
        /* inserimento e validazione sull'alfabeto delle sequenze all'interno del linguaggio */
        
        if (num_sequenze > 0)
            printf("Crea il primo linguaggio!\n");
        sequenza = (char *)calloc(lunghezza_max_sequenza,
                                  sizeof(char));
        i = 0;
        do
        {
            for (copia_cont = cont;
                 (i < num_sequenze);
                 i++)
            {
                do
                {
                    /* inserimento delle sequenze con opportune validazioni */
                    
                    inserisci_sequenze(lunghezza_max_sequenza,
                                       num_sequenze,
                                       cont,
                                       copia_cont,
                                       i,
                                       j,
                                       esito_lettura,
                                       continua,
                                       sequenza);    
                
                    /* validazione della sequenza di simboli all'interno dell'insieme e se valida viene memorizzata */
            
                    for (j = 0, sequenza_trovata = 1;
                         (j <= i && sequenza_trovata != 0);
                         j++)
                    {
                        sequenza_trovata = strcmp(sequenza, linguaggio_1[j]);
                        if (sequenza_trovata == 0)
                        {
                            printf("Sequenza di simboli gia' memorizzata all'interno del linguaggio!");
                            printf(" Un insieme non puo' contenere 2 simboli uguali.\n");
                        }
                    }
                }
                while (sequenza_trovata == 0);
                if (sequenza_trovata != 0)
                {
                    strcpy(linguaggio_1[i], sequenza);
                    cont++;
                }
            }
            /* richiesta all'utente per una modifica dell'allocazione */
    
            modifica_allocazione( esito_lettura,
                                 &continua);
    
            if (continua == 1)
            {
                /* richiesta all'utente dei dati per l'allocazione del linguaggio */
                
                richiedi_allocazione_linguaggio( esito_lettura,
                                                &num_sequenze,
                                                &lunghezza_max_sequenza);
                linguaggio_1 = (char **)realloc(linguaggio_1,
                                                num_sequenze * sizeof(char *));
                for (copia_i = 0;
                     (copia_i < num_sequenze); 
                     copia_i++)
                    linguaggio_1[copia_i] = (char *)realloc(linguaggio_1,
                                                            lunghezza_max_sequenza * sizeof(char));
                sequenza = (char *)realloc(sequenza,
                                           lunghezza_max_sequenza * sizeof(char)); 
            }
        }
        while (continua == 1);
    
    void richiedi_allocazione_linguaggio(int  esito_lettura,
                                         int *num_sequenze,
                                         int *lunghezza_max_sequenza)
    {
        /* richiesta all'utente delle dimensioni dei linguaggi */
        do
        {
            printf("Quante sequenze finite di simboli, presi dall'alfabeto, ");
            printf("vuoi memorizzare all'interno del linguaggio? (>=0)  ");
            esito_lettura = scanf("%d",
                                  num_sequenze);
            if (esito_lettura != 1 || *num_sequenze < 0)
                printf("Valore non accettabile!\n");
            while (getchar() != '\n');
        }
        while (esito_lettura != 1 || *num_sequenze < 0);
        if (*num_sequenze == 0)
            *lunghezza_max_sequenza = 0;
        else
        {
            do
            {
                printf("Quale sara' la lunghezza massima della sequenza (>0)  ");
                esito_lettura = scanf("%d",
                                      lunghezza_max_sequenza);
                if (esito_lettura != 1 || *lunghezza_max_sequenza <= 0)
                    printf("Valore non accettabile!\n");
                while (getchar() != '\n');
            }
            while (esito_lettura != 1 || *lunghezza_max_sequenza <= 0);
        }
    }
    
    /* definizione della funzione per inserire nuove sequenze con opportune validazioni */
    void inserisci_sequenze(int   lunghezza_max_sequenza,
                            int   num_sequenze,
                            int   cont,
                            int   copia_cont,
                            int   i,
                            int   j,
                            int   esito_lettura,
                            int   continua,
                            char *sequenza)
    {
        /*richiesta sequenza e validazioni */
        do
        {
            printf("\nInserisci la sequenza %d rispettando la lunghezza scelta:   ",
                   cont);
            scanf("%ms",
                  &sequenza);
            esito_lettura = strlen(sequenza);
            for (j = 0, continua = 0;
                 (esito_lettura <= lunghezza_max_sequenza && sequenza[j] != '\0');
                 j++)
            {
                if (sequenza[j] == 'a' || sequenza[j] == 'e' || sequenza[j] == 'i' || sequenza[j] == 'o' || sequenza[j] == 'u')
                    continua = 1;
                else
                {
                    continua = 0;
                    printf("Sequenza di simboli non valida, riprova!");
                }
            }
        }
        while (continua == 0);
    }
    
    /* definizione della funzione per eventuale modifica dell'allocazione*/
    void modifica_allocazione(int  esito_lettura,
                              int *continua)
    {
        do
        {
            printf("Vuoi memorizzare altre sequenze di simboli all'interno del linguaggio? (1 = si, 0 = no)  ");
            esito_lettura = scanf("%d",
                                  continua);
            if (esito_lettura != 1 || *continua < 0 || *continua > 1)
                printf("Valore non accettabile!");
            while (getchar() != '\n');
        }
        while (esito_lettura != 1 || *continua < 0 || *continua > 1);
    }
    
    questo è l'intero programma, poi il codice viene ripetuto perche creo due linguaggi. Quindi il tutto poi sarà chiuso tra 2 funzioni che inglobano il tutto. ad esempio crea_linguaggio_1 e poi ..._2. spero di venirne a capo. il programma se scritto uguale all'interno della main funziona, è gia stato testato...ma per rendere il codice piu comprensibile è meglio dividerlo in funzioni, cosa che pero non sono riuscito a fare dato che la sequenza scritta nella funzione inserisci sequenza non torna nel chiamante con il valore che invece ho attribuito all'interno della funzione
Devi accedere o registrarti per scrivere nel forum
9 risposte