Lecture dans un fichier texte avec separateur , ??

Lecture dans un fichier texte avec separateur , ?? - C++ - Programmation

Marsh Posté le 03-04-2006 à 20:18:12    

Bonjour !
 
VOila j'aimerai pouvoir gérer un vecteur qui va contenir des objets de type Produit.
voila ce que j'ai dans la classe TabProduits (qui va utiliser le vector)
 
 
Mon fichier .h

Code :
  1. #include <iostream>
  2. #include <vector>
  3. #include "Produit.h"
  4. using namespace std;
  5. class TabProduits {
  6. private :
  7.   /* Declaration d'un vecteur de produits  */
  8.   std:: vector <Produit> str_Vector;
  9. public :
  10.   // Constructeur
  11.   TabProduits();
  12.   //Produit(Produit & );
  13.   // Destructeur
  14.   ~TabProduits();
  15.   // Pour ajouter un produit au vecteur
  16.   void addProduit(Produit& );
  17. };


 
 
et le fichier .cc

Code :
  1. #include "TabProduits.h"
  2. // Constructeur
  3. TabProduits::TabProduits()
  4. {
  5. }
  6. // Destructeur
  7. TabProduits::~TabProduits()
  8. {
  9. }
  10. // Ajouter un produit au vecteur
  11. void TabProduits::addProduit(Produit &p)
  12. {
  13. str_Vector.push_back(p);
  14. }


 
et enfin un bon de l'erreur que j'ai:

Code :
  1. /usr/include/c++/3.3/bits/stl_construct.h: Dans function « void
  2.    std::_Construct(_T1*, const _T2& ) [with _T1 = Produit, _T2 = Produit] »:
  3. /usr/include/c++/3.3/bits/stl_vector.h:599:   instantiated from `void std::vector<_Tp, _Alloc>::push_back(const _Tp& ) [with _Tp = Produit, _Alloc = std::allocator<Produit>]'
  4. TabProduits.cc:16:   instantiated from here
  5. /usr/include/c++/3.3/bits/stl_construct.h:78: error: no matching function for
  6.    call to `Produit::Produit(const Produit& )'
  7. Produit.h:25: error: candidates are: Produit::Produit(Produit& )
  8. Produit.h:24: error:                 Produit::Produit(char*, char*, char*,
  9.    char*, char*, char*, int, int, int, int)
  10. /usr/include/c++/3.3/bits/vector.tcc: Dans member function « void
  11.    std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<_Tp*,
  12.    std::vector<_Tp, _Alloc> >, const _Tp& ) [with _Tp = Produit, _Alloc =
  13.    std::allocator<Produit>] »:
  14. /usr/include/c++/3.3/bits/stl_vector.h:603:   instantiated from `void std::vector<_Tp, _Alloc>::push_back(const _Tp& ) [with _Tp = Produit, _Alloc = std::allocator<Produit>]'
  15. TabProduits.cc:16:   instantiated from here
  16. /usr/include/c++/3.3/bits/vector.tcc:228: error: no matching function for call
  17.    to `Produit::Produit(const Produit& )'
  18. Produit.h:25: error: candidates are: Produit::Produit(Produit& )


 
 
 
EDIT--> J'ai changé le titre du post pour s'adapter au denrier probleme !


Message édité par angel92 le 04-04-2006 à 22:20:44
Reply

Marsh Posté le 03-04-2006 à 20:18:12   

Reply

Marsh Posté le 03-04-2006 à 20:24:37    

Je t'invite à te documenter sur le mot clef const


Message édité par _darkalt3_ le 03-04-2006 à 20:25:16
Reply

Marsh Posté le 03-04-2006 à 20:26:22    

oui justement la est mon probleme !!
Je le met ou le mot clef const ?
 
Parce que j'ai fai un constructeur par recopie pour Produit.
Mias apparament str_Vector.push_back(p) prend un objet constant 'const' en entrée c'est bien ca ?

Reply

Marsh Posté le 03-04-2006 à 20:37:12    

apparemment

Reply

