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

Langage C++ Discussion :

boucle ecriture lecture de fichier


Sujet :

Langage C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut boucle ecriture lecture de fichier
    Bonjour à tous, je suis en train de coder un pti programme mais la je commence à tourner en rond et j'aurais besoin d'un coup de main

    la partie qui bug :

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    while (fichier)
    			{	rest = " ";
    				w = 0;
    				rest.clear();
    				while (!fichier.eof())
    				{	
     
     
    					getline(fichier, contenu);
    					cfichier << contenu << endl;
    					tab[w] = contenu;
     
    					getline(fichier, contenu2);
    					cfichier << contenu2 << endl;
    					tab1[w] = contenu2;
     
    					getline(fichier, contenu3);
    					cfichier << contenu3 << endl;
    					tab2[w] = contenu3;
    					w++;
     
    					if ( w >= 12 )
    					{	if (w == 12)
    						{
    						rest = rest + tab[w];
    						}
    						else
    						{
    						rest = rest + tab[w];
    						rest = rest + tab1[w];
    						rest = rest + tab2[w];
    						}
     
    						cout << rest << endl;
    					}					
            			        if (fichier.eof() == 1)
     
            			        {
     
    					string requete = "INSERT INTO patients ( c1 ,c2 ,c3 ,c4 ,c5 ,c6 ,c7 ,c8 ,c9 ,c10 ,c11 ,c12 ,c13 ,c14) VALUES ('  " + tab[0] + "', '" + tab[1] + "', '" + tab[2] + "', '" + tab[3] + "', '" + tab[4] + "', '" + tab[5] + "', '" + tab[6] + "', '" + tab[7] + "', '" + tab[8] + "', '" + tab[9] + "', '" + tab[10] + "', '" + tab[11] + "', '" + rest + "', '" + rest2 + "' )";				
     
    					if (mysql_query(&mysql, requete.c_str()))
    					{
    					cout << "requete nok" << endl;
    					cout << mysql_error(&mysql);
    					}
    					else {
    					cout <<"requete ok" << endl;
    					remove(direcup);
    					}
     
    					}
    				}
     
    			}
    donc , tant qu'il y a des fichiers dans le repertoire, il va prendre les lignes du fichier unes par unes pour les écrires dans un autre fichier ds un premier temps puis il les stocke dans une variable.

    déjà je suis obliger de faire plusieurs getline dans la boucle car j'ai remarqué que le getline bugger au bout de 90 lignes environ : /

    mais mon plus gros probleme, est que lors de la premiere boucle, pour le premier fichier, la variable rest ne va pas se remplire, et au deuxième passage rest va prendre pour valeur, les lignes du fichier préscédent !

    bon c'est assez brouillon, j'en suis au début (dsl mon clavier n'a pas les accents ^^ )

    si qqn a une idée elle est bienvenue !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 711
    Points
    30 711
    Par défaut
    Salut, et bienvenue sur le forum...

    Le gros problème est que eof() vaut vrai quand... la fin du fichier est déjà dépassée...

    Tu ne peux donc pas te baser sur eof() pour déterminer s'il reste encore quelque chose à lire, sous peine de tenter une lecture supplémentaire qui conduira immanquablement et irrémédiablement à une erreur d'exécution.

    Je te conseille donc de te baser sur l'entrée de la correspondante FAQ pour savoir comment détecter efficacement la fin du fichier

    Mais, l'un dans l'autre, la logique que tu devrais suivre serait donc proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while(fichier)
    {
        while(std::getline(fichier,contenu) )
        {
            /* Ce qu'il faut faire du contenu */
        }
    }

  3. #3
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Tu peux aussi utiliser la méthode good() et quand elle renvoie false vérifier si c'est bien dû à la fin de fichier via la méthode eof().

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 711
    Points
    30 711
    Par défaut
    Citation Envoyé par seriousme Voir le message
    Tu peux aussi utiliser la méthode good() et quand elle renvoie false vérifier si c'est bien dû à la fin de fichier via la méthode eof().
    Peut être pourrais tu expliquer l'avantage que tu as à tester good après la lecture

    getline renvoie une valeur correspondant à vrai si elle arrive effectivement à récupérer une ligne de fichier... Tu n'a donc strictement rien d'autre à faire qu'à vérifier si cette fonction a obtenu un résultat

    Si j'ai bien compris, tab, tab1 et tab2 sont des tableau de chaines de caractères et on pour objectif de récupérer (en un seul tableau) les valeurs lues dans le fichier, afin de pouvoir créer une requete SQL...

    Si l'on considère que tu as un tableau de noms de fichiers sous la forme d'un std::vector<std::string> que j'appelerai filenames pour l'exemple, tu peux parfaitement t'en sortir avec un code proche 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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    /* le fichier de sortie */
    std::ofstream osf("sortie.txt");
    size_t filesSize = filenames.size();
    for(size_t i=0;i<filesSize;++i)
    {
        /* ouvertur du fichier à lire */
        std::ifstream ifs(filenames[i].c_str());
        /* nous avons besoin d'un tableau de chaines pour récupérer
         * les différentes  valeurs
         */
        std::vector<std::string> tab;
        /* et d'une chaine de caractères temporaire */
        std::string line;
        /* que l'on utilise pour lire l'intégralité du fichier source */
        while(std::getline(ifs,line))
        {
            /* on l'écrit dans le fichier de sortie */
            ofs<<line<<std::endl;
            /* et on l'ajoute dans le tableau de chaines */
            tab.push_back(line);
        }
        /* Nous avons fini de lire le fichier, nous créons la requete SQL */
        std::string requete:"insert into patients ( c1 ,c2 ,c3 ,c4 ,c5 ,c6 ,c7 ,c8 ,c9 ,c10 ,c11 ,c12 ,c13 ,c14) VALUES (";
        for(size_t i=0,i<tab.size();++i)
        {
            requete+="'";
            requete+=tab[i];
            requete+="'";
            requete+=(i==tab.size()-1?",":"");
        }
        requete += ")";
        /* et on tente d'invoquer cette requete */
        if (mysql_query(&mysql, requete.c_str()))
        {
            cout << "requete nok" << endl;
            cout << mysql_error(&mysql);
        }
        else 
        {
            cout <<"requete ok" << endl;
        }
     
    }
    NOTA: l'idéal serait peut être de séparer un peu d'avantage les responsabilités, car cette fonction fait trois choses bien distinctes:
    1. lire les fichiers
    2. créer les requetes
    3. effectuer les requetes
    L'idéal serait donc d'avoir autant de fonction qui ne font chacune qu'une et une seule chose

  5. #5
    Invité
    Invité(e)
    Par défaut
    Comme dit précédemment, si tu utilises eof(), il faut mettre le getline en fin de boucle...

    Quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    getline(ifs,line);
    while(!ifs.eof()) {
      // code de traitement ici
      getline(ifs,line);
    }
    Si tu fais dans l'autre sens

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    getline(ifs,line);
    while(!ifs.eof()) {
      getline(ifs,line);
      // code de traitement ici
    }
    Alors, quand tu arrives à la derniere ligne, tu fais un getline, ifs renvoie eof, mais tu essaies de le traiter quand meme avant de tester eof()...

    Alors forcément...

    Sur la FAQ et l'utilisation de

    while(getline()) {}

    comme seule condition de sortie, je ne le ferais pas.

    Le problème c'est que l'on traite de la même façon une situation normale (la fin du fichier) et une situation d'erreur (un getline qui plante)... Ce n'est pas sain. Si l'on est en train de charger une structure, après un eof(), elle est généralement correcte, après un getline() planté, elle ne l'est pas... Un code de ce type est potentiellement dangereux, je pense qu'il serait bon de mettre à jour la FAQ en ce sens...

    Francois

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 711
    Points
    30 711
    Par défaut
    Citation Envoyé par fcharton Voir le message
    <snip>

    Sur la FAQ et l'utilisation de

    while(getline()) {}

    comme seule condition de sortie, je ne le ferais pas.
    Je ne vois pas pourquoi...

    eof() renvoie l'état de l'un des failbit dont disposent les flux, au même titre que bad() ou fail(), mais avec des causes différentes...

    Lorsque tu fais un test uniquement sur eof, tu ne gère donc qu'une partie seulement des erreurs qui peuvent être survenues lors de la lecture.

    De plus, il existe un opérateur de conversion implicite en booléen qui permet d'obtenir une valeur vraie si la dernière opération sur le flux s'est correctement terminée, ou qui renvoie une valeur fausse si, pour quelle que raison que ce soit (corruption des données, fin de fichier atteinte, mauvais type de donnée à lire ou à écrire) l'opération a échoué.

    Il est donc beaucoup plus sécurisant d'effectuer un test sur getline ou même sur un flux>>valeur (à condition dans ce cas d'être sur que le fichier n'a pas été corrompu) que d'effectuer un test sur eof ou autre propriété d'erreur
    Le problème c'est que l'on traite de la même façon une situation normale (la fin du fichier) et une situation d'erreur (un getline qui plante)... Ce n'est pas sain. Si l'on est en train de charger une structure, après un eof(), elle est généralement correcte, après un getline() planté, elle ne l'est pas... Un code de ce type est potentiellement dangereux, je pense qu'il serait bon de mettre à jour la FAQ en ce sens...

    Francois
    l'utilisation de getline n'est, normalement, que la première opération qui tend à charger la structure...

    En effet, tu te retrouve, après utilisation de getline, uniquement avec une chaine de caractères dont tu sais qu'elle correspond à une ligne complète du fichier... dont tu espère qu'elle contient les informations (ou du moins une partie des informations ) qui te seront utiles pour charger la structure

    Ce n'est, bien souvent, pas suffisant pour décider que tu as chargé ta structure, qui peut, pourquoi pas être composée, entre autres, de valeurs numériques (voire d'autres structures).

    Il faut donc passer par une étape de conversion de cette ligne lue pour obtenir les valeurs qui t'intéressent réellement avec le type qui est réellement requis...

    Et il t'est toujours possible, si la conversion (ou une partie de la conversion) échoue de réagir de la manière la plus appropriée, et de manière bien plus fine que sur le seul fait d'une fin de fichier atteinte

    Mais le fait de passer par une chaine de caractères temporaire rend la vérification du format beaucoup plus facile, et permet de s'adapter à n'importe quel format (allant du fichier plat au XML en passant par le CSV)

    EDIT: Si tu es sur que ton fichier est correct (comprend: que les données sont du bon type et dans le bon ordre), tu peux très bien envisager une boucle sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while( (fichier>>valeur) )
    {
    }
    qui s'arrêtera dés que tu n'arrivera pas à lire la valeur.

    Cela arrivera:
    • parce qu'il n'y a plus de valeur à lire (fin de fichier)
    • parce que l'information qui suit dans le fichier n'est pas du type attendu (ex: double au lieu de int )

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut
    Merci pour toutes ces réponses, je vais tester avec un while (getline), ça devrait déjà aller mieux !

    edit : c'est bon ça a l'air de fonctionner, plus de pb de ligne max thx.

  8. #8
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Peut être pourrais tu expliquer l'avantage que tu as à tester good après la lecture
    Pas après avant

    getline renvoie une valeur correspondant à vrai si elle arrive effectivement à récupérer une ligne de fichier... Tu n'a donc strictement rien d'autre à faire qu'à vérifier si cette fonction a obtenu un résultat
    Découplage des responsabilités : getline est censé lire une ligne sur un flux valide, pas vérifier si tout va bien, même si de fait c'est le cas.
    Mais si plus tard le code évolue et qu'un autre fonction que getline est utilisée et que celle-ci ne fait pas ce processing supplémentaire de vérification il faudra changer le code.
    Alors qu'en séparant la logique de contrôle de la validité du flux de celle d'utilisation du flux, cette dernière peut évoluer sans se préoccuper du contexte.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    while(stream.good())
    {
        // read
    }
    if (stream.fail())
    {
        // error management
    }
    else if (stream.eof())
    {
        // OK
    }

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut
    je vien de retester, avec un while (getline) , il me refait le même bug, cad il me dit que la requete n'est pas valide.

    ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    while (getline(fichier, contenu))
    				{	
    					//cout << contenu << endl;
    					tab[w] = contenu;				
    					w++;
     
     
    					if ( w >= 12 )
    					{	
     
    						rest = rest + tab[w-1];
     
    					}
    donc, losque j'essaye d'envoyer la requete avec la variable rest dedans, il me renvoi un erreur, et cela au environ de la 90ieme ligne. (rest est un string)
    donc je ne sais pas d'ou cela vien, j'ai chercher mais je n'ai pas trouvé de manuel sur le getline parlant d'un nb de ligne maximum, c'est pour ça que dans ma "premiere version" je faisais plusieurs getline dans la meme boucle : /

    bon c'est un peu confus, mais si qqn a une idée.

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 711
    Points
    30 711
    Par défaut
    Citation Envoyé par seriousme Voir le message
    Pas après avant



    Découplage des responsabilités : getline est censé lire une ligne sur un flux valide, pas vérifier si tout va bien, même si de fait c'est le cas.
    Mais si plus tard le code évolue et qu'un autre fonction que getline est utilisée et que celle-ci ne fait pas ce processing supplémentaire de vérification il faudra changer le code.
    Alors qu'en séparant la logique de contrôle de la validité du flux de celle d'utilisation du flux, cette dernière peut évoluer sans se préoccuper du contexte.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    while(stream.good())
    {
        // read
    }
    if (stream.fail())
    {
        // error management
    }
    else if (stream.eof())
    {
        // OK
    }
    Je ne vois absolument pas où est le problème:

    L'opérateur de conversion implicite en booléen renvoie vrai si le flux est dans un état valide après la dernière action menée et false s'il est dans un état invalide.

    Tu peux donc déjà écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /* je tente seulement d'ouvrir un fichier */
    std::ifstream ifs("fichier.txt");
    if(!ifs)
        throw FileNotOpened("fichier.txt");
    (tu ne sais pas forcément pourquoi le fichier n'est pas ouvert, mais tu sais qu'il a été impossible de l'ouvrir )

    De plus, La lecture dans flux a, par nature, des effets de bords, à savoir:
    • déplacer le "curseur" de lecture
    • modifier la validité du flux.
    Ce deuxième point est à mettre en relation avec trois états d'invalidité potentiellement concurrents et un état de validité exclusif, représentés par des drapeaux au sein de la valeur renvoyée par rdstate():
    1. eofbit qui représente le fait que le fichier est devenu invalide parce que l'on a atteint la fin de fichier
    2. failbit qui représente le fait que le fichier est devenu invalide à cause d'une erreur reliée à la logique interne de l'opération elle-même
    3. badbit qui représente le fait que le fichier est devenu invalide à cause d'une erreur survenue sur le buffer du flux
    4. goodbit qui est exclusif des trois premiers (qui ne vaut vrai que si les trois autres sont à faux) et qui représente le fait que le flux est dans un état valide
    (chacun de ces état peut être récupéré séparément à l'aide des fonctions respective eof(), fail(), bad() et good() )

    (Pour être clair: l'opérateur implicite de conversion en booléen revient à invoquer good() )

    Et l'opération de lecture va donc fatalement faire que le flux est soit dans un état valide, soit dans un état invalide, même si l'on ne sait pas trop la raison de l'invalidité du flux (est-ce parce que l'on a essayé de lire une valeur d'un mauvais type ou parce qu'il n'y avait simplement plus de valeur à lire )

    Par contre, la fonction getline a l'énorme avantage d'être l'opération de lecture qui risque le moins de rater sur un fichier texte:

    Quelle type de donnée pourrait donc être le mieux adapté à la récupération de caractères qu'une... chaine de caractères , surtout si l'on peut avoir la certitude que la chaine en question est clairement délimitée (par défaut, par le retour chariot)

    Au final, une fois que tu as la certitude que le fichier a bel et bien été ouvert, une boucle proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::string temp;
    while(std::getline(ifs,temp))
    {
        /* gestion de la chaine lue afin de récupérer les données */
    }
    est donc bel et bien à prendre sous la forme de "tant que j'arrive à lire une ligne".

    La validation des données elles-même est à mettre dans la boucle, mais c'est normal, étant donné qu'il faut s'assurer que les données sont cohérente avec ce que tu attends

    Si, par la suite, tu veux affiner la gestion de la raison qui a fait que tu n'a pas réussi à lire une ligne dans le fichier, tu n'as, en définitive, plus beaucoup:
    Ce ne peut être suite au fait que badbit est placé car le buffer a déjà été correctement créé.

    Ce ne peut pas non plus être au fait qu'il y a eu une erreur propre à la lecture de la donnée car rien n'est plus adapté pour la récupération d'un (de) caractère(s) qu'une... chaine de caractères

    Si tu n'a pas réussi à lire la ligne, c'est donc... qu'il n'y avait plus de ligne à lire (que tu avais atteint la fin de fichier)

    Ce ne serait par contre pas le cas avec un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type var;
    while(ifs>>var)
    {
    }
    ou pire proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type var1;
    type2 var2
    while(ifs>>var1>>var2)
    {
    }
    parce que tu ne sais pas à la base si le fait que la lecture échoue vient du fait que la fin de fichier est atteinte ou du fait que la donnée à lire n'est pas du type adéquat

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 27
    Points : 16
    Points
    16
    Par défaut
    allons bon ! j'ai enfin trouvé mon erreur, ça venait d'un apostrohe dans mon fichier text, j'aurais dû y penser plus tôt ! ^^

    je n'ai plus qu'à les remplacer.

    encore merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. boucle infini lecture de fichier
    Par freeway57 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 13/06/2014, 14h57
  2. boucle de lecture des fichier binaire
    Par syki.mail dans le forum MATLAB
    Réponses: 9
    Dernier message: 10/10/2012, 15h54
  3. java card ecriture/lecture de fichier
    Par rojina29 dans le forum Développement Mobile en Java
    Réponses: 0
    Dernier message: 14/11/2008, 15h12
  4. calcul et boucle sur lecture de fichier
    Par marinaetsonchat dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 22/11/2007, 16h15
  5. Réponses: 2
    Dernier message: 26/09/2003, 15h51

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