DOMANDA Linguaggio C Stringhe Con Lunghezza Variabile

Pubblicità

steferro97

Nuovo Utente
Messaggi
131
Reazioni
14
Punteggio
38
Ciao a tutti, avevo una curiosità, esiste in C un modo per leggere una stringa di caratteri qualsiasi, senza prima specificare quanto sia la sua lunghezza massima? Su stack overflow avevo trovato una discussione che parlava di array flessibili, ma non ho capito come si usano e se possono essere utili per quello che voglio fare.
In pratica vorrei scrivere un programma che chiede all'utente di inserire una parola e la memorizza e stampa la lunghezza.
Avevo pensato di farlo anche con una lista a puntatori ma ciò richiederebbe l'inserimento di un carattere alla volta e non è quello che volevo, sapete darmi una mano?
 
In C una stringa è un array di char. Se è una stringa ben codificata, il carattere successivo all'ultimo carattere effettivo è un terminatore che si distingue da tutti gli altri.
Ciò significa che tu puoi recuperare la lunghezza della stringa contando tutti i caratteri non terminatori partendo dal primo, o più semplicemente con la funzione strlen (string.h se non erro).
 
In C una stringa è un array di char. Se è una stringa ben codificata, il carattere successivo all'ultimo carattere effettivo è un terminatore che si distingue da tutti gli altri.
Ciò significa che tu puoi recuperare la lunghezza della stringa contando tutti i caratteri non terminatori partendo dal primo, o più semplicemente con la funzione strlen (string.h se non erro).
Ciao, grazie per la risposta, ma non è quello che intendevo, conosco il carattere terminatore \0 e la funzione strlen() ,ma io chiedevo se fosse possibile leggere una stringa di caratteri senza dover inizializzare un array con una lunghezza massima predefinita. Cioè vorrei che sia il programma a dare la lunghezza all'array DOPO che la parola è stata inserita, a seconda della sua lunghezza.
 
In questo caso allora no, l'unica "soluzione" è scendere a compromessi con l'utente, per esempio imponendo una lunghezza massima per l'input.
 
È possibile leggere una stringa da input di lunghezza ignota allocando memoria dinamicamente.
In particolare è necessario leggere ogni singolo carattere ricevuto da tastiera fino all'inserimento di un carattere che indicherà il termine della stringa (in questo caso il carattere "a capo": '\n'): ad ogni carattere inserito si allocherà nuova memoria per inserire il carattere successivo il terminatore '\0' al termine della stringa.
Per allocare nuova memoria è possibile usare sia una malloc di una stringa di dimensione +1 rispetto alla precedente, copiare il contenuto della prima stringa nella seconda, aggiungere il nuovo carattere e liberare lo spazio della stringa precedente oppure sfruttare la funzione "realloc" che permette di aumentare la dimensione di una parte di memoria già allocata.
Inoltre non è necessario scrivere un carattere alla volta, ma, dato il funzionamento della funzione scanf, è possibile scrivere un'intera stringa seguita da un carattere '\n': chiamando la scanf (impostando la formattazione con "%c") essa leggerà un solo carattere alla volta della stringa precedente per ogni volta che verrà richiamata, senza dover aspettare la pressione del pulsate invio ad ogni richiamo poiché non ha ancora raggiunto il termine di stdin.
Codice:
#include <stdio.h>
#include <stdlib.h>

#define STOP '\n'


int main(int argc, char *argv[]) {
  int i;
  char c,*s;
 
  if(s=malloc(sizeof(char))) {
     scanf("%c",&c);
     for(i=0;c!=STOP;i++) {
       s[i]=c;
       if(!(s=realloc(s,(i+2)*sizeof(char)))) {
           printf("Errore nell\'allocazione della memoria");
           return EXIT_FAILURE;
       }
       scanf("%c",&c);
     }
     s[i]='\0';
   
     /*operazioni su s*/
   
     free(s);
   }
   else {
       printf("Errore nell\'allocazione della memoria");
       return EXIT_FAILURE;
   }
 
  return EXIT_SUCCESS;
}
 
Ultima modifica:
È possibile leggere una stringa da input di lunghezza ignota allocando memoria dinamicamente.
In particolare è necessario leggere ogni singolo carattere ricevuto da tastiera fino all'inserimento di un carattere che indicherà il termine della stringa (in questo caso il carattere "a capo": '\n'): ad ogni carattere inserito si allocherà nuova memoria per inserire il carattere successivo il terminatore '\0' al termine della stringa.
Per allocare nuova memoria è possibile usare sia una malloc di una stringa di dimensione +1 rispetto alla precedente, copiare il contenuto della prima stringa nella seconda, aggiungere il nuovo carattere e liberare lo spazio della stringa precedente oppure sfruttare la funzione "realloc" che permette di aumentare la dimensione di una parte di memoria già allocata.
Inoltre non è necessario scrivere un carattere alla volta, ma, dato il funzionamento della funzione scanf, è possibile scrivere un'intera stringa seguita da un carattere '\n': chiamando la scanf (impostando la formattazione con "%c") essa leggerà un solo carattere alla volta della stringa precedente per ogni volta che verrà richiamata, senza dover aspettare la pressione del pulsate invio ad ogni richiamo poiché non ha ancora raggiunto il termine di stdin.
Codice:
#include <stdio.h>
#include <stdlib.h>

#define STOP '\n'


int main(int argc, char *argv[]) {
  int i;
  char c,*s;
 
  if(s=malloc(sizeof(char))) {
     scanf("%c",&c);
     for(i=0;c!=STOP;i++) {
       s[i]=c;
       if(!(s=realloc(s,(i+1)*sizeof(char)))) {
           printf("Errore nell\'allocazione della memoria");
           return EXIT_FAILURE;
       }
       scanf("%c",&c);
     }
     s[i]='\0';
   
     /*operazioni su s*/
   
     free(s);
   }
   else {
       printf("Errore nell\'allocazione della memoria");
       return EXIT_FAILURE;
   }
 
  return EXIT_SUCCESS;
}

Grazie mille! Era quello che cercavo, grazie per la spiegazione e per aver scritto anche tutto il codice. La funzione "realloc" non l'avevo mai usata ne studiata, domani provo a testare il codice e vedere se riesco a farlo funzionare
 
Piccolo aggiornamento: avevo sbagliato a contare la lunghezza dell'array riallocato. In particolare ho modificato il codice da
Codice:
s=realloc(s,(i+1)*sizeof(char))
a
Codice:
s=realloc(s,(i+2)*sizeof(char))
 
realloc è una funzione che va evitata come la peste, soprattutto dai principianti. È una funzione mal progettata che fa mille cose e fatte male: alloca memoria, libera memoria e ridimensiona blocchi di memoria; il tutto in contrasto col principio secondo cui una funzione deve fare una cosa e farla bene. Inoltre invocare realloc per ogni carattere in input è come cambiare casa ogni volta che si ha un ospite a pranzo. I calcolatori sono soggetti a limiti e pertanto bisogna accettare il fatto che bisogna preallocare la memoria necessaria a leggere una stringa e porre dei limiti all'utente. Usa un array statico di char come buffer e leggi la stringa con fgets.
 
Ultima modifica:
Pubblicità
Pubblicità
Indietro
Top