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 :

string Buffer = "";


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    20
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 20
    Par d�faut string Buffer = "";
    salut
    j'ai un fichier .csv qui contient 27000 ligne et je veux suprrimer les ligne 4,5,6
    �a fonction avec le code que j'ai mais �a prend presque 2min pour s'ex�cut�
    y'a t'il unmoyenne pour minimiser le temps de l'execution

    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
     
    #include <string> 
    #include <fstream> 
     
    void Erase_Line1(char* z, int Line_to_Erase) 
    { 
    std::string Buffer = ""; //Variable contenant le texte à réécrire dans le fichier 
    std::ifstream ReadFile( z); 
    if (ReadFile) //Si le fichier est trouvé 
    { 
    std::string line; 
    int Line = 0; 
    while ( std::getline( ReadFile, line ) ) //on parcours le fichier et on initialise line à la ligne actuelle 
    { 
    Line++; 
    if(Line != Line_to_Erase) //Si la ligne atteinte est différente de la ligne à supprimer... 
    Buffer += line + "\n"; //On ajoute le contenu de la ligne dans le contenu à réécrire 
    } 
    } 
    ReadFile.close(); //On ferme le fichier en lecture 
     
    std::ofstream WriteFile( z); //On ouvre ce même fichier en écriture 
    WriteFile << Buffer; //On écris le texte dedans 
    WriteFile.close(); //et on ferme le fichier 
    } 
     
    int main() 
    { 
    Erase_Line1("z.txt", 4); 
    Erase_Line1("z.txt", 4); 
    Erase_Line1("z.txt", 4); 
     
    return 0; 
    }

  2. #2
    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,

    Selon la taille r�elle du fichier (parce que, 27000 lignes, ca fait beaucoup, mais, encore faut il voir combien de caract�res cela repr�sente ), tu pourrais envisager de te baser sur l'entr�e de la FAQ qui pr�sente comment lire l'int�gralit� d'un fichier dans un buffer...

    Une fois cette op�ration effectu�e, il deviendra relativement facile de faire le tri de ce que tu veux garder et de ce que tu veux virer � coup de find_first_of, ingore et autres substr
    L'id�e pouvant se baser sur un algorithme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    POUR chaque ligne précédent celle que je veux retirer
       écrire la ligne dans le fichier de destination
    FIN POUR
    supprimer la ligne que je veux retirer
    SI Fin exécution
        ecrire ce qui reste du fichier
    FIN SI
    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

  3. #3
    Membre �prouv� Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    D�tails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par d�faut
    Oui,

    ecrire a la vol�e chaque ligne lue qui doit etre dans le fichier destination/final.
    De m�moire quand tu fais un append sur string (ou un +=) il y a creation d une nouvelle string et recopie ce qui prend beaucoup de temps.

    sinon il doit exister la classe stringbuffer qui peut aussi reduire le temps d execution.

    [edit] bon y a pas stringbuffer en cpp, mais la concatenation de 27000 string me semble etre tres optimisable.

  4. #4
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    La classe std::string poss�de une fonction membre reserve.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre �prouv� Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    D�tails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par d�faut
    ca se fait de reserver, disons des lignes de 50 car en moyennes soit 1.35 Mega Windowsien

    [edit] d autant que apr�s test �a ne fait rien gagner en temps. Ce serait la recopie de caract�re qui prendrait tout ce temps

  6. #6
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 760
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activit� : Architecte technique retrait�
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 760
    Par d�faut
    D�j�, il serait peut �tre sage de ne pas relire 3 fois le fichier:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    int main() 
    { 
         Erase_Line1("z.txt", 4); // 1 fois
         Erase_Line1("z.txt", 4); // 2 fois
         Erase_Line1("z.txt", 4); // 3 fois
     
          return 0; 
    }
    => plut�t que de passer un num�ro de ligne, passer un vecteur de lignes rang�es dans l'ordre croissant
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    int main() 
    { 
         int lines[] = { 4, 5, 6, 0 };
         Erase_Line1("z.txt", lines);
         return 0; 
    }
    Puis on modifie le code de Erase_Line1
    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
    void Erase_Line1(char* z, int* lines_to_erase)
    { 
          std::ifstream ReadFile(z); 
     
          if (ReadFile) //Si le fichier est trouv� 
          { 
               std::ofstream WriteFile (z+qqc);
     
               std::string line;
                int linenb = 0; 
                int erasing_line = *lines_to_erase;
    
                while (erasing_line != 0) {
                     while ( std::getline( ReadFile, line ) ) //on parcours le fichier et on initialise line � la ligne actuelle 
                     { 
                           linenb++;
                           if (linenb == erasing_line)
                                 break;
                           WriteFile << line << endl; // *fix* nl?
    
                     }
                lines_to_erase++;
                erasing_line = *lines_to_erase;
                } 
                // recopier la fin du fichier ? Ajouter un test sur eof?
                while ( std::getline( ReadFile, line ) ) //on parcours le fichier et on initialise line � la ligne actuelle 
                { 
                           WriteFile << line << endl; // *fix* nl?
                 } 
                ReadFile.close(); //On ferme le fichier en lecture  
                WriteFile.close(); //et on ferme le fichier 
           }
    }
    Je n'ai pas test�, mais ca donne l'id�e.
    - W
    edit: j'avais oubli� de "coller" la fin du fichier
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    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
    Ceci dit, je me rend compte que tu va lire l'int�gralit� du fichier... � chaque fois que tu voudra supprimer une ligne...

    Au final, en voulant supprimer trois lignes, tu en arrive � devoir en lire ... 3*27000 = 78000 ...

    D�s lors, tu pourrais surement diviser le temps n�cessaire par trois, simplement en lisant le fichier une bonne fois pour toute et en mettant les lignes lues dans un conteneur "qui va bien"

    Ainsi, bien que la suppression d'�l�ment ne soit pas "forc�ment" le point fort de la classe vector, tu pourrais envisager un code 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
    int main()
    {
        /* un conteneur pour les lignes du fichiers */
        std::vector<std::string> tab;
        /* ouvrons le fichier en lecture */
        std::ifstream ifs("lefichier.csv");
        /*une chaine de caractères temporaire pour la lecture */
        std::string str;
        /* tant que l'on arrive à lire une ligne, ajoutons la dans le tableau
         * prévu à cet effet 
         */
        while(std::getline(ifs, str))
            tab.push_back(str);
        /* comme nous voudrons réouvrir le fichier en écriture
         * autant le fermer correctement 
         */
        ifs.close();
        /* créons deux itérateur: le premier sur la première chaine à supprimer
         * le second sur la derniere
         */
        std::vector<std::string>::iterator beg=tab.begin()+3 ;// (1+3= ...4 ;) )
        std::vector<std::string>::iterator end= tab.begin()+5;//(1+5 = ...6 ;) )
        /* et supprimons supprimons les, ainsi que ce qui se trouve entre les deux
         */
        tab.erase(beg, end);
        /* il n'y a plus qu'à réécrire le fichier */
        std::ofstream ofs("lefichier.csv");
        for(size_t i=0;i<tab.size();++i)
            ofs<<tab[i];
        /* merci d'être passé */
        return 0;
    }
    A adapter �ventuellement pour apporter plus de flexibilit� et ou plus de s�curit�

    [EDIT]grilled sur la remarque
    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

  8. #8
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 760
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activit� : Architecte technique retrait�
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 760
    Par d�faut
    D�sol�

    Pourquoi vouloir charger le contenu du fichier en m�moire alors qu'il "suffit" (a mon sens) de le r�-�crire sans les lignes que l'on souhaite supprimer?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    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
    Citation Envoy� par wiztricks Voir le message
    D�sol�

    Pourquoi vouloir charger le contenu du fichier en m�moire alors qu'il "suffit" (a mon sens) de le r�-�crire sans les lignes que l'on souhaite supprimer?
    - W
    Pour la raison toute simple que, dans l'�tat actuel des choses, yanlou ne semble pas vouloir pr�voir la suppresion de plusieurs ligne d'une seule traite (ce que fait pourtant mon code)...

    D�s lors, si pour chaque suppression de ligne, tu impose la lecture/r��criture compl�te du fichier en vue d'en supprimer la ligne souhait�e, cela devient vraiment masochiste (imagine le jour o� il souhaitera supprimer 100 lignes diss�min�es dans son fichier )

    une alternative serait de prendre les num�ros de lignes avant toute suppression dans un conteneur tri� (std::set, pourquoi pas ) et de les supprimer � la vol�e lors de la copie du fichier.

    Comme tu le vois, il y a de nombreuses solutions, et, finalement, aucune n'est *forc�ment* mauvaise... du moment que l'on s'arrange pour ne lire/�crire qu'une seule fois le fichier
    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

  10. #10
    Membre �m�rite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    D�tails du profil
    Informations personnelles :
    �ge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par d�faut
    Moi je me demande pourquoi charger inutilement beaucoup de donn�es en m�moire, avec toute la gestion de buffer que �a impose, alors qu'on peut faire si simple:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void eraseLines(const std::string& file,const std::string& tmpfile,std::set<unsigned int> lines) {
    ifstream f(file.c_str());
    ofstream tmpf(tmpfile.c_str());
     
    while(...) {
       lire ligne
       si ligne pas dans lines
          tmpf << line << std::endl;
    }
    supprimer file
    renommer tmpfile en file
    }
    A noter que pour trouver un fichier temporaire, il existe une fonction en C standard (par contre elle ne peut pas r�server un fichier sur un disque donn�, ce qui ralentirait cet algo, mieux vaut ajouter un suffixe au nom du fichier d'origine)
    On peut m�me faire g�n�rique en passant un foncteur au lieu d'en set, vector tri� ou autre, comme �a on pourrait d�terminer si une ligne reste ou pas avec d'autres crit�res que son num�ro.

  11. #11
    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
    Comme je l'ai dit, il existe plusieurs possibilit�s, et il est m�me vraisemblable que je me dirige vers une solution comme la tienne (nos posts se sont crois�s ), zach, pour autant que j'aie la certitude que l'application ne devra jamais faire autre chose que supprimer des lignes "inutiles"...

    L'avantage de la solution que j'ai pr�sent�e avant est qu'elle permet malgr� tout de garder les donn�es "sous la main" s'il advient que la suppression de lignes ne doit �tre qu'une des possibilit�s offertes par l'application
    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

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Erreur character string buffer too small
    Par uriel khaan dans le forum SQL
    R�ponses: 2
    Dernier message: 21/03/2007, 17h24

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