Stringhe 2

Indice

Lettura di una riga

#define N 50

int main()
{
    char nome[N];
    printf("Inserisci il tuo nome e il tuo cognome: ");
    /*
    le costanti stdin, stdout, stderr sono definite in stdio.h
    std == standard
    stdin = INPUT
    stout = OUTPUT
    stderr = MESSAGGI ERRORE
    */
    fgets(nome, N, stdin);
}

In questo modo possiamo leggere una intera riga, che può essere composta da più parole, ed inserirla in nome.

La funzione `fgets` riceve come secondo parametro la dimensione massima della stringa. La stringa inserita da fgets non supererà la dimensione passata come parametro, compreso il terminatore '\0'.

Leggendo tutta la riga la funzione include anche l'ultimo carattere inserito '\n' che normalmente vorremmo rimuovere.

Rimozione "a capo"

nome[strcspn(nome, "\n")] = '\0';
printf("Ti chiami -%s-\n", nome);

si veda https://man.openbsd.org/strcspn.3 La soluzione più intuitiva

nome[strlen(nome) - 1] = '\0';

non funziona e porta ad un crash nel caso in cui la stringa sia vuota (ovvero inizi con '\0') perchè strlen mi restituirà 0, quindi andrei ad eseguire nome[-1] = '\0' che è errato

La funzione strcspn se non trova la stringa cercata mi restituisce la posizione del terminatore di stringa, e questo gestisce tutti i casi possibili.

Svuotare buffer

Nel caso si voglia leggere una stringa lunga al masssimo N caratteri all'interno di un loop, se l'utente inserisce una stringa più lunga di N caratteri, i rimanenti rimangono nel buffer e verrebbero letti al loop successivo. Nel seguente esempio se l'utente inserisse una stringa da 30 caratteri ne verrebbero inseriti 19 nella stringa ed 11 verrebbero letti durante la seconda iterazione del ciclo, senza che venga chiesto altro input all'utente.

char s[20];
char ch;

while(1) {
    fgets(s, 20, stdin);

    // svuoto il buffer con un loop che esegue getchar fino a consumare tutti i caratteri inseriti dall'utente
    while ((ch = getchar()) != '\n' && ch != EOF) {
        ;
    }

    // fai qualcosa con la stringa s

}

Validate