IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Récuperer données d'un fichier


Sujet :

C++

  1. #1
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut Récuperer données d'un fichier
    Bonjour,

    J'essaye de créer un loader de fichier 3D OBJ. Le format est un format texte qui se présente comme ceci pour un simple cube :

    o 1

    # Vertex list

    v -0.539683 0 0.031746
    v 0.52381 0 0.031746
    v 0.52381 0 -1
    v -0.539683 0 -1
    v -0.539683 0 0.031746
    v 0.52381 0 0.031746
    v 0.52381 0 -1
    v -0.539683 0 -1
    v -0.539683 0.899706 0.031746
    v 0.52381 0.899706 0.031746
    v 0.52381 0.899706 -1
    v -0.539683 0.899706 -1

    # Face list

    g
    usemtl Default
    f 2 3 4 1
    g
    f 8 7 6 5
    g
    f 6 10 9 5
    g
    f 7 11 10 6
    g
    f 12 11 7 8
    g
    f 9 12 8 5
    g
    f 10 11 12 9

    # End
    Chaque vertice est définit par v suivi d'un espace et des trois couplets x, y, z, tandis que les faces par f.

    Je voudrais simplement récupérer ces valeurs, mais j'ai beaucoup de mal à comprendre comment ça fonctionne (ça a toujours été mon point faible, les fichiers ).

    J'ai pour ceci dans ma classe :

    CVector * vertices;
    stPolygon * polyList;

    Je pense qu'il est mieux d'utiliser des vector mais obn, on verra ça après. Donc j'ai réussi à récupérer le nombre de faces et le nombres de vertices avec ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    std::ostringstream buffer;
       std::string strBuffer;
       buffer << fichier.rdbuf();
       strBuffer = buffer.str ();
       std::string ligne;
     
       for (unsigned int i = 0 ; i < strBuffer.size () - 1; ++i)
       {
          if (strBuffer [i] == 'v' && strBuffer [i+1] == ' ')
             totalVertices++;
     
          if (strBuffer [i] == 'f' && strBuffer [i+1] == ' ')
             totalFaces++;
       }
    Toutefois, je ne sais pas du tout comment faire pour récuperer les autres valeurs que je veux...

    Par exemple je voudrais faire ça :
    if (strBuffer [i] == 'v' && strBuffer [i+1] == ' ')
    {
    GLfloat x, y, z;
    x = la valeur d'x;
    y = la valeur d'y;
    z = la valeur d'z;

    vertices = new CVector (x, y, z);
    totalVertices++;
    }

    J'avias pensé à un getline pour récuperer touta la ligne (je fais le if, si c'est bon, je récupère toute la ligne avec getline, et je récupère les valeurs), mais je suis incapable de le faire .

    Merci.

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Le plus facile, c'est d'utiliser un ifstream, qui est prévu pour...

    Les ifstream sont déclarés dans l'entete <fstream> et sont à utiliser sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::ifstream fichier(nom_fichier)
    ou nom fichier est une chaine C-like (tableau de caractères terminé par zero). Ce qui pourrait très bien prendre la forme (chaine étant une chaine de type std::string) de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::ifstream fichier(chaine.c_str());
    Du fait de la structure précise du fichier, le plus facile, apres vérification de l'ouverture du fichier, est sans doute de lire "chaine de caractère par chaine de caractère" et de convertir en fonction de ce qui est trouvé sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    std::string lecture;
    while(!fichier.eof())//une boucle pour lire tout le fichier
    {
        //on lit une premiere chaine de caractères
        //ca ne devrait pas arriver, mais on veille à ce que la lecture se passe
        // bien
        if(!(fichier>>chaine))
            throw std::runtime_error("erreur de lecture");
        //une suite de test pour savoir à quoi on a affaire
        if(chaine=="#") //ligne de commentaire, on se contente de lire le reste
                        //de la ligne
            getline(fichier,chaine);
        if(chaine=="v")
        {
            //une ligne pour un vecteur on lit trois coordonnées que l'on converti
            //une solution serait de les introduire dans une std::map<int,Vertice>
            //où int sera le numéro du vertice (auto-incrémenté)
        }
        if(chaine=="usemtl")
        {
            // la chaine qui suit est le nom du matériau à utiliser pour les faces
            //à mettre en relation avec la liste des matériaux utilisables
        }
        if(chaine=="f")
        {
            //ce qui suit est une liste de numéro de vertice, terminée par 
            //la chaine "g"
            //encore une fois, on les lit un par un, puis on converti en entier
            // et ca peut servir comme valeur à chercher comme cle dans
            //la map indiquée plus haut
        }
    }
    La convertion en réel ou en entier se baserait alors sur un ifstringstream et ce qui est indiqué dans la FAQ:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    std::ifstringstream iss(chaine);
    //convertion en entier
    int entier;
    iss>> entier;
    //convertion en réel
    float reel;
    iss>>reel;
    selon le cas
    PS: le code met des apostrophes, mais, normalement ce sont des guillemets qui sont à utiliser comme valeur de test de la chaine
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    J'ai une petite question supplémentaire.

    J'ai une ligne de ce style :

    *MESH_NUMVERTEX 8

    Et je souhaite récupérer le nombre de vertex. En faisant comme tu as dit, j'arrive à récupérer sans problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    while (!fichier.eof())
       {
          fichier >> chaine;
     
          if (chaine == "*MESH_NUMVERTEX") // *MESH_NUMVERTEX nbVertex
          {
             getline (fichier, chaine); // On récupère la ligne
             std::istringstream iss (chaine);
     
             iss >> m_iNumVertices;
          }
          else if (chaine == "*MESH_NUMFACES") // *MESH_NUMFACES nbFaces
          {
             getline (fichier, chaine); // On récupère la ligne
             std::istringstream iss (chaine);
     
             iss >> m_iNumFaces;
          }
       }
    Toutefois le truc que je comprend pas, c'est que getline (fichier, chaine) est censé prendre TOUTE la ligne, c'est a dire *MESH_NUMVERTEX 8. Donc au début je faisais ça :

    std::string temp;
    iss >> temp (il devrait y avoir *MESH_NUMVERTEX) >> nbVertex;

    Toutefois ça marche pas, et seul :

    iss >> nbVertex; me récupère la bonne valeur...

    *MESH_NUMVERTEX a disparu de la ligne ? .

    De même, quelle différence entre fichier >> ligne et std::getline (fichier, ligne) ?

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    En fait, il n'y a vraiment que quand on rencontre un # qu'il est utile d'utiliser getline()... dans tous les autres cas, il est mieux de une simple lecture de la chaine qui suit, et de la convertir dans ce qui nous convient le mieux.

    Ce ne serait donc pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (chaine == "*MESH_NUMVERTEX") // *MESH_NUMVERTEX nbVertex
    {
        getline (fichier, chaine); // On récupère la ligne
        std::istringstream iss (chaine);
             iss >> m_iNumVertices;
    }
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (chaine == "*MESH_NUMVERTEX") // *MESH_NUMVERTEX nbVertex
    {
        fichier>>chaine; //on récupère la chaine suivante
        std::istringstream iss (chaine);
             iss >> m_iNumVertices;
    }
    car rien n'empeche forcément qu'il y ai quelque chose apres le nombre (de vertex ou de faces)...

    Pour peu que le fichier prenne la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    usemtl Default    f 2 3 4 1  g  f 8 7 6 5  g  f 6 10 9 5  g  f 7 11 10 6  g  f 12 11 7 8  g  f 9 12 8 5  g
    (qui reste malgré tout correcte), getline prendra toute la ligne, alors qu'il ne faut que chaque chaine prise séparément
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    En fait, il n'y a vraiment que quand on rencontre un # qu'il est utile d'utiliser getline()... dans tous les autres cas, il est mieux de une simple lecture de la chaine qui suit, et de la convertir dans ce qui nous convient le mieux.
    Pourquoi que quand on rencontre un # ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (chaine == "*MESH_NUMVERTEX") // *MESH_NUMVERTEX nbVertex
    {
        fichier>>chaine; //on récupère la chaine suivante
        std::istringstream iss (chaine);
             iss >> m_iNumVertices;
    }
    car rien n'empeche forcément qu'il y ai quelque chose apres le nombre (de vertex ou de faces)...
    Je comprends pas tellemnt. On a déjà pris auparavant fichier >> chaine... Donc chaine contient toute la ligne du fichier non ? Pourquoi refait-on encore un fichier >> chaine après ? Donc si je comprends bien, fichier >> chaine ne copie dans chaine que un mot (enfin jusqu'à ce qu'il rencontre un espace ?)...

    Donc imaginons qu'on ait ça :

    bidule chouette 01054555
    supraBidule chouetteHibou 14

    On fait un fichier >> chaine, chaine contient bidule, puis on enchaine avec un getline (fichier, chaine), chaine contient chouette 01054555, puis un autre fichier >> chaine et chaine contient supraBidule, c'est ça ? ^^

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    En ce qui concerne l'utilisation de getline() si on a rencontré un #:

    Le caractère # signifie que tout ce qui suit (jusqu'au premier retour à la ligne) est un commentaire...

    Comme on ne sait pas la longueur du commentaire (tout au plus, on sait qu'il se terminera par un retour à la ligne)... on prend d'office toute la ligne, et on est tranquil

    En ce qui concerne la réutilisation de chaine:

    Si tu regarde attentivement le fichier, tu remarqueras que la "structure" reste toujours identique:

    une information sur ce qui suit et un nombre fini de données...

    Par exemple, pour les coordonées des points, on a
    ce qui revient à dire
    v: on a une coordonnée (suivie de la coordonnée X du point, de la coordonnée Y du point et de la coordonnée Z du point)
    Pour les coins des faces, on a
    ce qui revient à
    f: c'est une face
    (2 3 4 1 ...): l'ensemble des points qui définissent la face
    g: la liste de points est finie

    Pour les commentaires, c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # ceci est un commentaire, il peut contenir autant de chaines que voulu
    #: ce qui suit est un commentaire (tout ce qui suit jusqu'à la fin de la ligne en fait partie)

    Etc.

    Le but de la lecture de chaine au début de boucle, c'est uniquement... pour savoir ce qu'on doit faire.

    Une fois que l'on sait ce qu'on doit faire, on n'a plus besoin de cette valeur, et donc, la variable chaine peut très bien etre réutilisée pour autre chose (pour lire la chaine suivante, par exemple )

    Enfin, concernant l'utilisation de getline() ou de l'opérateur >>, tu as bien compris le principe...

    Je reprend ton exemple pour la suite de mes explications, si tu le veux bien
    bidule chouette 01054555
    supraBidule chouetteHibou 14
    si tu as un code du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    fichier>>chaine; //[1]
    getline(fichier,chaine); //[2]
    Apres le [1] chaine contient bien bidule et tu peux l'utiliser à ta guise...
    Apres le [2] chaine contient, comme tu l'a si bien compris "chouette 01054555"... mais...

    Si tu dois gérer "chouette" et "01054555" séparément, tu sera embeté parce que tu devra commencer par ...séparer chouette et 01054555 avant de pouvoir travailler

    Donc, autant lire les chaines une à une... tu lis une chaine, tu traite la chaine, et tu recommence avec la chaine suivante

    Comme tu l'a bien comprsi, lors du deuxieme passage [1][2], tu aura respectivement "supraBidule" et "chouetteHibou 14" dans chaine, et le problème sera le meme...

    Par contre, si, pour lire les trois chaines, tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    fichier>>chaine; //[1]
    //traitement de la premiere chaine
    fichier>>chaine; //[2]
    traitement de la deuxieme chaine
    fichier>>chaine; //[3]
    traitement de la troisième chaine
    pour les deux lignes, tu aura respectivement

    Apres [1] bidule pour la premiere ligne et supraBidule pour la deuxieme
    Apres [2] chouette pour la premire ligne et chouetteHibou pour la deuxieme
    Apres [3] 01054555 pour la premiere ligne et 14 pour la deuxieme...

    Est-ce que tu comprend mieu l'avantage que l'on peut tirer de cette manière de travailler ?
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    <Parenthèse>
    Citation Envoyé par koala01
    Le caractère # signifie que tout ce qui suit (jusqu'au premier retour à la ligne) est un commentaire...
    Pour ce genre de choses, les streambuf filtrants sont un vrai bonheur: tu plugues ton filtre qui ignore les commentaires à la *nix, et tu lis comme s'ils n'existaient pas.
    James Kanze a écrit deux articles sur le sujet, et boost.iostream met en oeuvre une généralisation du concept.
    </>
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Luc Hermitte
    <Parenthèse>

    Pour ce genre de choses, les streambuf filtrants sont un vrai bonheur: tu plugues ton filtre qui ignore les commentaires à la *nix, et tu lis comme s'ils n'existaient pas.
    James Kanze a écrit deux articles sur le sujet, et boost.iostream met en oeuvre une généralisation du concept.
    </>
    Décidément, il faudrait vraiment qu'un de ces jours je tache de m'attaquer un peu à la bibliotheque boost

    Tout comme je subodore qu'il y aurait beaucoup plus efficace à faire pour le code que je proposais dans mon premier post en passant, par exemple, par une énumération et un switch...case (mais là, je suis trop fatigué)...

    Mais au moins, j'espère que Bakura aura maintenant compris quand il a intéret à utiliser getline() et quand il a intéret à utiliser l'opérateur de flux...

    Sinon, ben, j'essayerai de trouver une autre manière de le lui expliquer
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Non, j'ai vraiment bien compris, je te remercie vraiment, c'était très clair.

    En gros, vu que les lignes ont tout le temps la même forme, c'est mieux d'utiliser >>...

    Je posterai ici mon loader quand je l'aurais fini voir si tu y trouves des choses à améliorer si ça ne te dérange pas ^^.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Par défaut
    C'est toujours comme pour ton cube, le format obj ne gère jamais les normales ?

  11. #11
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Finalement je me suis tourné vers le format ASE. Mon loader est presque terminé. Les normales y sont spécifiés, si elles ne le sont pas, ben j'en ait pas, je peux très bien les calculer mais bon... Il est déjà très peu performant comme ça mon loader si en plus je dois passer du temps à calculer les normales ^^.

  12. #12
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Bien que tu te sois tourné vers ASE (que je ne connais absolument pas), je me permets un petit "up" pour signaler =>Ce lien<= qui contient les spécifications des formats OBJ et MTL, pour ceux que cela pourrait intéresser
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Ok ! Enfin mon loader est fini ! Pour les fichiers txt, je pense que la meilleur doc c'est encore de regarder le fichier ^^.

Discussions similaires

  1. Réponses: 0
    Dernier message: 23/03/2012, 09h59
  2. Récuperer des données dans un fichier XML/ Sitemap
    Par Maldus dans le forum ASP.NET
    Réponses: 6
    Dernier message: 07/07/2008, 17h25
  3. récuperer des données d'un fichier XML
    Par ryoussef19 dans le forum Visual C++
    Réponses: 64
    Dernier message: 10/07/2007, 13h39
  4. récuperer des données d'un fichier xml
    Par Ljungberg dans le forum XML
    Réponses: 4
    Dernier message: 13/06/2006, 09h54
  5. [JTable] Comment récuperer les données d'un fichier texte ?
    Par Makunouchi dans le forum Composants
    Réponses: 2
    Dernier message: 03/05/2005, 16h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo