2009-09-13 11 views
9

Sono un principiante alla ricerca di un modo semplice e veloce per analizzare un file di testo in C o C++ (wxWidgets)file di configurazione Parse in C/C++

Il file sarà simile a questa (una categoria principale con "oggetti secondari") che verranno visualizzati in una casella di riepilogo

[CategoryA] 

[SubCat] 

    Str1 = Test 

    Str2 = Description 

[SubCat] [End] 

[SubCat] 

    Str1 = Othertest 
... 

[CategoryA] [End] 

Qualche suggerimento?

+0

Se si scrive il proprio formato che probabilmente devono scrivere il proprio parser. Vedi http://stackoverflow.com/questions/1669/learning-to-write-a-compiler – dmckee

risposta

14

Sembra che tu voglia analizzare un file abbastanza vicino a un file ini.

Esistono almeno alcune librerie di parser INI: minIni, iniParser, libini, ad esempio.

0

Che ne dici di provare a creare un semplice file XML? Ci sono un sacco di librerie che possono aiutarti a leggerlo, e il vantaggio aggiunto è che molti altri programmi/lingue possono leggerlo anche tu.

+0

Ho trovato il sovraccarico di non necessariamente l'analisi, ma il legame dei file xml ai dati non vale la pena per i semplici file di configurazione . Se hai qualcosa che crea i binding, è una questione diversa. –

1

Sembra più semplice implementare il proprio parser piuttosto che provare ad adattare quello esistente che non si conosce.

La struttura sembra - dal tuo esempio - basata su linee. Questo rende l'analisi facile.

Generalmente è consigliabile caricare il file in un albero e quindi girarlo attorno se necessario.

1

Solo su Windows, GetPrivateProfileSection esegue questa operazione. È deprecato a favore del registro ma è ancora qui e funziona ancora.

13

Dovrebbe essere abbastanza semplice scrivere il parser per questo se si utilizzano gli stream. Si può leggere un file usando un std::ifstream:

std::ifstream ifs("filename.ext"); 
if(!ifs.good()) throw my_exceptions("cannot open file"); 
read_file(ifs); 

Poiché sembra orientato alla linea, si dovrebbe quindi leggere prima le linee, e quindi elaborare questi:

void read_file(std::istream& is) 
{ 
    for(;;) { 
    std::string line; 
    std::getline(is, line); 
    if(!is) break; 
    std::istringstream iss(line); 
    // read from iss 
    } 
    if(!is.eof()) throw my_exceptions("error reading file"); 
} 

Per l'analisi vera e propria, si potrebbe 1) prima sbirciare il primo personaggio. Se questo è un [, espellilo dallo stream e usa std::getline(is,identifier,']') per leggere qualsiasi cosa si trovi tra "[" e "]". Se non è un [, utilizzare std::getline(is, key, '=') per leggere il lato sinistro di una coppia chiave-valore, quindi std::getline(is, value) per leggere il lato destro.

Nota: l'ingresso del flusso, sfortunatamente, di solito non è esattamente velocissimo. (Questo non deve essere così, ma in pratica lo è spesso.) Tuttavia, è davvero facile da fare ed è abbastanza facile farlo bene, una volta che conosci pochissimi schemi per lavorare con le sue peculiarità (come if(strm.good()) non è lo stesso di if(strm) e non è l'opposto di if(strm.bad()) e poche altre cose a cui dovrete abituarvi). Per qualcosa di critico dal punto di vista delle prestazioni (har har!) Come la lettura di un file ini dal disco, dovrebbe essere abbastanza veloce in 999.999 su 1.000.000 di casi.

+2

Tre anni dopo, ma una risposta molto informativa. Sono abbastanza nuovo per i flussi di file e hai fornito tutte le informazioni di cui avevo bisogno per creare un parser di base senza librerie aggiuntive (in genere mi piace l'intero argomento getline per ottenere una stringa tra caratteri specifici). Vorrei poter dare più di un +1. –

9

Si consiglia di provare Boost.Program_Options. Tuttavia ha una formattazione leggermente diversa. Più vicino ai file INI. Le sottocategorie sono fatte in questo modo:

[CategoryA] 
Option = Data 

[CategoryB.Subcategory1] 
Option = Data 

[CategoryB.Subcategory2] 
Option = Data 

Inoltre ha alcune altre funzionalità quindi è in realtà molto utile IMO.

0

Se si utilizza wxWidgets, prenderei in considerazione wxFileConfig. Non sto usando wxWidgets, ma la classe sembra supportare categorie con sottocategorie.

3

Provare Configuratore. È una libreria C++ facile da usare e flessibile per l'analisi dei file di configurazione (dal più semplice INI ai file complessi con nesting arbitrario e controllo semantico). Solo testata e multipiattaforma. Utilizza le librerie Boost C++.

See: http://opensource.dshevchenko.biz/configurator