Insertion/Extraction de données formatées d'un fichier texte

Insertion/Extraction de données formatées d'un fichier texte - C++ - Programmation

Marsh Posté le 27-12-2009 à 21:24:17    

Bonjour tout le monde,
 
J'ai un fichier formaté sous cette forme :
 
Destinataire|Objet|Message
Destinataire|Objet|Message
Destinataire|Objet|Message
 
voici un exemple :
 
x|Test|salut c'est un message
y|Alerte|Fai attention
x|blabla|re !
 
Enfait je developpe une application en c++ (Simulation d'une boite mail) avec laquelle plusieurs utilisateurs, sur un meme pc, peuvent s'echanger des msg : L'utilisateur X ouvre l'application , envoie un message à Y.Quand apres Y ouvre l'application il trouve le message envoyé par X.
 
Je me suis dit d'enregistrer tout les messages dans un fichier texte formaté comme decrit dessus, voici mon code pour l'ecriture :

Code :
  1. #include "EcrireMail.h"
  2. #include <iostream>
  3. #include <fstream>
  4. #include <string>
  5. using namespace std;
  6. void EcrireMail::enregistrer(){
  7. string msg;
  8. string objet;
  9. string des;
  10. getline(cin, objet); // REMARQUEZ CE GETLINE
  11. cout << "Veuillez Indiquez L'objet :" << endl;
  12. getline(cin, objet);
  13. cout << "Veuillez ecrire votre message :" << endl;
  14. getline(cin, msg);
  15. cout << "Destinataire :" << endl;
  16. std::getline(cin, des);
  17. std::cout<< "message destine a :"<<des<<endl;
  18.  cout << "objet : "<<objet<<endl;
  19.  cout <<"message : "<<msg;
  20. ofstream f( "test.txt",ios_base::app);
  21.  if (!f.is_open())
  22.   cout << "Impossible d'ouvrir le fichier en écriture !" << endl;
  23.  else
  24.  {
  25.   f << des << "|" << objet << "|" << msg << endl;
  26.  }
  27.   f.close();
  28. }


 
Pour commencer vous remarquez k'il ya un getline inutilse au debut, et bien j'ai toujours un probleme avec le premier getline ?!
 
Maintenant, kan l'utilisateur X lance l'application, et souhaite voir les messages qu'il a reçu, je dois parcourir le fichier en cherchant les ligne qui commencent par X (Les messages destinés à X)
Or MON PROBLEME et que je ne mairise pas le deplacement du surseur du fichier !!
j'utilise ce code qui me permet de recuperer de prendre le premier mot en considerant le PIPE "|" comme separateur :

Code :
  1. #include "LireMail.h"
  2. #include <iostream>
  3. #include <fstream>
  4. #include <string>
  5. using namespace std;
  6. void LireMail::ouvrir(){
  7.  string utilisateur;
  8.  utilisateur = 'x';
  9.  ifstream f("test.txt" );
  10. ;
  11.  string des;
  12.  string objet;
  13.  string msg;
  14.  //ifstream fichier("test.txt", ios::in);
  15.  if(f)  // si l'ouverture a fonctionné
  16.         {
  17.   while(f.good())
  18.   {
  19.    getline(f,des,'|');
  20.    if(strcmp(des.c_str(),utilisateur.c_str())==0)
  21.     {
  22.      cout << des << endl;
  23.      getline(f,objet,'|');
  24.      cout << objet << endl;
  25.      getline(f,msg,'|');
  26.      cout << msg << endl;
  27.     }
  28.    else
  29.     {
  30.      cout << "Vous n'avez aucune message" << endl;
  31.     }
  32.   }
  33.   f.close();
  34.         }
  35.         else
  36.                 cerr << "Impossible d'ouvrir le fichier !" << endl;
  37. }


Mon probelem c'est que je ne sais comment faire pour placer le curseur à la ligne suivante apres avoir lu le premier mot de chaque ligne (le destinataire) ??
Et je voudrais aussi savoir comment je fais pour extraire juste les messages : je demande à extraire juste le 3eme champs de chaque ligne ??!!

 
Donc comme vous voyez mon probleme est essentiellement le deplacement du curseur !
 
En l'attente de vos reponses veuillez accepter mes salutations distinguées

Reply

Marsh Posté le 27-12-2009 à 21:24:17   

Reply

Marsh Posté le 27-12-2009 à 22:19:06    

Salut
Pour "placer le curseur à la ligne suivante", il suffit de lire la ligne en entier. Rien ne t'empêche ensuite de la découper en cherchant le caractère | et de n'analyser que certaines parties dont tu as besoin.
Une fois que tu as la ligne entière, tu extrais le destinataire et si besoin les autres champs de la même façon.
Regarde du coté de boost::tokenizer
 
Sinon tes messages ne font jamais plusieurs lignes?


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 28-12-2009 à 08:11:05    

Comme préconisé, boost tokenizer,voire boost spirit


Message édité par Joel F le 28-12-2009 à 08:11:59
Reply

Marsh Posté le 28-12-2009 à 11:18:15    

Merci pour vos reponse,
 
Seulement je suis debutant en c++ et quand vous me dites d'utiliser boost tokenizer ça ne m'ai vraiment pas facile, j'ai meme essayer de chercher comment l'utiliser mais les codes m'ont paru un peu difficile et j'ai rien compris !
 
Mais comme vous l'avez remarqué dans mon code, j'arrive facilement à extraire le premier champ (destinataire) avec la fonction getline(fichier, chaine, separateur) seulement mon probleme c'est que apres avoir fait ça, je voudrais faire de meme pour la ligne qui suit ! je ne sais pas comment faire pour placer le curseur au debut la ligne suivante apres cette operation !!
 
et pour ptitchep : Tu m'a demandé si mon msg pouvait s'etaler sur plusieur ligne : Et ben oui !! c'etais un autre probleme probleme que j'avais ignoré pour l'instant, mais j'aimerai bien lui trouver une solution !! parceque comme vous le savez le message peut comntenir aussi des retour à la ligne et tout  
1- Je ne sais pas si l'idée d'utiliser le pipe '|' comme separateur restera adequate dans ce cas ?!
2- je ne sais comment faire pour permettre à l'utilisateur de faire des retour à la ligne puisque la touche entrée passe à l'etape suivante dans le code !!
 
En l'attente de vos reponses, veuillez accecpter mes salytations distinguées.

Reply

Marsh Posté le 28-12-2009 à 12:22:33    

si tu ne veux pas utiliser boost, qui est tres pratique, la reponse ta ete fourni:
fais un getline sur la ligne entiere pas jusqu'au premier separateur, et ensuite dans la chaine recupere tu decoupe tes champs.
 
avec boost tokenizer tu pourrai recuperer un truc ca assez facilement:
destinataire,objet,"mon super message\necrit sur 2 lignes";
 
par exemple...
 
 
et je suis une quiche en code hein. ca fais 8 mois que j'ai pas fais de c++

Reply

Marsh Posté le 28-12-2009 à 12:35:26    

Apprendre a utiliser des lib. Externes c'est le b.a ba. ...

Reply

Marsh Posté le 28-12-2009 à 14:37:40    

trouvé à l'arrache sur google (je n'ai pas de code à moi sous la main, ni de souvenirs car ça fait un bail que je n'ai pas utilisé ça):

Code :
  1. int main(int argc, char** argv)
  2. {
  3.    std::string text = "token, test   string";
  4.    char_separator<char> sep(", " );
  5.    boost::tokenizer<char_separator<char>> tokens(text, sep);
  6.    for ( boost::tokenizer<char_separator<char>>::iterator it = tokens.begin();
  7.          it != tokens.end();
  8.          ++it)
  9.    {
  10.       std::cout << *it << "." << std::endl;
  11.    }
  12. }

A tester, ou valider par Joel F


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 28-12-2009 à 21:24:33    

-pour separer ne pas utiliser | (use tabs or ',' cest mieux)
 
boost::tokenizer est tres puissant!
 
- il faut avoir un header (dest, src, obj)
puis le corp du message dan un seul bloc
 
boost::tokenizer  va etre utiliser pour collecter
les membre du header. ;)  

