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 :

couper une chaine qui a une longueur variable


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut couper une chaine qui a une longueur variable
    Bonjour,

    Voilà j'ai une chaine de caractère suivant : /devl/truc/koi/X(n fois)-AAAAMMJJHHMMSS.

    le X représente l'origine du fichier, ce nom peut-être de taille 4 ou 6.

    La racine du fichier peut elle varier selon l'environnement.

    Ce que je voudrai essayer de faire ce de récupérer juste le nom du fichier.

    Je sais le faire sous shell mais en C++ je ne sais pas...

    Merci d'avance pour votre aide,

  2. #2
    Invité
    Invité(e)
    Par défaut
    Si je comprend bien, tu veux récupérer juste X(n fois)-AAAAMMJJHHMMSS.
    Tu as la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void _splitpath(
       const char *path,
       char *drive,
       char *dir,
       char *fname,
       char *ext 
    );
    dans stdlib, mais c'est peut-être que sous Windows.

    Sinon si tu veux le faire toi même, parcourt ta chaîne en partant de la fin et tu t'arrêtes au premier '/'. Tu met les caractères dans un buffer de taille fixe pour pas t'embêter (en considérant qu'il peut y avoir 6 X) et à la fin tu inverses la chaine.

  3. #3
    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 708
    Points
    30 708
    Par défaut
    Salut,

    Il existe une classe fournie par le standard qui permet de se faciliter énormément la vie dans la gestion des chaines de caractères.

    Il s'agit de la std::string, qui est disponible dans l'espace de noms std par inclusion du fichier <string>.

    L'avantage de cette classe, c'est que tu n'es plus obligé de gérer les chaines de caractères sous la forme de tableaux de caractères alloués dynamiquement (de chaine "C style" ), mais aussi qu'elle fournit un tas de méthodes sympa

    Parmis les méthodes en question, tu a find, qui recherche la première occurrence d'un mot ou d'une chaine dans une autre, et rfind recherche la dernière occurrence d'une chaine dans une autre, ainsi qu'une méthode substr qui permet de récupérer une partie de la chaine d'origine

    Si donc tu n'a strictement aucun besoin de récupérer les différents noms de dossiers, tu peux très bien utiliser d'abord la méthode rfind, suivie de la méthodes substr sous une forme 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
    int main ()
    {
        std::string chemin="/devl/truc/koi/X(n fois)/AAAAMMJJHHMMSS";
        std::string final;
        /*recherche la dernière occurence de "/" */
        size_t found= chemin.rfind("/");
        /* si l'a trouvé */
        if(found!=std::string::npos)
            /* nous supprimons tout ce qui précède, mais aussi le dernier "/" */
            final=chemin.substr(found+1);
        else
            final = chemin;
        std::cout<< final;
        return 0;
    }
    Si tu veux récupérer chaque nom de dossier séparément, il faudra "ruser" un peu, et, par exemple, faire en sorte de placer chaque sous chaine dans un tableau de chaine sous une forme 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
    int main ()
    {
        std::string chemin="/devl/truc/koi/X(n fois)/AAAAMMJJHHMMSS";
        std::vector<std::string> tab;
        size_t found;
        do
        {
            /* recherche le premier "/" de la chaine */
            found= chemin.find("/");
            /* si le caractère est trouvé et que ce n'est pas le premier de la
             * chaine, c'est que nous avons affaire à un sous dossier
             */
            if(found!=0 && found!=std::string::npos)
            {
                /* nous prenons le premier nom trouvé */
                std::string temp=chemin.substr(0,found);
                /* nous l'insérons dans le tableau */
                tab.push_back(temp);
                /* et nous supprimons la sous-chaine correspondante
                 * (y compris le "/" qui suit
                 */
                chemin=chemin.substr(found+1);
            }
            /* le caractère n'est pas trouvé, c'est que nous avons affaire au fichier
             */
            else if(found==std::string::npos)
            {
                //gère la dernière chaine de caractère
                tab.push_back(chemin);
            }
            /* si le caractère est trouvé en première position (index 0), c'est
             * que nous avons affaire au chemin absolu, et que nous devons gérer "/"
             */
            else if(found == 0)
            {
                chemin=chemin.substr(1);
            }
        }while(found!=std::string::npos);
        /* il ne reste "plus qu'à" afficher les différents dossier */
        for(size_t i = 0;i<tab.size();++i)
            std::cout<<tab[i]<<std::endl;
        return 0;
    }
    Mais, pour que tu puisse comprendre l'intégralité du code, il me faut aborder - même de manière très succinte - la classe std::vector.

    Il s'agit en réalité d'un conteneur fourni par le standard qui agit exactement de la même manière qu'un tableau C style, dans le sens où tous les éléments du tableaux sont mémorisés de manière contigüe, et qu'il assure donc un acces en temps constant à n'importe quel élément contenu.

    Le standard aime bien fournir des conteneur "génériques", que l'on appelle des "classes template", et le vector en fait partie.

    Pour pouvoir utiliser cette classe, il "suffit" d'indiquer entre <> le type d'élément qu'il va contenir lors de la déclaration
    .
    La classe est disponible dans l'espace de noms std (comme tout ce qui est fourni par le standard), par inclusion du fichier d'en-tête <vector>

    La méthode push_back que j'ai utilisée dans ce code a simplement pour but de rajouter un élément apres le dernier existant.

    La méthode size permet quant à elle de connaitre le nombre d'éléments présents dans le tableau (mais l'acces par index se fait de 0 à size() -1 )

  4. #4
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 266
    Points : 6 688
    Points
    6 688
    Billets dans le blog
    2
    Par défaut
    A voir aussi boost::filsystem. Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    boost::filesystem::path monPath( "C:/dev/Libs/boost_1_35_0/boost/filesystem/config.hpp" );
    std::cout << monPath.leaf() << std::endl;
     
    // sortie console: config.hpp

Discussions similaires

  1. [sed] Remplacer une chaine qui précède une autre chaine
    Par noooop dans le forum Shell et commandes GNU
    Réponses: 8
    Dernier message: 25/03/2014, 10h31
  2. Réponses: 0
    Dernier message: 04/08/2010, 15h02
  3. Comperer une chaine hexa avec une chaine non hexa
    Par kaboume dans le forum Développement
    Réponses: 2
    Dernier message: 21/05/2010, 17h21
  4. Réponses: 15
    Dernier message: 26/03/2006, 13h10
  5. Réponses: 4
    Dernier message: 16/04/2004, 17h31

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