 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
fanny Chevalier Guest
|
Posted: Wed Jun 07, 2006 3:29 pm Post subject: lecture d'un fichier |
|
|
Bonjour,
Je dispose d'un fichier contenant des données utilisateur sur chaque ligne.
Pour lire ce fichier, j'ouvre un flux ifstream et récupère chaque champ
selon son type (entier, chaine, ...)
Cependant, certaines lignes ne respectent pas le meme format que les
autres en ce qui concerne les champs.
Autrement dit je dispose de ces deux types de formats :
entier entier caractere entier date(format aaaa-jj-mm)
entier entier caractere date(format aaaa-jj-mm)
Comment puis-je faire pour identifier les lignes qui contiennent
l'entier supplémentaire ?
Je recupère une ligne ainsi (cas de la ligne sans l'entier
supplémentaire) :
ifstream input;
// ouverture fichier
int entier1, entier2, annee, jour, mois;
char caratere, c_temp;
input >> entier1 >> entier2 >> caractere >> annee >> c_temp >> jour >>
c_temp >> mois;
Peut-etre je peux pré-traiter mon fichier en ajoutant en debut de ligne
le nombre de mots qu'elle contient ?
Merci par avance pour vos réponses.
F.C. |
|
| Back to top |
|
 |
Michel Decima Guest
|
Posted: Wed Jun 07, 2006 4:21 pm Post subject: Re: lecture d'un fichier |
|
|
In news:e669pm$4o2$1 (AT) news (DOT) u-bordeaux1.fr,
fanny Chevalier <chevalie (AT) labri (DOT) fr> typed:
| Quote: | Bonjour,
Je dispose d'un fichier contenant des données utilisateur sur chaque
ligne. Pour lire ce fichier, j'ouvre un flux ifstream et récupère
chaque champ selon son type (entier, chaine, ...)
Cependant, certaines lignes ne respectent pas le meme format que les
autres en ce qui concerne les champs.
Autrement dit je dispose de ces deux types de formats :
entier entier caractere entier date(format aaaa-jj-mm)
entier entier caractere date(format aaaa-jj-mm)
Comment puis-je faire pour identifier les lignes qui contiennent
l'entier supplémentaire ?
|
Lire les lignes une par une dans une chaine de caracteres, et ensuite
traiter le contenu de la chaine avec un istringstream
std::ifstream input("data.txt");
std::string line;
while (getline(input, line)) {
std::istringstream parser(line);
parser >> entier1 >> entier2 >> caractere >> annee >> c_temp
| Quote: | jour >> c_temp >> mois;
|
if (parser >> entier_supplementaire) {
...
}
} |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Wed Jun 07, 2006 5:19 pm Post subject: Re: lecture d'un fichier |
|
|
On Wed, 7 Jun 2006 13:21:07 +0200, "Michel Decima"
<michel.decima (AT) francetelecom (DOT) com>:
| Quote: | Lire les lignes une par une dans une chaine de caracteres,
|
Oui.
| Quote: | et ensuite
traiter le contenu de la chaine avec un istringstream
|
Y'a pas à dire, les istream ne m'ont jamais inspiré.
En PHP, j'utiliserais les regex sans hésiter une seconde ; en C++,
j'ai moins ce réflexe, mais ça peut tout de même être une bonne idée. |
|
| Back to top |
|
 |
Michel Decima Guest
|
Posted: Wed Jun 07, 2006 5:51 pm Post subject: Re: lecture d'un fichier |
|
|
In news:40hd82dhu6po8le66hglt2et6iuv8uriu2 (AT) 4ax (DOT) com,
Fabien LE LEZ <gramster (AT) gramster (DOT) com> typed:
| Quote: | On Wed, 7 Jun 2006 13:21:07 +0200, "Michel Decima"
michel.decima (AT) francetelecom (DOT) com>:
Lire les lignes une par une dans une chaine de caracteres,
Oui.
et ensuite
traiter le contenu de la chaine avec un istringstream
Y'a pas à dire, les istream ne m'ont jamais inspiré.
En PHP, j'utiliserais les regex sans hésiter une seconde ; en C++,
j'ai moins ce réflexe, mais ça peut tout de même être une bonne idée.
|
J'ai propose istringstream pour rester standard et ne pas trop 'perturber'
le code original. Apres, c'est la complexite de traitement et la
disponibilite
des outils qui determine le choix (si on va jusqu'a Boost.Spirit, il faut
aussi
ajouter les competences du programmeur...) |
|
| Back to top |
|
 |