Reply

Marsh Posté le 28-12-2009 à 21:35:26    

ptitchep a écrit :

A tester, ou valider par Joel F


 
je valide ;)

Reply

Marsh Posté le 29-12-2009 à 11:28:03    

Merci pour vos réponse,  
J'ai essayé de télécharger les librairies BOOST, mais c'était ni facile à trouver ni à installer !
En plus je ne vois pas l'intérêt d'installer tout ça (500 Mb ou plus) juste pour séparer une chaine de caractère !
Et comme je vous ai dit, j'arrive à recupere les premier champs avec getline je preferai reduire mon probleme au deplacement du curseur et non pas à la separation de la chaine !
Comme j'ai expliqué, je voudrais savoir comment passer à la ligne suivante apres avoir lu le premier champs en utilisant getline(fichier,chaine,separateur) ?
Moi j'ai pensé une getline(fichier,chaine) dans le vide comme ça juste pour lire le reste de la chaine et passer à laligne suivante, seulement je me suis dit que c'est peut etre inadequat de fire des getline comme ça dans le vide juste pour se deplacer !!
 
Et pour mon message, je voudrais savoir comment je peut permetre à l'utilisateur de taper plusieur lignes avec des retour à la lignes et tout ??!! est ce que dans ce cas le pipe '|'  reste un bon separateur (j'ai pensé que c'est presque le seul caractere que l'utilisateur ne tapera pas dans son message !)
 