Marsh Posté le 03-04-2006 à 20:38:53    

bon ben j'ai remplacé mon constructeur par recopie, c'est donc devenue (puisque c ca que le vecteur semble vouloir) :
Produit:: Produit(const Produit& )
 
sauf que maintenant j'ai plein d'erreurs du type:
Produit.cc:41: error: passant « const Produit» comme «cet» argument de «char*
   Produit::getNom() » écarte les qualificateurs
 
Qu'est ce que ca veux dire ?


Message édité par angel92 le 03-04-2006 à 20:39:02
Reply

Marsh Posté le 03-04-2006 à 20:44:26    

c'est pas parce que il cherche (const produit& ) que c'est ce qu'il faut lui donner !
 
renseigne toi sur const !

Reply

Marsh Posté le 03-04-2006 à 20:46:38    

bon je me suis renseigné lol, mais c'est pas facile de faire le tri parmis l'enorme masse d'informations qu'on trouve.
 
Mais apparament, dans mon constructeur par recopie il ne lui faut que des truc constants.
Or, dedan, je passe par des accesseurs qui eux ne sont pas déclarés comme constants. Je fais comment pour le faire ?


Message édité par angel92 le 03-04-2006 à 20:47:15
Reply

Marsh Posté le 03-04-2006 à 20:54:26    

voila ce que j'ai dans mon constructeur par recopie et dans la méthode qu'il appel:
 

Code :
  1. Produit::Produit(const Produit &p)
  2.   {
  3.     ref = new char[strlen( p.getRef() )+1];
  4.     strcpy(ref, p.getRef() );
  5.   }
  6.   // Accesseurs
  7.   char* Produit::getRef()
  8.   { return ref; }


Message édité par angel92 le 03-04-2006 à 20:54:44
Reply

Marsh Posté le 03-04-2006 à 21:05:34    

ouf j'ai trouvé ! ! !  
Donc si j'ai bien compri il que toutes les méthodes appelées par le constructeur par recopie soient déclarées constantes, cad qu'elles ne modifient pas l'objet en question. ce qui donne :
 
 
 // Accesseurs
 char* Produit::getRef() const
 { return ref; }

Reply

Marsh Posté le 03-04-2006 à 23:02:16    

c'est quoi ces char * ? dégage ça et utilise std::string. on est pas l'armée du salut, on debug pas le code c++ + char* ici

Reply

Marsh Posté le 03-04-2006 à 23:02:16   

Reply

Marsh Posté le 04-04-2006 à 09:12:36    

Conclusion:
 
- il fallait se documenter attentivement, et c'est à retenir
- les char* en c++ c'est très très mal
 
Bon courage pour la suite.

Reply

Marsh Posté le 04-04-2006 à 19:04:25    

ben disons que c pour mes cours que je fais ca !
Donc je dégage les char* ??
Okay, ca me semble aussi un peu archaique en effet !
 
J'ai d'ailleurs une question.
Est ce que on peu affecter dynamiquement une string ?
Cad:
 
std::string s1 = "toto";
std::string s2;
s2 = s1;
 
Est ce que s2 va prendre comme valeur s1 ?

Reply

Marsh Posté le 04-04-2006 à 20:58:55    

oui, c'est le but
 

Citation :

Donc si j'ai bien compri il que toutes les méthodes appelées par le constructeur par recopie soient déclarées constantes, cad qu'elles ne modifient pas l'objet en question


 
faut pas compliquer les choses, indépendament du constructeur par copie ce qui compte c'est que le parametre est une référence sur un objet constant, tu dois le manipuler comme tel. Sur un objet constant tu ne peux lui appliquer qu'une méthode 'const' (ainsi dans la méthode this est un  pointeur sur un objet constant) sans casser son attribut de constance.
La regle générale c'est que quand tu appel une méthode ou une fonction faut vérifier que les types d'objets que tu lui passes respectent le prototype, et en c++ le typage est assez fort pour faire la diférence entre un objet et un objet de meme type mais constant.

Reply

