Devo leggere un file INI classico:
[SEZIONE1]
campo1=valore1
campo2=valore2
[SEZIONE2]
campo1=valore1
lo devo fare con un micro (LM3S1918) in C.
Ho trovato una strada che funziona ma mi sembra macchinosa e abbastanza
brutta.
1) leggo il file riga per riga tramite fgets
2) comparo a manina (if, elseif, elseif) con strcmp l'intera riga e se
corrisponde al nome di una sezione allora imposto la variabile section.
3) se non trovo corrispondenze, spezzo la riga con strtok usando '='
come delimitatore e mi prendo campo e valore.
4) come prima comparo a manina il campo con tutti i possibili nomi.
Quando (e se) lo trovo imposto la variabile item.
5) converto la stringa valore in intero (sono tutti interi per fortuna).
6) passo a una funzione gli interi section, item e value.
7) questa funzione ha due switch annidati che in base alla sezione e al
campo indicati (faccio riferimento a degli enum per comodità di lettura)
assegna il valore alla variabile corretta, ovviamente contenuta in una
struttura, così da avere tutti i parametri assieme.
8) proseguo con la riga successiva...
Il vantaggio di un simile "algoritmo" è che non mi devo preoccupare
dell'ordine delle sezioni e dei campi e quindi è facilmente espandibile
(aggiungendo la nuova voce nell'enum, negli else if e negli switch).
Chiaramente gestisco e segnalo eventuali errori di coerenza.
Come si può fare meglio?



































Libreria Pronta all'uso
Esiste una libreria scritta in ANSI C per il parsing dei file .ini già pronta all'uso.
Si chiama: "iniparser".
E' possibile scaricare i sorgenti al seguente URL: http://ndevilla.free.fr/iniparser/
Re: Leggere file INI con un uC
Mi sembra che questa implementazione sia di difficile manutenzione.
Secondo me dovresti separare la logica di parsing dai dati (nomi sezioni
e campi).
In questo modo la funzione rimane generica e la puoi chiamare quante
volte vuoi, semplificando anche la manutenzione.
Di solito, la API più diffusa che si usa per leggere un file ini è la
seguente:
get_string(file, sezione, chiave, default, buffer);
Tutto il file viene letto alla ricerca della "sezione" contenente la
"chiave". Il risultato viene messo in "buffer" se il campo è trovato,
altrimenti viene usato il "default".
Con solo questa funzione puoi farci tutte le varianti che vuoi, perché
basta che poi chiami la atoi() per ottenere un intero, atof() per i
float e via dicendo.
Per usi normali, il fatto che il file venga riletto tutte le volte non è
un problema. Per normali intendo fino a diverse decine/un centinaio di
valori da leggere.
Un'implementazione come quella che ho indicato sopra è disponibile in
BeRTOS, fatta da un mio collega.
Qui trovi la documentazione:
http://doc.bertos.org/2.5/ini__reader_8h.html
Qui il sorgente:
http://dev.bertos.org/browser/trunk/bertos/mware/ini_reader.c
BeRTOS supporta anche i Luminary.