Evitare stringhe di formattazione hard-coded

3

In C, ci piace usare #define o const globali per evitare valori e stringhe di codifica hard.

Come possiamo evitare le stringhe hard-coding che devono essere formattate? Si consideri, ad esempio, la costruzione di un percorso file su un bus i2c in linux:

snprintf (dev, size, "/dev/i2c-%u", bus_no)

Non mi piace l'idea di aggiungere un #define I2C_BUS_FMT "/dev/i2c-%u" all'inizio del file (o del file di intestazione), perché quando leggi snprintf (dev, size, I2C_BUS_FMT, bus_no) non puoi vedere quanti e di quale tipo gli specificatori di formato sono ... devi prenderlo per fede che accetta un singolo unsigned int o go check.

Lo stesso problema si applica a const globals.

Come posso evitare le stringhe di formattazione hard-coding senza spostare le informazioni importanti lontano dal luogo in cui è utilizzato?

    
posta Woodrow Barlow 28.07.2016 - 16:53
fonte

2 risposte

7

Non sentirti obbligato a definire ogni costante come simbolo di un preprocessore solo perché qualcuno lo chiama best practice. Ci sono buone ragioni a favore e contro di esso, e il modo migliore per decidere è guardare la situazione e usare il tuo giudizio.

La domanda da porsi è "se definisco questo come simbolo di un preprocessore, dove verrà usato?" Se la risposta è "in una funzione", non c'è motivo per cui non dovrebbe essere cablato nel posto one in cui è usato. Ciò mantiene tutta la conoscenza di come funziona concentrato in un unico posto.

Vado fuori di testa e presumo che nel tuo programma, format_i2c_bus() sia l'API per la formattazione di quei percorsi. Ciò significa che chiunque lo desideri dovrebbe chiamare questa funzione per portare a termine il lavoro. Se si definisce un simbolo per la stringa di formato, lo si rende disponibile per l'uso in qualsiasi funzione altra in grado di visualizzarla. Ciò lascia spazio a qualcuno per fare la propria formattazione, che è l'ultima cosa che vuoi perché non hai più un posto dove apportare modifiche quando la formattazione del percorso cambia.

C'è una vecchia linea guida nella progettazione dell'interfaccia utente che dice che se l'utente non può fare qualcosa, non dovrebbe essere mostrato a loro come opzione. Questo vale anche per il software: se altri moduli non devono fare uso di qualcosa, assicurati che non sia visibile a loro.

    
risposta data 28.07.2016 - 18:13
fonte
0

In questo caso, il codice potrebbe sfruttare la concatenazione letterale stringa.

// Define this someplace else
#define I2C_BUS_PREFIX "/dev/i2c-"
...
// Keep specifier informaiton local
snprintf(dev, size, I2C_BUS_PREFIX "%u", bus_no);

Inoltre, il codice potrebbe usarlo per ridimensionare il buffer

//                                                  1/3 is about log10(2)
#define UNSIGNED_STR_SIZE (sizeof(unsigned)*CHAR_BIT/3 + 2)
...
#define DEV_SIZE     (sizeof(I2C_BUS_PREFIX) + UNSIGNED_STR_SIZE)
char dev[DEV_SIZE];
snprintf(dev, sizeof dev, I2C_BUS_PREFIX "%u", bus_no);
    
risposta data 04.08.2016 - 04:20
fonte

Leggi altre domande sui tag