Marsh Posté le 04-04-2006 à 21:30:43    

bon j'avance j'avance.
J'aurais encore une question.
 
Mes données dont stockées dans un fichier texte, avec sepratateur tabulation de la forme:
 
id  nom  prenom adresse
 
Sauf que quand il y a un espace dans l'adresse ca bug !
 
alors comment faire ?
passer par un séparateur , ou ; ??
et je fai comment pour parcourrir tout le fichier jusqu'a ce qu'il n'y ai plus de ligne ?
 
mais comment est ce que je dois faire ?
 
pour l'instant je fais :
(j'ai mi une boucle qui parcours 10 lignes juste pour les testes, mais jsai pas comment m'arreter proprement)

Code :
  1. ifstream fichier_clients("base_clients.txt" );
  2.   for(int i=0; i<=9; i++)
  3.   {
  4.  // Affection des valeurs dnas le fichier
  5.  fichier_clients>>id_tmp>>nom_tmp>>prenom_tmp>>adresse_tmp;
  6.            }


 
 
 

Reply

Marsh Posté le 04-04-2006 à 22:54:05    

c'est toi qui décide du format du fichier ?

Reply

Marsh Posté le 04-04-2006 à 22:56:26    

Euh oui, c'est moi qui entre toutes les données en fait.
Le format .txt c'est ce qu'il y a de plus simple quoi.

Reply

Marsh Posté le 04-04-2006 à 23:01:54    

ben met un séparateur oui, sinon tu vas galérer pour savoir si ton espace est un séparateur de données ou un simple espace dans une adresse.
A moins que tu ne lises 3 blocs, et que tu considères que le reste est l'adresse, peu importe le nombre d'espaces.

Reply

Marsh Posté le 04-04-2006 à 23:07:49    

Ok, je fais comment ensuite en C++ pour récuperer mes données séparées par des virgules ?
et enfin c'est quoi la condition a mettre dans le while pour que je boucle tant qu'il y a dans lignes dans le fichier ?
 
