Nei titoli e nei testi troverete qualche rimando cinematografico (ebbene si, sono un cinefilo). Se non vi interessano fate finta di non vederli, già che non sono fondamentali per la comprensione dei post...

Di questo blog ho mandato avanti, fino a Settembre 2018, anche una versione in Spagnolo. Potete trovarla su El arte de la programación en C. Buona lettura.

sabato 11 agosto 2012

Oh my, my, strncpy()
come usare la strncpy() in C

In attesa di qualche idea per un post più interessante (e sicuramente più lungo da preparare) mi soffermerò un po' sulla libc e, in particolare, sulla strncpy(), anche se, in realtà, la scelta della funzione è solo un pretesto per dare alcuni suggerimenti di stile, come vedrete (se avete un vuoto di memoria con la libc, clickate sul nome della funzione).

Scrivere in C senza usare direttamente le funzioni di libreria della libc è abbastanza inusuale, ma ci sono dei casi in cui, tra le n-mila funzioni disponibili, manca proprio quella che fa al caso tuo (oppure c'è e non te ne sei accorto). Esempio: mi è successo (caso reale, giuro) di dover leggere linee ripetitive da un file e di dover estrarre solo una parte delle linee per copiarlo in un array, ossia, riassumendo:

- abbiamo n-linee del tipo "...id = 123456;" (il numero cambia a ogni linea e, al posto dei puntini si sono altre informazioni).
- il numero puo`essere più o meno lungo: da 1 a 8 caratteri.
- dobbiamo estrarre il numero, trasformarlo in int e copiarlo in un array di int.

Beh, ovviamente ci sono molti modi per farlo, e uno potrebbe essere di identificare dove comincia il numero e poi usare usare la strncpy()... ma il numero non ha lunghezza fissa: allora bisogna contare la lunghezza e poi usare la strncpy(). Oppure usare la strtok(), e chi più ne ha più ne metta. E il codice diventa sempre più lungo e illeggibile: come sarebbe stato bello risolvere tutto con una semplice chiamata alla strcnpy() !

Ma dico io: chi l'ha detto che se nella libc non c'è la funzione che fa al caso mio non posso riscriverla ? Non necessariamente queste funzioni sono oggetti misteriosi e indescrivibili. Ad esempio la strncpy() è una funzione molto semplice, e riscriverla a proprio uso e consumo è facilissimo:

/* myStrncpy()
 * versione speciale della strncpy() que si ferma al primo ";" e copia max (n-1) char 

 * assicurando un "\0" finale
 */
char *myStrncpy(
    char         *dest,
    const char *src,
    size_t       n)
{
    size_t i;

    // copia src in dest (con stop a <n - 1> chars o al primo "\0" o al primo ";")
    for (i = 0; i < (n - 1) && src[i] != '\0' && src[i] != ';'; i++)
        dest[i] = src[i];

    // fill con "\0" i chars restanti
    for ( ; i < n; i++)
        dest[i] = '\0';

    // ritorna un pointer a dest
    return dest;
}


E così, il flusso principale del programma fa una sola chiamata alla myStrncpy() senza fronzoli strani, salvando eleganza e leggibilità. In un altro file ci mettiamo la myStrncpy(), pronta per essere riutilizzata in altri progetti (farà parte della nostra, personale, libc).

Ciao e al prossimo post.

2 commenti:

  1. Bravo!!! Bel post! E a quando una versione spagnola?

    Angeles

    RispondiElimina
    Risposte
    1. Grazie Angeles per il tuo sostegno. Per la versione Spagnola ci sto già lavorando...

      Elimina