Manipulation complexe de chaine de caractère....

Résolu
Signaler
Messages postés
25
Date d'inscription
mercredi 11 avril 2007
Statut
Membre
Dernière intervention
6 avril 2008
-
Messages postés
25
Date d'inscription
mercredi 11 avril 2007
Statut
Membre
Dernière intervention
6 avril 2008
-
Bonjours a tous,

j'ai un probleme avec un de mes dévevellopement :

    j'ai une chaine de style :

       doc.txt&doc2.txt&toto.doc&
       dans un char.

       j'ai écrit une fonction, lire ( char * lachaine, int numerodumot );
       par ex :

       si lachaine = doc.txt&doc2.txt&toto.doc&;
       lire(lachaine,2) = "doc2.txt";

       mais, je bloque sur cette fonction que j'ai réécrite entierement plusieurs fois... sans succés ....

      pour ceux qui peuvent m'aider, je vous remerie d'avance, et je vous souhaite un bonne journée ...

4 réponses

Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009
1
Bonjour,

Voila un petit exemple rapide d'extraction de ce type de sous-chaîne de caractère.
 
La sous-chaîne extraite dans la fonction Lire() est stockée dans une chaîne de caractères statique interne à la fonction. C'est beaucoup plus simple comme écriture et comme utilisation que de devoir passer une chaîne supplémentaire à la fonction mais il ne faudra pas utiliser cette fonction plusieurs fois dans la même instruction ! Elle retournerait systématiquement la dernière demande traitée. C'est à dire qu'il ne faut pas faire quelque chose du genre : printf("%s - %s",Lire(lachaine,2),Lire(lachaine,3));
comme dans la fin du programme où l'on voit que les appels de la fonction sont exécutés du dernier vers le premier puisque c'est le résultat du premier appel qui est répété !

#include <stdio.h>





const char* Lire
(
    const char* pszChaine // E:chaîne à examiner du style "xxx&yyy&zzz&"
   ,int         iRang     // E:rang de la sous-chaîne à extraire
)                         // S:sous-chaîne extraite
{
   // --- Sous-chaîne extraite
   const int iLongSousChaine = 100;
   static char szSousChaine[iLongSousChaine];




   // --- Délimiteur de sous-chaînes
   const char delimiteur = '&';






   // --- Pointer le début de la sous-chaîne
   // --- en recherchant le délimiteur précédent
   int i = 0;
   const char* pszDebut = pszChaine;
   while (i < iRang - 1)
   {
      pszDebut = strchr(pszDebut,delimiteur);
      if (pszDebut == NULL)
      {
         // --- Rang maxi dépassé : sous-chaîne inexistante
         // --- On retourne une sous-chaîne vide
         szSousChaine[0] = 0;
         return szSousChaine;
      }
      ++pszDebut; // pour dépasser le délimiteur
      ++i;
   }
  
  
   // --- Pointer la fin de la sous-chaîne
   // --- en recherchant son propre délimiteur
   const char* pszFin = strchr(pszDebut,delimiteur);
   if (pszFin == NULL)
   {
      // --- Rang maxi dépassé : sous-chaîne inexistante
      // --- On retourne une sous-chaîne vide
      szSousChaine[0] = 0;
      return szSousChaine;
   }






   // --- Recopier la sous-chaîne
   int iLongueur = pszFin - pszDebut;   if (iLongueur >iLongSousChaine) iLongueur iLongSousChaine - 1;
   strncpy(szSousChaine,pszDebut,iLongueur);
   szSousChaine[iLongueur] = 0; // terminateur
   return szSousChaine;
}





void main()
{
   char* szLaChaine = "doc.txt&doc2.txt&toto.doc&";



   printf("1 = <%s>\n",Lire(szLaChaine,1));
   printf("2 = <%s>\n",Lire(szLaChaine,2));
   printf("3 = <%s>\n",Lire(szLaChaine,3));
   printf("4 = <%s>\n",Lire(szLaChaine,4));

   // --- Exemple de cas illégal ici
   printf("\n1=%s 2=%s 3=%s 4=%s\n"
         ,Lire(szLaChaine,1)
         ,Lire(szLaChaine,2)
         ,Lire(szLaChaine,3)
         ,Lire(szLaChaine,4));
}


Ce qui donne :

1 = <doc.txt>
2 = <doc2.txt>
3 = <toto.doc>
4 = <> plus de sous-chaîne à extraire

1=doc.txt 2=doc.txt 3=doc.txt 4=doc.txt on récupère 4 fois la première demande !



Jean-François
Messages postés
482
Date d'inscription
vendredi 26 août 2005
Statut
Membre
Dernière intervention
5 décembre 2009
1
Pas de quoi,

Il n'y a pas de problème pour lire avec une boucle mais :
- en commençant par 1 (le premier rang est 1 et non 0 ici)
- en modifiant la fonction Lire() pour retourner un pointeur NULL quand il n'y a pas (ou plus) de sous-chaîne, c'est plus pratique à utiliser !

#include <stdio.h>



const char* Lire
(
    const char* pszChaine // E:chaîne à examiner du style "xxx&yyy&zzz&"
   ,int         iRang     // E:rang de la sous-chaîne à extraire (à partir de 1)
)                         // S:sous-chaîne extraite ou NULL si aucune
{
   // --- Sous-chaîne extraite
   const int iLongSousChaine = 100;
   static char szSousChaine[iLongSousChaine];



   // --- Délimiteur de sous-chaînes
   const char delimiteur = '&';





   // --- Pointer le début de la sous-chaîne
   // --- en recherchant le délimiteur précédent
   int i = 0;
   const char* pszDebut = pszChaine;
   while (i < iRang - 1)
   {
      pszDebut = strchr(pszDebut,delimiteur);
      if (pszDebut == NULL)
      {
         // --- Rang maxi dépassé : sous-chaîne inexistante
         // --- On retourne un pointeur NULL
         return NULL;
      }
      ++pszDebut; // pour dépasser le délimiteur
      ++i;
   }
  
  
   // --- Pointer la fin de la sous-chaîne
   // --- en recherchant son propre délimiteur
   const char* pszFin = strchr(pszDebut,delimiteur);
   if (pszFin == NULL)
   {
      // --- Rang maxi dépassé : sous-chaîne inexistante
      // --- On retourne un pointeur NULL
      return NULL;
   }





   // --- Recopier la sous-chaîne
   int iLongueur = pszFin - pszDebut;   if (iLongueur >iLongSousChaine) iLongueur iLongSousChaine - 1;
   strncpy(szSousChaine,pszDebut,iLongueur);
   szSousChaine[iLongueur] = 0; // terminateur
   return szSousChaine;
}





void main()
{
   const char* szLaChaine = "doc.txt&doc2.txt&toto.doc&";



   const char* psz;
   for (int i=1 ; psz = Lire(szLaChaine,i) ; ++i)
      printf("%d = <%s>\n",i,psz);
}


Ce qui donne :

1 = <doc.txt>
2 = <doc2.txt>
3 = <toto.doc>



Jean-François
Messages postés
25
Date d'inscription
mercredi 11 avril 2007
Statut
Membre
Dernière intervention
6 avril 2008

Merci beaucoup , c'est exactment cela qu'il me fallai.

merci encore.

petite question, tu crois que

for(i=0;i<...;i++)
lire (str,i);

marcherai ?

bonne journée a tous !
Messages postés
25
Date d'inscription
mercredi 11 avril 2007
Statut
Membre
Dernière intervention
6 avril 2008

D'accord, merci encore pour ton aide et bonne journée.
je commencais vraiment a m'arracher les yeux mais la, sa va mieu ...   :D