Sostituto di gets(char *str) del c (versione con while e versione con fgets)


A chi non è mai capitato di voler acquisire una stringa con degli spazzi ed dover utilizzare quindi gets, ma compilando con gcc il suo utilizzo viene segnalato con un errore di warning in quanto viene considerata un’espressione pericolosa?

Oggi vediamo due possibili soluzioni:

1°:

#include<stdio.h>
#define MAX 1000
void acquisisci(char *str);
int main(){
    //dichiarazioni
    char str[MAX];
    
    //acquisizione dati
    printf("inserire la stringa :\n");
    acquisisci(str);
    
    //stampa
    printf("%s\n",str);
}

void acquisisci(char *str){
     //dichiarazioni
     char carattere;
     
     //acquisizione
     while((carattere=getchar())!=10 && carattere!=EOF)
          *(str++) = carattere;
     
     //aggiunta \0
     *str = 0;
}

2°:

#include<stdio.h>
#include<string.h>
#define MAX 1000
void acquisisci(char *str);
int main(){
    //dichiarazioni
    char str[MAX];
    
    //acquisizione dati
    printf("inserire la stringa :\n");
    acquisisci(str);
    
    //stampa
    printf("%s\n",str);
}

void acquisisci(char *str){
     //acquisizione
     fgets(str,MAX,stdin);
     
     //sostituzione del \n con \0;
     str[strlen(str)-1] = 0;
}

Allora in tutte e due gli esempi nel main semplicemente, una volta dichiarata la stringa, l’acquisisco con la mia funzione ed in seguito la stampo.

Mentre nella funzione creata per l’acquisizione (acquisisci(char *str)) semplicemente nel primo esmepio acquisisco carattere per carattere con getchar, mentre nella seconda mi appoggio a fgets, una funzione molto simile a gets.

In particolare nella prima acquisisco un carattere e lo memorizzo nella variabile carattere e continuo fin quando è diverso dal \n(10) e da EOF(end of file – fine del file, ad ogni acquisizione memorizzo il carattere nella stringa incrementando il puntatore ad essa ed infine aggiungo a fine stringa un \0(0).

Nel secondo esempio invece uso l’fgets, che è simile a gets, con l’unica differenza che vuole come parametri anche l’input e la lunghezza del vettore nel quale memorizzare la stringa.
La lunghezza del vettore è MAX, mentre l’input è lo standard input cioè stdin.
Infine presenta un ultimo problema e cioè acquisisce anche il \n alla fine per cui per evitare di averlo nella stringa e quindi avere anche la stringa più lunga di un carattere dobbiamo sostituirlo con \0, per far ciò basta fare str[strlen(str)-1] = 0; dato che il \n è l’ultimo carattere della stringa che si trova quindi alla posizione strlen(str)-1.

È ovvio che il secondo metodo è molto più facile da implementare però è molto meno efficiente dato che serve una stringa più grande di un carattere rispetto a quelli che si usano effettivamente, viene effettuata una chiamata a strlen in più con le relative conseguenze in termini di tempo in caso di stringa molto lunghe, dato che deve scorrere tutta la stringa, quindi in caso di stringhe molto lunghe, ad esempio quando si reindirizza lo standard input con

CC BY-SA 4.0 Sostituto di gets(char *str) del c (versione con while e versione con fgets) by cardinale claudio is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Lascia un commento