et re-enfin, (lol et oui j'ai plein de questions jsui un gros noob), il existe une commande en C++ pour vider un fichier .txt de tout son contenu ?


Message édité par angel92 le 04-04-2006 à 23:09:24
Reply

Marsh Posté le 04-04-2006 à 23:23:07    

Citation :

Ok, je fais comment ensuite en C++ pour récuperer mes données séparées par des virgules ?


 
en standard, sur un flux tu dois lires les séparateurs (stream >> an_int >> comma >> ...) sinon avec boost::format ca se parse facilement
 

Citation :

et enfin c'est quoi la condition a mettre dans le while pour que je boucle tant qu'il y a dans lignes dans le fichier ?


 

Code :
  1. std::string line;
  2. while( getline(file, line) ) { ... }


 

Citation :

et re-enfin, (lol et oui j'ai plein de questions jsui un gros noob), il existe une commande en C++ pour vider un fichier .txt de tout son contenu ?


 
tu l'ouvres en ecriture, en c++ ca se fait simplement en instanciant un std::ofstream (raii)


Message édité par skelter le 04-04-2006 à 23:23:51
Reply

Marsh Posté le 04-04-2006 à 23:24:33    

Merci bcp pour tout ces renseignements je vais en faire bon usage :D

Reply

Marsh Posté le 05-04-2006 à 00:10:50    

j'ai mis ca, mais ca marche pas !
 
fichier>>id>> comma >>nom>> comma >>prenom>> comma >>adresse_tmp
 
et meme
fichier>>id>> "," >>nom>> "," >>prenom>> "," >>adresse_tmp
 
que faire?


Message édité par angel92 le 05-04-2006 à 00:12:31
Reply

Marsh Posté le 05-04-2006 à 00:14:53    

montres une ligne du fichier
 
quel est le type de comma ?

Reply

Marsh Posté le 05-04-2006 à 00:24:55    

1,Jean,Moulin,15RueBidon
 
l'erreur que j'ai dans le compilateur est la suivante (enfin c'est qu'un bout):
error: ambiguous overload for 'operator>>'

Reply

Marsh Posté le 05-04-2006 à 00:26:37    

montre plus de code, j'ai paumé ma boule de crystale :)

Reply

Marsh Posté le 05-04-2006 à 00:37:14    

loool ok dsl
 
 

Code :
  1. #include <iostream>
  2. #include <fstream>
  3. .
  4. .
  5. .
  6.          // Déclaration des données temporaires
  7.   ifstream fichier("base.txt" );
  8.   string ligne;
  9.   string id_tmp;
  10.   string nom_tmp;
  11.   string prenom_tmp;
  12.   string adresse_tmp;
  13.   while( getline(fichier_clients, ligne) )
  14.   {
  15.  // Affection des valeurs dnas le fichier
  16.  fichier>>id_tmp>> comma >> nom_tmp>> comma >>prenom_tmp>> comma >>adresse_tmp;
  17.            .
  18.            .
  19.           }


Message édité par angel92 le 05-04-2006 à 00:39:31
Reply

Marsh Posté le 05-04-2006 à 00:46:47    

quand je mets >>comma>> j'ai ca comme erreur dans le copilateur
 
error: `comma' undeclared (first use this function)

Reply

Marsh Posté le 05-04-2006 à 00:52:36    

en francais ca veut dire que comma n'est pas déclaré
 
le plus simple c'est de mettre un caractere blanc (espace par exemple) comme séparateur si tu lis des string, ou alors utilises boost::format

Reply

Marsh Posté le 05-04-2006 à 00:55:48    

ben le probleme vien de Adresse qui sera de la forme 15 Rue Machin, et pas collée comme c'est le cas dans mon fichiers.

Reply

Marsh Posté le 05-04-2006 à 09:39:02    

Ce sont des erreurs de base tout ça, y'a des centaines de pages web qui en traitent.

Reply

Marsh Posté le 06-04-2006 à 00:07:56    

_darkalt3_ a écrit :

Ce sont des erreurs de base tout ça, y'a des centaines de pages web qui en traitent.


comma non déclaré, c'est une erreur de base. Résoudre le problème du délimiteur virgule, ça n'en est pas un. Et au moins, ça mérite une discussion. Je ne connais pas de moyen simple pour faire cela. ça se fait avec iword/pword, et des docs sur ce sujet ne se trouvent pas précisément par centaines ...
Comme l'a dit skelter, le plus simple est probablement d'utiliser Boost.Format.


Message édité par ++fab le 06-04-2006 à 00:18:41
Reply

Marsh Posté le 06-04-2006 à 09:48:42    

Citation :

error: `comma' undeclared (first use this function)


 
Un automate de lecture de fichiers, c'est du niveau première année d'info [:spamafote]
Et des tutoriels sur les stream, y'en a quand meme pas mal.

Reply

Marsh Posté le 06-04-2006 à 09:50:11    

euh boosst::tokenizer devrait permettre de lever quelques difficultés.
Voire boost::spirit si tu es courageux

Reply

Marsh Posté le 06-04-2006 à 23:03:19    

_darkalt3_ a écrit :

Un automate de lecture de fichiers, c'est du niveau première année d'info [:spamafote]


Qu'est-ce qu'on est censé en déduire ?
 

_darkalt3_ a écrit :

Et des tutoriels sur les stream, y'en a quand meme pas mal.


 

Code :
  1. template <class T>
  2. void f( std::istream& is )
  3. {
  4.     T buf;
  5.     is >> setSeparator( "," ); // ou is >> commaSeparator;
  6.     is >> buf;
  7. }


Pour implémenter un manipulateur de ce genre, il n'y a pas foule sur le web, et ça a sa place sur ce forum.
D'ailleurs c'est un sujet que je n'ai jamais vu traité ici.


Message édité par ++fab le 06-04-2006 à 23:04:06
Reply

Marsh Posté le 06-04-2006 à 23:47:05    

en googlant on tombe sur un topic la dessus
 
http://www.thescripts.com/forum/thread137675.html

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed