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 :

Parser une chaine de caractère


Sujet :

C++

  1. #1
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut Parser une chaine de caractère
    Bonjour

    Je suis confronté à un problème très bizarre je dois dire.

    J'ai un fichier de nombres complexes sous la forme de matrices :
    1+4i 3-5i 7+2i
    3+4i 4-66i 45-78i
    4+8i 56+2i 4-i
    Je lit via une méthode le fichier de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     while ( getline( file2, val, ' ' ) )
            {
    			cout << val << endl ;
    			this->values[i][j] = Complex::getComplexFromString(val) ;
    				j++ ;           
    				// new row
    				if(j == m) { i++ ; j=0 ; }
            }
    Comme vous pouvez le voir, j'affiche 'val' pour être sûr que chaque complexe est bien pris. Et c'est le cas, j'ai la liste de tous mes complexes qui s'affiche.
    Mais le truc bizarre, c'est ce que j'obtiens à la sortie de la méthode getComplexFromString(). Cette méthode a pour but de créer un objet Complex en parsant la chaine 'val' et en récupérant, sous la forme de variables double, la partie réelle et la partie imaginaire.

    Voici la partie importante de celle-ci :
    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
    // si il y a le signe +
    if(sNum.find("+") != string::npos)
    		{
    			istringstream iss( sNum );
    			getline( iss, s, '+' ) ;
    			re = stringToDouble(s);
    			getline( iss, s, '+' ) ;
    			im = stringToDouble(s);
     
    		}
                   // il y a le signe -
    		else 
    		{		
    			istringstream iss( sNum );
    			getline( iss, s, '-' ) ;
    			re = stringToDouble(s);
    			getline( iss, s, '-' ) ;
    			im = -1*stringToDouble(s);
    		}
    	}
     
    		Complex ret(re,im);
    		return ret ;
    Je ne sais pas si c'est la meilleure façon de faire mais en clair, si y'a le signe + alors on sépare la chaine en deux selon le +, pareil pour le - .

    Mais en sortie, j'obtiens la liste de complexes suivantes :
    1+4i
    3-5i
    7+2i
    4-66i
    45+8i
    56+2i
    4-6.5271e+262i
    2.64014e-308-6.5271e+262i
    Incompréhensible... Les trois premiers sont bons, le quatrième manque, le cinquième est bon, le sizième est partiellement bon, le septième manque, le huitième est bon et le neuvième est pas bon. Et le dernier, je ne sais pas d'où ça vient. En fait, pour le neuvième, c'est normal que la partie imaginaire soit fausse vue que je n'ai pas encore codé le fait que "i" tout seul vaut 1.

    Mais pourquoi ce résultat pour les autres? Certains sont bons, d'autres non et d'autres manquent carrément !

    Sauriez-vous d'où ça vient ? Me conseillez-vous une autre méthode? (sachant que je n'ai pas le droit d'utiliser de biblio externe).

    Merci

    Nas'

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    Je peux me tromper (apres tout), mais...

    Pour expliquer le fait que le quatrième manque, c'est relativement simple...

    Tu effectue un getline avec, comme séparateur... l'espace, ce qui est un des séparateur de ton fichier...

    Sauf que...

    Il y a de fortes chances pour que le séparateur, en fin de ligne (apres le 3 eme, et le 6eme, dans l'exemple donné) ne soit pas un espace, mais bien ... un \n...

    Et il semlerait que tu ne le prenne pas en compte

    Résultat des courses, quand tu effectue la lecture, tu obtiens pour val:
    1. 1+4i
    2. 3-5i
    3. 7+2i(\n)3+4i coupé à \n... 3+4i est donc "passé à la trappe"
    4. 4-66i
    5. 45-78i\n4+8i coupé à \n... 4+8i est donc "passé à la trappe"
    6. 56+2i
    7. 4-i Qu'y aura-t-il à la place du ...
    ce qui, semble justifier tes résultats ...

    Je crois donc qu'il serait opportun de travailler en deux temps:
    1. Récupérer la ligne complete par un
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      getline(fichier,ligne); //prend la ligne -->\n (trois valeurs selon
                              //                      exemple)
    2. récupérer les valeurs de la ligne une à une
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      //transformation de ligne en istringstream
      std::istringstream iss(linge);
      //récupération des valeurs, avec l'espace comme séparateur
      while(iss)
      {
          getline(iss,val); // pas sur de moi, sur ce coup là :p
          ...
      }

  3. #3
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Merci pour ta réponse qui me semble logique en fait.
    Mais ce qui est étrange, c'est que si j'affiche les valeurs récupérées avec le séparateur espace, j'ai bien TOUS les éléments de la matrice. Le problème se situe en sortie de la fonction qui coupe chacun d'eux selon le signe (+ ou -). Donc c'est que le séparateur espace marche mais ce n'est pas normal comme tu viens de l'expliquer

    Ca commence à me prendre légèrement la tête là.

    Nas'

  4. #4
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Je viens d'utiliser mon cerveau et je comprends maintenant pourquoi il est tout à fait normal qu'avant la fonction, tout s'affiche correctement puisque la valeur en fin de matrice "contient" celle qui suit...

    Alors j'ai fait quelque chose, j'ai écrit dans ma fonction une petite boucle qui affiche sous forme décimale la valeur de chaque caractère reçu.
    Et le 7+2i qui se trouve en fin de ligne de la matrice se retrouve bien avec la valeur de ce qui suit...

    Ta méthode est pas mal, j'y avais pensé mais le truc c'est que ça va trop alourdir mon code et comme je ne maitrise pas du tout le C++ (je l'apprends tout seul depuis quelques jours), je ne me sens pas encore trop à l'aise.

    Alors ce que je vais faire, c'est que je essayer de faire une fonction qui remplace tout \n par un espace. On verra ce que ça donne.

    Merci et à bientôt pour le verdit

    Nas'

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je n'aime pas trop la méthode dont tu lis tes complexes. Elle est bien trop rigide. En particulier, si tu as une entrée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    +++ La valeur est +++ : +3-6i
    Tu ne pourras jamais la lire avec ta méthode. En fait, tu a écrit du code pour lire une fichier ne contenant que des complexes, il me semblerait plus intéressant d'écrire du code lisant 1 complexe sur le flux en cours, sans toucher à rien d'autre. Quelquechose qui pourrait s'utiliser ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Complexe c1, c2;
    int i;
    string s;
    cin >> s >> c1 >> i >> c2;
    Et alors ta lecture de fichier pourrait s'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    vector<Complexe> resultat;
    Complexe courant;
    while (iss >> courant)
    {
      resultat.push_back(courant);
    }
    return resultat;
    PS :
    Citation Envoyé par koala01
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while(iss)
    {
        getline(iss,val); // pas sur de moi, sur ce coup là :p
    }
    Et tu as raison... Il faut écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while(getline(iss,val))
    {
    }

  6. #6
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Merci pour ta méthode qui est plus juste. Mais c'est trop tard, j'ai trop avancé pour revenir au Vector. Sinon, je connais d'avance la forme des complexes et il n'y aura pas de '+' devant la partie réelle.

    En fait, je viens d'essayer un truc et ça ne marche toujours pas mais là c'est vraiment très étrange.
    Dans ma fonction de séparation via l'espace, j'ai fait ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    if((ind = val.find("\n")) != string::npos)
    			{
     
    				// jump the \n
    				this->values[i][j] = Complex::getComplexFromString(val.substr(0,ind-1)) ;
    				j++ ;           
    				// new row
    				if(j == m) { i++ ; j=0 ; }
    				this->values[i][j] = Complex::getComplexFromString(val.substr(ind+1,val.length()-1)) ;
    			}
    else {
    // ce qu'il y avait avant 
    }
    Donc si je trouve le '\n', je construits deux string que je passe en paramètre sans le '\n'. Et dans ma fonction getComplexFromString(), j'ai affiché la valeur ASCII de chaque char contenu dans la string passée en argument et c'est supposé marcher puisqu'il n'y a plus le 10 (\n) !!

    Qu'est-ce qui ne va pas encore ?

    Nas'

  7. #7
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Maintenant, c'est sûr qu'il y a un problème non pas dans ma fonction de décomposition du complexe mais dans celle qui récupère dans le fichier en séparant par l'espace.
    Car je viens de tester ma fonction getComplexFromString() via une saisie au clavier et ça marche parfaitement, j'ai bien mes objets Complex qui sortent.

    Ce que je ne comprends pas, c'est que dans ma fonction, je dis bien que si y'a un \n, créer deux string (que j'ai même affichées) et les passer à ma fonction de récupération. Celle-ci marchant parfaitement, je ne vois pas d'où ça peut venir!!

    Nas'

  8. #8
    Membre habitué Avatar de ccensam
    Inscrit en
    Juillet 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Juillet 2005
    Messages : 128
    Points : 162
    Points
    162
    Par défaut Voila ce que je pense
    En plus de tout ce qui est déja dit. Quand vous découpez votre chaîne (complexe) en fonction de l'operateur (+ ou -) vous aurez :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    si votre complexe, par exemple est 5+6i :
    la décomposition est : 
    5
    6i
    Alors la comversion de 6i en double echouera car 6i n'est pas un double ni un float ni un entier n'est rien. c'est une chaine.
    Donc tu dois éliminer le i.

    En plus, remarquez que vous devez traiter le cas ou votre complexe s'ecrit sous le forme : a+i ou a-i , la partie imaginaire ne contient aucun digit!!!!

    En tout cas, je vais essayer de créer un bout de code pour vous!!!!

Discussions similaires

  1. [XL-2007] Parser une chaine de caractère SQL avec un code en VBA
    Par Sosthy10 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 30/06/2015, 11h49
  2. Parser une chaine de caractères
    Par batchi dans le forum Général Python
    Réponses: 3
    Dernier message: 05/02/2014, 11h34
  3. [DOM] Parser une chaine de caractères au lieu d'un fichier
    Par kkt8 dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 27/03/2012, 10h30
  4. [XML] Parser une chaine de caractère XML
    Par lololeuleu dans le forum APIs
    Réponses: 10
    Dernier message: 16/08/2007, 21h27
  5. Parser une chaine de caractères
    Par mariafan dans le forum Langage
    Réponses: 8
    Dernier message: 18/07/2007, 09h49

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