fanny Chevalier Guest
|
Posted: Wed Jun 07, 2006 6:04 pm Post subject: Re: lecture d'un fichier |
|
|
Michel Decima wrote:
| Quote: | In news:40hd82dhu6po8le66hglt2et6iuv8uriu2 (AT) 4ax (DOT) com,
Fabien LE LEZ <gramster (AT) gramster (DOT) com> typed:
On Wed, 7 Jun 2006 13:21:07 +0200, "Michel Decima"
michel.decima (AT) francetelecom (DOT) com>:
Lire les lignes une par une dans une chaine de caracteres,
Oui.
et ensuite
traiter le contenu de la chaine avec un istringstream
Y'a pas à dire, les istream ne m'ont jamais inspiré.
En PHP, j'utiliserais les regex sans hésiter une seconde ; en C++,
j'ai moins ce réflexe, mais ça peut tout de même être une bonne idée.
J'ai propose istringstream pour rester standard et ne pas trop 'perturber'
le code original. Apres, c'est la complexite de traitement et la
disponibilite
des outils qui determine le choix (si on va jusqu'a Boost.Spirit, il faut
aussi
ajouter les competences du programmeur...)
|
Merci pour votre aide, mais j'ai opté pour awk qui me rajoute le nombre
de champs de chaque ligne en début de ligne
Ainis, en testant cette valeur, je sais si la ligne comporte l'entier
supplémentaire ou non.
awk '{print NF " " $0}' monFichier > copieFichier
Merci encore |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Jun 07, 2006 7:01 pm Post subject: Re: lecture d'un fichier |
|
|
Fabien LE LEZ wrote:
| Quote: | On Wed, 7 Jun 2006 13:21:07 +0200, "Michel Decima"
michel.decima (AT) francetelecom (DOT) com>:
Lire les lignes une par une dans une chaine de caracteres,
Oui.
et ensuite traiter le contenu de la chaine avec un
istringstream
Y'a pas à dire, les istream ne m'ont jamais inspiré.
|
Tout dépend de ce qu'il y a à faire, mais en général, si le
nombre de champs varie, je crois que tu as raison. On peut le
faire, ici, avec quelque chose du genre :
std::string line ;
while ( std::getline( source, line ) ) {
std::istringstream s( line ) ;
std::vector< std::string >
fields(
(std::istream_iterator< std::string >( s )),
(std::istream_iterator< std::string >()),
std::back_inserter( fields ) ;
switch ( fields.size() ) {
case 4 :
// Quatre champs ...
break ;
case 5 :
// Cinq champs ...
break ;
default :
// Erreur...
break ;
}
}
Mais j'aurais plutôt tendance à utiliser ma classe FieldArray (à
http://kanze.james.neuf.fr, j'espère).
| Quote: | En PHP, j'utiliserais les regex sans hésiter une seconde ; en
C++, j'ai moins ce réflexe, mais ça peut tout de même être une
bonne idée.
|
C'est aussi une solution. Moi-même, j'ai énormement l'habitude
de AWK pour ce genre de chose. Au point que les toutes premières
classes que j'ai écrites en C++, c'était pour faire des choses
qu'on fait naturellement en AWK : String (naturellement, à
l'époque), AssocArray (un tableau haché indexé par des String --
aujourd'hui avec le type d'index comme paramètre du template
aussi), et FieldArray, qui découpe une chaîne en champs, selon
un critère donné. Pendant longtemps, je me servais du modèle
template et l'héritage pour choisir le critère ; aujourd'hui,
c'est le modèle stratégie, mais dans les utilisations typiques,
il n'y a pas de différence. Quelque chose comme ci-dessus
s'écrit :
std::string line ;
while ( std::getline( source, line ) ) {
Gabi::BlankSeparatedFields
fields( line ) ;
// ...
}
La véritable avantage, par rapport à la solution purement
standard ci-dessus, c'est que par la suite, tu peux changer la
définition de ce que c'est qu'un champ simplement en changeant
le type de fields (ou en se servant de la classe de base,
Gabi::FieldArray, et en fournissant toi-même le Splitter (le
délégué qui fait le travail).
Sinon aussi, boost::regex offre pas mal de possibilités.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|