Reply

Marsh Posté le 29-12-2009 à 11:28:03   

Reply

Marsh Posté le 29-12-2009 à 11:43:48    

M3HD1 a écrit :

J'ai essayé de télécharger les librairies BOOST, mais c'était ni facile à trouver ni à installer !

Tout à fait d'accord

M3HD1 a écrit :

En plus je ne vois pas l'intérêt d'installer tout ça (500 Mb ou plus) juste pour séparer une chaine de caractère !

Parce que boost c'est LA bibliothèque à installer, si tu fais du C++, tu en auras besoin.

M3HD1 a écrit :

Et comme je vous ai dit, j'arrive à recupere les premier champs avec getline je preferai reduire mon probleme au deplacement du curseur et non pas à la separation de la chaine !

Je ne pense pas que ce soit une réduction du problème.

M3HD1 a écrit :

Comme j'ai expliqué, je voudrais savoir comment passer à la ligne suivante apres avoir lu le premier champs en utilisant getline(fichier,chaine,separateur) ?
Moi j'ai pensé une getline(fichier,chaine) dans le vide comme ça juste pour lire le reste de la chaine et passer à laligne suivante, seulement je me suis dit que c'est peut etre inadequat de fire des getline comme ça dans le vide juste pour se deplacer !!

Cela me semble aussi simple que moche (surtout si pour une raison ou une autre tu as un message vide, tu vas perdre une ligne) mais si tu ne veux pas utiliser boost...[:spamafote]

M3HD1 a écrit :

Et pour mon message, je voudrais savoir comment je peut permetre à l'utilisateur de taper plusieur lignes avec des retour à la lignes et tout ??!! est ce que dans ce cas le pipe '|'  reste un bon separateur (j'ai pensé que c'est presque le seul caractere que l'utilisateur ne tapera pas dans son message !)

Tant que ni le destinataire ni l'objet ne peuvent pas contenir |, oui. Pour le retour à la ligne peut-etre que tu pourrais par exemple ajouter \ à la fin de la ligne pour indiquer que le message continu. Dans ce cas tu fais des getline tant que le dernier caractère = '\'. Ce serait simple à mettre en place. Ou alors changer ton fichier en Dest|objet|nbLignes|msg. Voilà pour les solutions simples qui me viennent à l'esprit.


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 29-12-2009 à 12:06:21    

M3HD1 a écrit :

Merci pour vos réponse,  
J'ai essayé de télécharger les librairies BOOST, mais c'était ni facile à trouver ni à installer !


 
 :heink:  
 
www.boost.org  t'as un lien DOWNLOAD cash sur la premiere page.
 
Ensuite, l'install se resume à ./bootstrap && sudo ./bjam install
 
Et oui, les 500Mo sont necessaires, c'ets LA bibliothèque à avoir et savoir utiliser
 

Reply

Marsh Posté le 29-12-2009 à 13:19:30    

