|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
[C++] Lettura file testo con tag
Ciao ragazzi, volevo chiedervi quale è il modo più intelligente per leggere un file di questo tipo:
Codice:
[name] nome = pippo [surname] cognome = topolino [tag_1] val_1 = a; [tag_2] val_2 = b; .. .. [tag_n] val_n = n I tag potrebbero anche non essere in questo ordine ( almeno quelli senza numero progressivo) Ultima modifica di Unrue : 22-09-2008 alle 16:47. |
![]() |
![]() |
![]() |
#2 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Il prezzo da pagare è nella maggiore quantità, rispetto ad altre soluzioni, di linee di codice da scrivere. Se questo prezzo sei disposto a pagarlo, ti posso fare un esempio. Ciao ![]() |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Be' se le tag iniziano e finiscono con [] e non sono precedute da spazi direi:
![]()
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! Ultima modifica di DanieleC88 : 22-09-2008 alle 21:14. |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Si, basta usare l'operatore >> dal file, che ottiene una parola escludendo spazi e caratteri whitespace in generale... quindi controllare se il primo carattere della stringa ottenuta è [, e se l'ultimo è ].
Se è vero interpreti il testo interno come comando, e le stringhe successive come parametri, o roba del genere ![]() Poi, quando incontri una nuova tag resetti i parametri e rifai da capo. Cmq che ci devi fare con le istruzioni dopo le tags? e come sono strutturate? |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Quote:
![]() Ultima modifica di Unrue : 23-09-2008 alle 11:21. |
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Potresti usare le regex.
Potresti usare automi a stati finiti, implementando la lettura manuale riga per riga. Ma perchè complicarsi la vita e non usare l'XML? Trovi parser già pronti per tutte le esigenze. Se proprio vuoi scriverti un parser a mano devi considerare che potresti trovare anche documenti non validi, esempio valori con i caratteri "riservati" "[" o "]" |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#8 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Secondo me è già un complicarsi la vita usare usare un file in formato XML dovendo stare attenti a rispettare la corretta struttura dei nodi quando se ne crea uno. In fondo si tratta di effettuare il parsing di un semplice file, non dobbiamo certo implementare un compilatore. P.S. E se fosse necessario tenere conto delle prestazioni, implementare a mano la propria libreria per regex non sarebbe una cattiva idea: http://swtch.com/~rsc/regexp/regexp1.html ![]() Ultima modifica di Vincenzo1968 : 23-09-2008 alle 13:44. |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Feb 2006
Messaggi: 1304
|
Quote:
Codice:
string s; file >> s; if( s[0] == '[' && s[s.length()] == ']') { if( s == "[name]") {...} else if( s == "[surname]" ) {...} else if( s == ... ) {...} } Semplicemente, quando vengono lette il codice corrispondente è attivato. |
|
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
1 - Fai a mano, come spiegato sopra. Se non hai bisogno di un gran controllo sugli errori puo' essere una alternativa abbastsanza rapido. 2 - Regex, usando una delle varie librerie presenti, ad esempio quella in boost (http://www.boost.org/doc/libs/1_36_0...tml/index.html) Ti viene abbastanza facile, visto che la regex per l'inizio sezione e' "\[(.*?)\]", mentre quella delle keywords puoi partire da qualcosa tipo "(.*?)=(.*?)" (per poi fare eventualmente tu conversioni e trim): lavori una linea alla volta, se la linea matcha la prima regex cominci una nuova sezione, se matcha la seconda aggiorni la map (o quel che usi) e se entrambe falliscono errore. 3 - Usi un generatore di parser piu' complesso (tipo http://spirit.sourceforge.net) ma non penso ne valga la pena. Il modo piu' semplice e' probabilmente usare uno tra il metodo 1 e 2, leggere riga per riga, se e' del primo tipo inizi la nuova sezione, se del secondo metti in mappa il valore, altrimenti segnali l'errore.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele Ultima modifica di marco.r : 23-09-2008 alle 14:39. Motivo: Ma porc, mi aveva castrato il messaggio :confused: |
|
![]() |
![]() |
![]() |
#11 | ||
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Quote:
![]()
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
||
![]() |
![]() |
![]() |
#12 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
File tags.txt:
Codice:
[name] nome = pippo [surname] cognome = topolino [tag_1] val_1 = a [tag_2] val_2 = b [tag_n] val_n = n Codice:
[name] nome = [surname] cognome = topolino [tag_1] v#al_1 = a [tag_2] val_2 b [8tag_n] = n ![]() Codice:
#include <iostream> using namespace std; #include "SectionsFileAutomaton.h" int main() { string section; string val_name; string val; char *szFileName1 = "C:\\Scaricamenti\\Temp\\tags.txt"; char *szFileName2 = "C:\\Scaricamenti\\Temp\\tags2.txt"; try { Automaton myAutomaton(szFileName1); cout << endl << "File " << szFileName1 << endl; for ( int k = 0; k < myAutomaton.getNumErrors(); k++ ) cout << endl << myAutomaton.m_errors[k] << endl; cout << endl; section = "surname"; val_name = "cognome"; if ( myAutomaton.getValue(section, val_name, val) ) cout << section << " -> " << val_name << " = '" << val << "'" << endl; else cout << section << " -> " << val_name << " non trovato." << endl; cout << endl; section = "prova"; val_name = "niente"; if ( myAutomaton.getValue(section, val_name, val) ) cout << section << " -> " << val_name << " = '" << val << "'" << endl; else cout << section << " -> " << val_name << " non trovato." << endl; cout << endl; myAutomaton.readFile(szFileName2); cout << endl << "File " << szFileName2 << endl; for ( int k = 0; k < myAutomaton.getNumErrors(); k++ ) cout << endl << myAutomaton.m_errors[k] << endl; cout << endl; section = "surname"; val_name = "cognome"; if ( myAutomaton.getValue(section, val_name, val) ) cout << section << " -> " << val_name << " = '" << val << "'" << endl; else cout << section << " -> " << val_name << " non trovato." << endl; cout << endl; } catch(AutomatonException ex) { cout << ex.getMessage() << endl; } return 0; } ![]() |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
E' analogo al formato dei file INI.
http://it.wikipedia.org/wiki/File_INI Sotto Windows ci sono gia' delle API che permettono di leggere agevolmente questi tipi di file, essendo che erano i file di configurazione preferiti sotto Windows 3.11 e 95 Esistono tantissimi wrapper che circondano il cuore di queste API, quindi se la tua implementazione e' sotto Windows puoi cercare con google qualcosa tipo Visual c++ read ini file
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:41.