Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219

    [C]Stringhe allocate dinamicamente,problema puts

    Salve a tutti,ho scritto un programma che alloca dinamicamente caratteri per comporre una stringa,pensavo che funzionasse ma delle volte non mi stampa tutta la stringa intera.
    Per esempio delle volte da input digito una stringa e me ne ristampa solo un pezzo,vorrei sapere cosa sto sbagliando.
    Ecco il codice:
    codice:
    int main()
    {
        int i=0;
        char *c,ci;
        c=(char*)malloc(sizeof(char));
        while(ci!=10)
        {
          ci=getchar();
          c[i]=ci;
          i++;
          c=(char*)realloc(c,sizeof(char)*i);
        }
        puts(c);
        return 0;
    }

  2. #2
    Una prima miglioria consiste nel terminare a 0 la stringa, come da convenzione in C.

    Per il C la convenzione (e quello che si aspettano centinaia di funzioni C) è che la stringa di caratteri sia un array di char che termina con un carattere di valore ascii = 0.


    codice:
    int main()
    {
        int i=1;//inizialmente serve almeno un carattere per il terminatore '\0'
        char *c,ci;
        c=(char*)malloc(sizeof(char));
    
        while(ci!=10)
        {
          ci=getchar();
          c[i]=ci;
          i++;
          c=(char*)realloc(c,sizeof(char)*i);
        }
        c[i]='\0'; //inserisco terminatore '\0' 
        puts(c);
        return 0;
    }
    Se vuoi anche raffinare un po il tutto, una seconda miglioria potrebbe consistere nel chiamare realloc non per ogni singolo carattere ma ogni multiplo di N (che so io 512) caratteri, risparmiando un be po di realloc.

    Una terza miglioria sarebbe verificare che malloc e realloc non ritornino NULL, a meno che non sia un esercizio scolastico sarebbe anzi obbligatorio.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    466
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int i=0;
        char *c,ci;
        c=(char*)malloc(sizeof(char));
        while(ci!=10)
        {
          ci=getchar();
          c[i]=ci;
          i++;
          c=(char*)realloc(c, i + 1);
        }
        c[i] == 0;
        puts(c);
        free(c);
        return 0;
    }
    I puntatori si liberano con la free().

  4. #4
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    L' ho trasformata in una funzione per ottenere stringhe senza sapere la dimensione a priori,da stdin o da file:
    codice:
    char* get_string(FILE *fp,char*ptr)
    {
        ptr=(char*)malloc(sizeof(char));
        int i=1;
        char ci;
        fflush(stdin);
        while(ci!=10)
        {
            ci=fgetc(fp);
            if(ci!=10)
              ptr[i-1]=ci;
            else
              ptr[i-1]='\0';
            ptr=(char*)realloc(ptr,(i+1)*sizeof(char));
            i++;
        }
        fflush(stdin);
        return ptr;
    }
    L' intento è di usarla durante un mio programma,dove ad esempio faccio:
    codice:
    char *p;
    p=get_string(stdin,p);
    /*faccio quello che devo fare*/
    free(p);
    La uso al posto di ogni funzione di lettura da input.

    P.S.: ma se io sono sicuro che la memoria verrà allocata,per convenzione devo comunque verificare che non punti a NULL?
    In genere me la realloca sempre,in che casi può fallire?

  5. #5
    Si devi sempre verificare che la memoria sia stata allocata.

    inoltre se realloc restituisce NULL devi ricordarti di liberare la memoria precedentemente allocata.

  6. #6
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Cioè...durante il programma lo interrompo e faccio comparire un messaggio di errore del tipo:memoria piena? Nel mio caso sto facendo un' agenda.

  7. #7
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    bella funzione penso che la userò

    perchè la variabile i deve essere inizializzata a 1 e non a zero?
    codice:
    char* get_string(FILE *fp,char*ptr)
    {
        ptr=(char*)malloc(sizeof(char));
        int i=1;//non va bene a 0?
        char ci;
        fflush(stdin);
        while(ci!=10)
        {
            ci=fgetc(fp);
            if(ci!=10)
              ptr[i-1]=ci;
            else
              ptr[i-1]='\0';
            ptr=(char*)realloc(ptr,(i+1)*sizeof(char));
            i++;
        }
        fflush(stdin);
        return ptr;
    }
    Tecnologia

  8. #8
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    In effetti non avevo calcolato che il terminatore viene aggiunto direttamente,prima lo aggiungevo a fine ciclo.Per cui quell' i puo' diventare 0 oppure si sostituisce (i+1) con i.Prova a vedere se va.

  9. #9
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Dovreste aiutarmi a rendere stabile la funzione get_string,funziona bene sulle letture da stdio,ma da file da problemi.
    Molte volte mi stampa anche un' altra stringa,probabilmente è perchè l' area di memoria di ptr si è espansa e contiene qualche valore casuale,essendo che mi devo fermare a i e non i+1,però non mi include mai il terminatore alla fine,glelo devo dire 2 volte sennò non me lo considera
    Ecco qua cosa sto provando a fare,lettura da file,sostituite quel "prova.txt" con qualsiasi altro file.
    Sto provando ad aprire il file prova.txt che contiene:
    codice:
    5
    78
    89
    90
    hhhhhh
    ghhhhhh
    5
    30
    12
    30
    hhhhhhhhhh
    fhfhhfhf
    Ecco il codice completo:
    codice:
    typedef struct
    {
        int data [4];                                                   /* contenuto: mese,giorno,ora,minuti */
        char *oggetto;
        char *testo;
    }nota;
    
    
    typedef struct
    {
        int par[2];                                                     /* parametri di ricerca di una nota */
        char *parole_chiave;
    }parametri;
    
    
    void nota_write (FILE *fp,nota *ptr);
    nota *nota_read(FILE*fp,nota *ptr);
    int num_line(FILE*fp);
    char* get_string(FILE *fp,char*ptr);
    
    
    int main()
    {
        nota *ptr;
        FILE *fp;
        fp=fopen("prova.txt","r");
        ptr=nota_read(fp,ptr);
        fclose(fp);
        return 0;
    }
    
    nota *nota_read(FILE*fp,nota *ptr)
    {
        ptr=(nota*)malloc(sizeof(nota));
        fscanf(fp,"%d\n%d\n%d\n%d\n",&(*ptr).data[0],&(*ptr).data[1],&(*ptr).data[2],&(*ptr).data[3]);
        (*ptr).oggetto=get_string(fp,(*ptr).oggetto);
        (*ptr).testo=get_string(fp,(*ptr).testo);
        return ptr;
    }
    
    
    void nota_write (FILE *fp,nota *ptr)
    {
        fprintf(fp,"%d\n%d\n%d\n%d\n%s\n%s\n",(*ptr).data[0],(*ptr).data[1],(*ptr).data[2],(*ptr).data[3],(*ptr).oggetto,(*ptr).testo);
    }
    
    int num_line(FILE*fp)
    {
        int c,line=1;
        do
        {
            c = fgetc (fp);
            if (c == '\n')
              line++;
        }while (c != EOF);
        rewind(fp);
        return line;
    }
    
    
    char* get_string(FILE *fp,char*ptr)
    {
        ptr=(char*)malloc(sizeof(char));
        int i=1;
        char ci;
        fflush(stdin);
        while(ci!=10)
        {
            ci=fgetc(fp);
            ptr[i-1]=ci;
            ptr=(char*)realloc(ptr,i*sizeof(char));
            i++;
        }
        ptr[i-2]='\0';
        puts(ptr);
        printf("%d",strlen(ptr));
        fflush(stdin);
        return ptr;
    }
    La get_string funziona male,provate a sostituire,quel puts alla fine della get_string dovrebbe stampare la stringa letta da file,ma mi stampa:
    codice:
    hhhhhh
    6HFI
    3
    Anche se il terminatore glielo ho messo e stramesso (ho anche provato a inserirlo 2 volte).
    Ma niente da fare,ogni volta mi stampa una stringa sporca

  10. #10
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Ecco qua l' utlima "versione" di get_string,legge riga per riga stringhe da stdin o da file (i dati vanno separati da newline).
    codice:
    char* get_string(FILE *fp,char*ptr)
    {
        ptr=(char*)malloc(sizeof(char));
        int i=1;
        char ci;
        if(fp==stdin)
          fflush(fp);
        else
        {
            ci=fgetc(fp);
            if(ci!='\0')
              fseek(fp,-1,SEEK_CUR);
        }
        while(ci!=10)
        {
            ptr=(char*)realloc(ptr,i*sizeof(char));
            ci=fgetc(fp);
            if(ci!=10)
              ptr[i-1]=ci;
            else
              ptr[i-1]='\0';
            i++;
        }
        fflush(stdin);
        return ptr;
    }

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.