C'est surtout la doc qui n'est pas très intuitive je trouve. A l'époque de ma première install tout ce que j'avais trouvé c'était quelque chose du genre "Boost ne se compile pas sauf quelques parties" puis la liste des choses à compiler sans aucune explication. Quand on l'a fait une fois par contre ça roule


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 29-12-2009 à 13:39:38    

Re
 
Bon alors je suis entrain d'installer BOOST et je vais utiliser le tokenizer comme vous m'avez conseiller (Merci)
 
Sinon "ptichep" j'ai pas vraiment saisi ta solution pour les retours à la ligne dans les messages, moi mon probleme c'est quand l'utilisateur est en mode console, Je lui affiche : Tapez Votre Message.
Je voudrais savoir qsque l'utilisateur doit taper pour retourner à la ligne, en sachant qu'en tapant sur entré on passe à l'etape suivante qui sera l'affichage du message : Taper le nom du destinataire.
 
??!!
 
Pire encore, comment enregistrer ces plusieurs dans les fichiers pour pouvoir les extraire apres correctement ?!
 
Et en ce qui concerne la librairei boost, je dois faire un include ou un truc du genre pour que ça fonctionne ?!
 
 
Merci les gars pour votre aide ! desolé si je vous embete avec mes questions, mais je tiens vraiment à apprendre le C++ et faire un bon mini projet.
 
En l'attente de vos reponses, veuillez accepeter mes salutations distinguées.

Reply

Marsh Posté le 29-12-2009 à 13:42:44    

ptitchep a écrit :

C'est surtout la doc qui n'est pas très intuitive je trouve. A l'époque de ma première install tout ce que j'avais trouvé c'était quelque chose du genre "Boost ne se compile pas sauf quelques parties" puis la liste des choses à compiler sans aucune explication. Quand on l'a fait une fois par contre ça roule


 
La doc d'install a été refaite recemment (1.39 de tete), le Getting Started est qd meme suivable

Reply

Marsh Posté le 29-12-2009 à 16:56:56    


 
Voici mon code :
 

Code :
  1. string utilisateur;
  2.  utilisateur = 'x';
  3.  ifstream f("test.txt" );
  4.  string ligne;
  5.  string des;
  6.  string objet;
  7.  string msg;
  8.  if(f)  // si l'ouverture a fonctionné
  9.         {
  10.   while(f.good())
  11.   {
  12.    getline(f,ligne);
  13.    //cout << des << endl;
  14.        //std::string str = "Hello|world||foobaryowbaz|";
  15.     typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
  16.     boost::char_separator<char> sep("|" );
  17.     tokenizer tokens(ligne, sep);
  18.     tokenizer::iterator tok_iter = tokens.begin();
  19.     if(strcmp((*tok_iter).c_str(),utilisateur.c_str())==0) // VOICI MON PROBLEME !!!!!!!!
  20.     {
  21.      for (tok_iter;tok_iter != tokens.end(); tok_iter++)
  22.      {
  23.        //std::cout << "<" << tok_iter << "> ";
  24.        std::cout << "<" << *tok_iter << "> ";
  25.        std::cout << "\n";
  26.      }
  27.     }
  28.   }
  29.   f.close();
  30.         }
  31.         else
  32.                 cerr << "Impossible d'ouvrir le fichier !" << endl;
  33. }


 
 
Quand j'ai utiliser strcmp , je me suis dit de convertir le *tok_iter en const char * ?! C'est ça ?
 
Mais ça me genere une grosse erreur !! genre fenetre d'avertissement : Just In Time Debugger ....
 


Message édité par M3HD1 le 29-12-2009 à 17:50:44
Reply

Marsh Posté le 29-12-2009 à 19:12:59    

je pense que tokenizer renvoit des std::string et que dnc la comparaison se fait avec == ou !=

Reply

Marsh Posté le 29-12-2009 à 22:08:49    

ne pensez pas que c'est trop 500mb  
(il ya un film dedans ??) :heink:  
elle n'est pas avec linux !
 
utilisateur peut ecrire tout ! meme ca ╝
 
[il faut entrer bien pour sortir vite]: :lol:  
peut etre pas la peine de decomposer la ligne
jai dit qu'il faut un header et un body
(markup , comme xml, html.... et en plein text)
 
<head>
 dest  1 ligne
 src    2 ligne
 obj    3 ligne
