Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur Substr sur un string

    12 octobre 2018 à 10:40:39

    Bonjour,

    je récupère la liste des fichiers dans un répertoire que je stock ensuite dans une chaine de carractère , je dois ensuite isoler plusieurs morceaux du nom de chaque fichier pour les utiliser.

    Malheureusement quand je fais un substr ou un erase, ca me limite la position de départ à 0, 1 ou 2 (ce qui est dérangeant vue que je dois sélectionner des caractères au niveau du 12/13eme caractère.

    en gros je suis censé sélectionner les 3 lignes de chiffres (Cf ci-dessous) mais ne pouvant pas me positionner au 13/14 eme caractère c'est un peux difficile.

    je pense que ca peut avoir un rapport avec le DIR mais pourtant ca m'affiche bien une chaine de caractère et la bonne.

    Quelques idées? j'avoue que je bloque...

    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <windows.h>
    #include <sys/types.h>
    #include <dirent.h>
    #include <sys/stat.h>
    #include <time.h>
    #include <conio.h>
    #include <fstream>
    
    
    using namespace std;
    
    
    int i=0;
    
    void tri(string chaine)
    {
    
    
        string nom;
        string nom2;
        string date;
    
    
      //RZP-EDOIRABECA_TV_9999999_12345678_201810
        i++;
        if(i>1)
        {
            string str = chaine;
    
    
            cout << str<<endl;
    
            nom = str.substr(12,16);
            nom = nom.erase(16,20);
    
    
            cout << nom << "   "<< nom2 <<"   "<< date << endl;
    
        }
    
    
    }
    int main()
    {
    
    
    
        DIR *dir;
        struct dirent *p;
        char *fic = NULL;
    
        dir=opendir("d:/utilisateurs/William/Desktop/dev/c++/tri2/test");
        while((p = readdir(dir))!=NULL)
        {
                fic = p->d_name;
    
                string test = fic;
    
                cout << test << endl;
    
                tri(test);
    
    
    
        }
        closedir(dir);
    
    
    
     return 0;}
    



    -
    Edité par Smokof 12 octobre 2018 à 10:45:08

    • Partager sur Facebook
    • Partager sur Twitter
      12 octobre 2018 à 11:12:35

      Salut,

      Pour extraire des chaines de caractère selon un pattern, si ton compilateur te le permet (C++11), il serait plus pratique d'utiliser les regex

      Le tiens pourrait être (si j'ai bien compris ce que tu veux extraire)

      .*_([0-9]+)_([0-9]+)_([0-9]+)

      Sinon pour ton substring, j'ai pas bien saisi le problème, pourquoi tu dis ne pas pouvoir te positionner au bon caractère ?

      -
      Edité par romantik 12 octobre 2018 à 12:00:14

      • Partager sur Facebook
      • Partager sur Twitter
      Dream on, Dream on, Dream until your dream comes true
        12 octobre 2018 à 11:18:07

        ca m'affiche une erreur lors de l'execution (pas dans le compilateur, le programme se lance bien) , mais il m'affiche un out of range en me disant  "_pos (wich is 12) > this-> size() <which is 2>

        ce que je comprends c'est que la position de début peut pas passer au dessus de 2 alors que la chaine est bien plus longue, mais du coup mes caractères sont bien plus grands que le 2eme...

        -
        Edité par Smokof 12 octobre 2018 à 11:20:58

        • Partager sur Facebook
        • Partager sur Twitter
          12 octobre 2018 à 11:33:08

          Eh bien puisque tu n'as aucune vérification de pattern avant l'extraction, tu appliques substring sur une mauvaise string

          Je pense que tu sautes '.' (le répertoire courant) grâce à ta variable globale i (pas très propre comme façon de faire d'ailleurs, on y reviendra si tu veux) mais tu te prends quand même '..' (le répertoire parent) que tu passes dans ta fonction subtring, mais qui est de longueur 2 (ce que t'indique l'erreur)

          Tu dois pouvoir voir que tu es en train de traiter '..' grâce à ton affichage `cout << test << endl`

          • Partager sur Facebook
          • Partager sur Twitter
          Dream on, Dream on, Dream until your dream comes true
            12 octobre 2018 à 12:17:08

            Salut,

            tu as le code

                    nom = str.substr(12,16);
                    nom = nom.erase(16,20);
             

            Mais:

            • si str ne fait pas au minimum 28 caractères (12 + 16 = 28, parait-il :D ), tu aura une exception de type out_of_range
            • Par la suite, tu veux effacer les caractères 16 à 20 d'une chaine de caractères qui n'en contient que ... 16... Comment veux tu que l'ordinateur s'y prenne???

            -
            Edité par koala01 12 octobre 2018 à 12:25:27

            • Partager sur Facebook
            • Partager sur Twitter
            Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
              12 octobre 2018 à 18:38:31

              Pour le cas particulier des listing de répertoire, il y a boost/std filesystem

              namespace fs = // std ou boost filesystem
              
              using file_list = std::vector<fs::path>;
              
              file_list list{};
              for (auto it = fs::directory_iterator{root}
                   ; it != fs::directory_iterator{}
                   ; ++it){
                 auto p = it->path();
                 if (fs::is_regular_file(p)){
                   list.push_back(p);
                 }
              }

              A la sortie du for, list contient la liste des fichiers du répertoire ^^ on peut avoir la liste des fichier du répertoire et de tous les sous-répertoire en remplaçant le directory_iterator par un recursive_directory_iterator. Naturellement comme filesystem est dédiée à la gestion des systèmes de fichiers, on peut extraire l'extension, le nom du fichier, le chemin, on peut récupérer la taille, construire des chemins, créer des répertoires et même des arborescences complètes. De tout c++17, c'est franchement ce que j'utilise le plus, avec ça naviguer dans les systèmes de fichier est un vrai bonheur ^^ 

              -
              Edité par int21h 12 octobre 2018 à 18:54:38

              • Partager sur Facebook
              • Partager sur Twitter
              Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                22 octobre 2018 à 8:08:00

                Bonjour,

                Je reviens sur mon erreur (maintenant que je suis de retour sur le projet xD) 

                L'erreur était bien causee par le répertoire courant et parents (./..) qui étaient donc inférieur au str que je devais faire, je vous remercie l'erreur a pu être corrigée

                • Partager sur Facebook
                • Partager sur Twitter
                  22 octobre 2018 à 9:01:28

                  Malheureusement question gcc il faut encore utiliser libstdc++-fs pour avoir le support de filesystem sur Linux :(
                  • Partager sur Facebook
                  • Partager sur Twitter

                  git is great because Linus did it, mercurial is better because he didn't.

                  Erreur Substr sur un string

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown