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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    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
    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
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    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 )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 294
    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 294
    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, 09h31
  2. Réponses: 0
    Dernier message: 04/08/2010, 14h02
  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, 16h21
  4. Réponses: 15
    Dernier message: 26/03/2006, 12h10
  5. Réponses: 4
    Dernier message: 16/04/2004, 16h31

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