</head>
<msg>
....
...
...
</msg>
 
/----------------------------------------------
ca c'est quelque pseudo-code , (ne me dit pas    performance)
 
 
EnterBloc("<xxx>" ){
  // cmp lines until "<xxx>"
}
ExitBloc("</xxx>" ){
 // cmp lines until "</xxx>"
 
}
equalstr(ba1 , ba2){
  if(stricmp(ba1, ba2) == 0){
     return true;
  }
  return false;
}
 
getlinefromfile(filestrm,ba){
    getline(filestrm,ba){
    }  
}
 
getline(strm,ba){
}
 
ecrireline(ba , strm)
 strm << ba << endl;
end  
 
// OK ca c'est m'on avis , et vous ete libre!  :)

Reply

Marsh Posté le 29-12-2009 à 22:37:34    

J'ai aussi essayé :

Code :
  1. if((*tok_iter)==utilisateur)


 
Mais ça me genere toujours une grosse erreur !!
 
This application has requested the runtime to ..... ----> dans une fenetre avec : abandonner, recommencer, ignorer
 
Et puis : Assertion failed : valid_, file c:\program files\bosst....\...\token_iterator.hpp  
 
!!!!!!!   :ouch:     !!!!!!!

Reply

Marsh Posté le 29-12-2009 à 22:45:04    

Salut,
 
_tomjost : J'aime bien ton idée, ça parait logique et surtout beaucoup plus facile que la mienne (Faut dire que je reconnais que mon application ets plutot facile !) Seulement je vais devoir tout recommencer ! Et je suis un peu hesitant de peur de retomber dans le meme probleme apres !  
 
J'attend vos encouragement  :??:

Reply

Marsh Posté le 29-12-2009 à 22:46:44    

Re __tomjost,
Tu voulais dire que je formate mon fichier comme du XML mais en Texte ?!
9a parait faisable, mais tu pense que ça sera aprecié ?
 
Merci pour tes idées

Reply

Marsh Posté le 29-12-2009 à 23:03:59    

:sol:  c'est plus international (autre que le binaire)  
et vous aller affronter moin de problem , ton premier code va pas aller trop
loin car il ya d'autre problem que tu va rencontrer apres
meme si elle ne sont pas visible maintenant , Ok , encore tu es
libre ; on peut attendre l'avis de quelqun d'autre ;
(valider la direction ou non). :)  

Reply

Marsh Posté le 30-12-2009 à 07:59:34    

A mon avis aussi le fichier xml est une bonne solution qui te permet de gérer des messages complexes. Il y a des bibliothèques pour lire simplement les fichiers ;)


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 30-12-2009 à 09:04:46    

Bonjour,
Je dois alors utiliser une bib quipermet de lire un fichier XML comme TinyXML
Ou bien je fait une structure XML avec un fichier texte ?

Reply

Marsh Posté le 30-12-2009 à 11:12:27    

un fichier XML c'est du texte non?
Par contre je ne peux pas te conseiller pour le choix de la bibliothèque désolé.


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 30-12-2009 à 12:02:02    

Je voulais dire je lit le fichier avc des fonction normale de getline, tokenizer ...
Ou bien je cherche une bonne bib pour le XML avec c++ ??

Reply

Marsh Posté le 30-12-2009 à 12:51:57    

tinyxml

Reply

Marsh Posté le 30-12-2009 à 13:49:33    

Bon alors je vais me documenter sur TinyXML il parait que c'est la plus facile !
Sinon, je voudrais savoir comment faire avec la console pour que l'uilisateur puisse faire des retour à la ligne sachant que la touche entré ne permet pas de le faire puisqu'elle sert à passer à l'etapesuivante dans le code ?!

Reply

Marsh Posté le 30-12-2009 à 16:41:45    

ben une doc bien utile, la page concernant getline
regarde le param delim, ca repond a ton besoin

Reply

Marsh Posté le 30-12-2009 à 19:39:06    

Merci DUCON3D,
J'ai deja utilisé un separateur avec getline, seulement je voulais recuperer le premier champs d'une phrase dont les champs sont separés par des | et je savais pas comment passer à la ligne suivante apres avoir recuperer un champs d'une phrase.
 
