Strtok - probleme d'encapsulation?

Résolu
Chris8412 Messages postés 4 Date d'inscription mercredi 23 juillet 2008 Statut Membre Dernière intervention 28 juillet 2008 - 23 juil. 2008 à 17:56
Chris8412 Messages postés 4 Date d'inscription mercredi 23 juillet 2008 Statut Membre Dernière intervention 28 juillet 2008 - 28 juil. 2008 à 12:44
Bonjour a toutes et a tous!

Voici mon premiere message sur votre forum. Avant de poser ma question, félicitations et merci a tous pour cette source d'infos gigantesque qu'est cppfrance! Ca fait environ un mois que je le parcours tous les jours pour trouver des solutions a mes problemes et apprendre le C++ ....

Malgres tout, j'ai un probleme et je n'ai pas trouvé comment le résoudre, ou du moins pas encore, mais apres un gros mal de tete, me suis dis que peut-etre vous pourriez éclairer la lanterne d'un tout jeune programmeur en C++.

Voila, j'utilise strtok pour trouver des chaines de caracteres dans un fichier que j'ouvre au préalable.
Ce fichier ressemble a ceci :

toto      titi      tata      tutu
toto2    titi2    tata2    tutu2
...

chacune des chaines de caracteres est séparée par une tabulation et chaque ligne par un retour a la ligne... rien d'extraordinaire.

J'ai testé strtok sur une ligne, cela marche nickel.
J'ai testé sur une colonne, cela marche nickel.
Mais quand je mixe els 2 cela ne marche pas....

Voici mon bout de code :

char *p1, *p2;
char *input = Buffer;
p1 = strtok (input,"\r\n");
   while (p1 != NULL) {



   TListItem *pItem = ListViewText->Items->Add();
   p2 = strtok(p1, "\t");
  while (p2 != NULL)  {
      pItem->SubItems->Add (p2);
      p2 = strtok (NULL, "\t");
  }



  p1 = strtok(NULL,"\r\n");
}





En fait lorsque j'execute la ligne p2 = strtok(p1, "\t");  p1 qui jusque la contenait bien ma ligne en entier, passe subitement a la valeur de p2 ... soit le premier élement de ma ligne.

Quelqu'un aurait-il une idée sur la question?

PS : si jamais la réponse existe déja et que je ne l'ai tout simplement pas trouve sur le forum, je m'en excuse ...

Merci beaucoup
Chris

6 réponses

Liverion Messages postés 296 Date d'inscription mardi 22 avril 2008 Statut Membre Dernière intervention 18 août 2008
24 juil. 2008 à 09:31
Il me semble que c'est indiqué dans la doc du strtok , mais voila l'explication : strtok modifie la chaine qu'on lui passe en entrée, tout le temps. Il te suffit donc d'utiliser une variable temporaire dans laquelle tu stockerais la valeur de ton p1 :

char *p1, *p2,*tmp;

char *input = Buffer;

p1 = strtok (input,"\r\n");

   while (p1 != NULL)
  {

      TListItem *pItem = ListViewText->Items->Add();

        *tmp1 = *p1;

  p2 = strtok(tmp1, "\t");
   while (p2 != NULL) 
{
       pItem->SubItems->Add (p2);
       p2 = strtok (NULL, "\t");
   }

   p1 = strtok(NULL,"\r\n");

}

~~
Les trois lois de Codes-Sources :
Loi 1) Tu lis et respectes le reglement
Loi 2) Tu penses à valider si une reponse apportée à ton problème t'a aidé
Loi 3) Si tu ne respectes pas les 2 premières ....TU SORS !!
3
cs_Lucky92 Messages postés 180 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 16 août 2012 2
24 juil. 2008 à 20:11
Salut,

si ton path est délimité par des guillemets voici une adaptation possible du code :

#include <fstream>
#include
#include <sstream>
using namespace std;
...
ifstream file( "input.txt" ) ;
string line ;
while ( getline( file , line )  )
{
    TListItem *pItem = ListViewText->Items->Add();
    istringstream iss( line );
    string word ;
    while ( iss >> word )
    {             if ( *word.begin() '"'  && <gras>*word.rbegin() !'"' </gras>)

            {

                string suite;

                while( *word.rbegin() != '"' && iss >> suite )

                {

                   word + = " " + suite;

                }

            }
        pItem->SubItems->Add( word.c_str() );
    }
}
...

la traduction est la suivante :
si le mot lu commence par un " et ne se termine pas par un ", alors c'est qu'il y a une suite ; tant que le mot ne se termine pas par un " et que j'arrive à extraire une suite, je concatène un espace et la suite à mon mot.
3
cs_Lucky92 Messages postés 180 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 16 août 2012 2
23 juil. 2008 à 21:20
Bonsoir,

une des possibilités pour résoudre ton problème est d'utiliser du vrai C++ standard ( en effet strtok c'est une fonction C ).

#include <fstream>
#include
#include <sstream>
using namespace std;
...
ifstream file( "input.txt" ) ;
string line ;
while ( getline( file , line )  )
{
    TListItem *pItem = ListViewText->Items->Add();
    istringstream iss( line );
    string word ;
    while ( iss >> word )
    {
        pItem->SubItems->Add( word.c_str() );
    }
}
...

Personnellement, je trouve que la résolution de ce type de problème est nettement plus simple en C++ standard. Désolé si je ne répond pas vraiment à ta question...
j'ai essayé de débugger ton programme, mais finalement,  c'est plus rapide d'écrire le code ci-dessus que de se replonger dans la doc de strtok.
0
Chris8412 Messages postés 4 Date d'inscription mercredi 23 juillet 2008 Statut Membre Dernière intervention 28 juillet 2008
24 juil. 2008 à 11:06
Bonjour bonjour!!

Liverion, j'ai déja essayé de passer par une variable temporaire mais ca n'a pas marché. En meme temps, j'avoue que c'était en fin de journée et du coup j'ai peut-etre commis une erreur que je n'ai pas vu ou mal interprétée. merci tout de meme pour l'info car au moins je saurais que j'étais pas loin de la solution !!

Lucky92, j'ai essayé ta méthode et j'avoue qu'elle est beaucoup plus simple et terriblement efficace!!!! Merci énormément!!


Ceci dit, j'ai rencontré un tout petit  probleme en l'utilisant. A savoir : l'un des string qu'elle doit me trouver est en fait le path d'une image. Mais sachant que l'image peut tout-a-fait se trouver dans "Mes documents" ... cela signifie que le path contient des espaces. Donc lorsque je cherche les mots dans ma ligne, il me coupe le path a chaque espace. Auriez-vous une idée?

PS : sachant qu'il s''agit d'une autre question qui découle de la premiere, dois-je faire un autre post? Si oui, je le créerai sans soucis

Merci encore a vous deux.

Chris
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Chris8412 Messages postés 4 Date d'inscription mercredi 23 juillet 2008 Statut Membre Dernière intervention 28 juillet 2008
24 juil. 2008 à 11:07
PS : j'ai mis les deux réponses en accepté, car elles répondent toutes les 2 a mon probleme...

Chris
0
Chris8412 Messages postés 4 Date d'inscription mercredi 23 juillet 2008 Statut Membre Dernière intervention 28 juillet 2008
28 juil. 2008 à 12:44
Désolé j'ai pris un long weekend ;)

Effectivement ca marche et en plus c'est on ne peut plus simple ... merci milles fois Lucky92 !!

Chris
0
Rejoignez-nous