Alors qlqu'un pourrait me proposer une idée pour perrmettre à l'utilisateur d'ecrire tout un texte(avec des retour à la lignes..) avec le mode console ?

Reply

Marsh Posté le 30-12-2009 à 20:42:15    

---------------------------
 console   :sleep:  
---------------------------
*bonjour ecrit un msg puis appuyer CTRL+S to send!
* baaaaaaaa
  baaaaaaaa
  CTRL+S
 
*merci!
---------------------------

Reply

Marsh Posté le 30-12-2009 à 21:26:52    

Merci tomjost,
Mais comment je fai pour que la touche entré ne valide pas et que la touche CTRL+S execute la suite du code ?!
 
Desolé si ma question te parait un peu bete !

Reply

Marsh Posté le 30-12-2009 à 23:16:30    

M3HD1 a écrit :

Merci tomjost,
Mais comment je fai pour que la touche entré ne valide pas et que la touche CTRL+S execute la suite du code ?!
 
Desolé si ma question te parait un peu bete !


 
Non pas bete , mais peut etre CTRL+S ....
 
 
Mais voici CTRL+E (Envoyer et non Send) :D  
ca functionnne :
/*
heeeeeeeeeeeeeeeeee
fffffffffffffffffffff
fffffffffffffffffffff
^E
*/
 
// le '\05' represente CTRL+E dans la console ,
// et replace Enter comme un delimiteur.
 
int main(int argc, char* argv[])
{
 char buf[128];
 istream& stm = cin.getline(buf, 128, '\05');
 
 cout << buf;
 return 0;
}  ;)  

Reply

Marsh Posté le 31-12-2009 à 01:00:25    

en gros c'est ce que je disais en 2 lignes, ca demandais plus d'extrapolation certes  :pt1cable:  
 
tu peux aussi ajouter une limite en nombre de caractere, c'est utile comme parametre

Reply

Marsh Posté le 31-12-2009 à 17:38:26    

Merci
 
Et pour la comparaison de Tokenizer ieterator avec une chaine de caractere ??!! Il ya tjr une erreur apres l'execution(qui est juste!!) de Just In Time Debugger ....
voila le code :
string MACHAINE;
tokenizer::iterator tok_iter = tokens.begin();
    strcmp((*tok_iter).c_str(),MACHAINE)
et ça :
 
if(*tok_iter==MACHAINE)
 
Toute les deux me generent la meme erreur !!

Reply

Marsh Posté le 31-12-2009 à 19:15:32    

strcmp(const char* , const char*)
 
1/ strcmp((const char*)((*tok_iter).c_str()), MACHAINE)
2/ if((*tok_iter).c_str() == MACHAINE)  
 
ca s'appelle casting. , il faut convertir au meme type.

Reply

Marsh Posté le 31-12-2009 à 19:25:51    

Sorry! :(  
 
strcmp((const char*)((*tok_iter).c_str()), (const char*)MACHAINE)
 
MACHAINE : MaChaine , c'est mieux

Reply

Marsh Posté le 02-01-2010 à 21:40:47    

Merci tomjost mais ya toujours cette erreur !!  
 
Il a une fenetre dans laquelle il y a les bouton : Recommencer/Abandonner/Ignorer
 
Et puis l'execution (Sans erreur !) et a la fin ce message :
 
Assertion failed : valid_, file c/\program files..../boost/token_iterator.hpp line 56  
This application has requested the runtime to terminate it ...

Reply

Marsh Posté le 18-01-2010 à 20:38:25    

M3HD1 a écrit :

Merci tomjost mais ya toujours cette erreur !!  
 
Il a une fenetre dans laquelle il y a les bouton : Recommencer/Abandonner/Ignorer
 
Et puis l'execution (Sans erreur !) et a la fin ce message :
 
Assertion failed : valid_, file c/\program files..../boost/token_iterator.hpp line 56  
This application has requested the runtime to terminate it ...


assertion failed :  
quelque faute (dangereux!) qui ne doit pas passer en release
(vous etes en debug-mode)
on doit assurer que tu ecrit pas hors limit du memoire
par exemple ... et cette assuration a fallu (voir line 56)
 
[poste s'il ya des problemes ,  mais peut etre je ne peut plus repondre]
  :hello:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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