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 :

Position curseur après récupération caractère


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2016
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Position curseur après récupération caractère
    Bonjour,

    J'ai un problème. Je voudrais remplacer des valeurs spécifiques dans un fichier texte.
    Dans un premier lieu, je voudrais repérer ces valeurs :

    1)Je récupère chaque ligne du fichier jusqu'à trouver celle qui précède la ligne avec les valeurs

    2) Je cherche un caractère spécifique (mais présent dans d'autres lignes, d'où étape 1) précédant la valeur

    3)Je récupère la position du curseur (et la valeur, ça c'est bon)


    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
     
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    #include <sstream>
     
     
    using namespace std;
     
    string const chemin("D:/test.txt"); 
    char caractere (0);
    int position = 0;
     
    int main()
    {
        string line; //déclaration d'une chaîne de caractère nommée "line"
        ifstream fichier(chemin.c_str()); //on ouvre le fichier en lecture, avec chemin définit plus haut
     
        if (!fichier) //si on a un problème à l'ouverture
    		return -1; //on renvoie une erreur
        else {
     
        while (!fichier.eof()) //tant qu'on est pas à la fin du fichier
        {
            getline (fichier, line); //récupération de chaque ligne
            if(line == "chaine_recherchee") //Si la ligne correspond à celle qui précède la ligne avec la valeur
            {
     
                do{
                    fichier.get(caractere); //cherche parmis tous les caractères
                }while (caractere != 'X');      //la lettre X
                position  = fichier.tellg(); //on recupere la valeur de la position
                cout << position  << endl; //et on l'affiche
            } //fin si
        }// fin while
        } //fin else
        fichier.close();
    } //fin main
    Le problème, c'est que j'ai un écart de 10 caractères entre la position réelle dans le fichier texte et la position retournée par le programme.

    Ce problème n'apparaît seulement quand il y a plusieurs valeurs à récupérer. S'il n'y a qu'une chaîne recherchée, le programme retourne la bonne position.

    Autre soucis, j'ai remarqué qu'après le caractère recherché, si j'ajoute des retour à la ligne dans le .txt, j'ai un écart de 2 caractères en plus qui s'ajoute avec la valeur retournée par le code.

    Si j'ajoute n'importe quoi mais sur la même ligne du caractère, juste après, pas d'écart en plus.

    Ex fichier.txt :

    blablablablablablablablablablablablablablablablablabla
    blablablablablablablablablablablablablablablablablabla

    Chaine_recherchee
    blablablablablabla X blablablablablablablablabla

    blablablablablablablablablablablablablablablablablabla

    Chaine_recherchee
    blablablablablabla X blablablablablablablablabla

    blablablablablablablablablablablablablablablablablabla
    Chaine_recherchee
    blablablablablabla X blablablablablablablablabla

    blablablablablablablablablablablablablablablablablabla

    Je voudrais surtout que quelqu'un m'éclaire sur le positionnement du curseur. Je pensais que l'écart venait du fait qu'il va se positionner au mot d'après mais l'écart ne correspond pas ?

    J'espère avoir été clair, merci à quiconque prendra le temps de m'aider

    EDIT : nom des variables mis à jour

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Honnêtement c'est très difficile de te comprendre, et il est logique que tu es des difficultés à transformer cela en code, tellement c'est flou dans ta tête...

    Si je te suis, tu cherches à remplacer "des valeurs" (caractères ?) par d'autres... dans ce cas, la méthode de l'objet string, find_first_of pourrait faire l'affaire, non ?

    Avec ton exemple,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    string exemple ("blablablablablablaXblablablablablablablablabla");
     
    size_t pos = exemple.find_first_of('X');
     
    cout << "Position de X: " << pos << endl; // Position de X: 18
    Pour remplacer un caractère spécifique,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    string exemple ("blablablablablablaXblablablablablablablablabla");
     
    size_t pos = exemple.find_first_of('X');
     
    exemple[pos] = 'b'; // remplace 'X' par 'b'
     
    cout << exemple << endl; // blablablablablablabblablablablablablablablabla
    La question que je me pose est, est-ce que cette position c'est par rapport à l'ensemble du fichier, ou par rapport à une ligne du fichier ?

    Si je tape à côté dans ma réponse, il faudra sans doute que tu apportes des détails ou un exemple concret...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2016
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Salut fred1599,

    Tu as vu juste, j'ai un fichier texte de ce type :


    <block name="Coding_A">
    <attr value="X8Y2">
    </block>

    <block name="Coding_B">
    <attr value="X4Y2">
    </block>

    <block name="Coding_C">
    <attr value="X9Y2">
    </block>

    J'ai arrêté l'extrait à ces 3 blocs, il y en a plus. Le caractère en gras (la coordonnée suivant X) est "la valeur" que je récupère.
    Je voudrais mettre en mémoire la position de cette coordonnée "9". (en rouge)
    Quand je dis "position", c'est effectivement par rapport à l'ensemble du fichier et non de la ligne.
    Dans mon cas, la coordonnée en X : "9" du 3ème bloc est le caractère n°982.
    Avec mon programme, j'obtiens 992.
    Cette coordonnée est un chiffre, et j'en calcule une nouvelle dans ce même programme.
    Il y a en tout 16 blocs donc 16 coordonnées à modifier.

    Pourquoi je cherche cette position ?
    Une fois récupérée, j'utilise :

    fichier.seekp(position,ios::beg); //J'ouvre le fichier texte, et je me met à l'emplacement de la coordonnée avec ladite position

    (ex : 982 caractères après le début, pour la coordonnée du block 3)

    fichier<< setw () << nouvelle_coordonnée; //J'écris la nouvelle coordonnée correspondante sur l'ancienne, pour la remplacer

    A chaque bloc correspond une nouvelle coordonnée.

    Le problème, c'est que je pensais récupérer la position avec : fichier.tellg(); en la mettant dans "position" :

    Je cherche le X précédant la coordonnée, donc je pensais que le curseur se mettrait juste après

    Quand j'affiche position, sa valeur ne correspond pas à la place de la coordonnée dans "fichier.txt", j'ai un écart de 10, pour chaque coordonnée.

    Résultat, la nouvelle coordonnée se retrouve dans les choux, 10 caractères après l'ancienne.

    Pour ta méthode avec find_first_of, je ne connais pas la valeur de la coordonnée, je sais seulement qu'il y a un 'X' avant...
    Je ne peux donc pas la chercher directement.
    D'où cette méthode, je ne sais pas s'il y plus simple.

    Rappel : je cherche la ligne du type " <block name="Coding_C"> ", je recherche ensuite le X pour récupérer l'ancienne valeur. J'utilise l'ancienne pour calculer la nouvelle et j'écris la nouvelle au bon endroit sauf qu'elle écrite ailleurs car la position n'est pas la bonne.

    Mon programme est long, l'extrait mis au début comporte juste la partie récup de position, qui ne marche déjà pas. En soit la partie calcul je n'avais pas besoin d'en parler, mais si ça peut vous aider à mieux comprendre ?

    Je sais pas si c'est plus clair... J'espère que vous serez pas fâches avec les coordonnées en tout cas

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    Vous vous emmerdez pour pas grand-chose.
    Il s'agit d'un fichier au format XML, utilisez une bibliothèque XML pour lire directement les informations et construire les objets en mémoire.
    Une simple requête XPath pour trouver le ou les nœuds à modifier en RAM.
    Faire les modifications en RAM.
    Vous sauvegardez vos nœuds directement dans le fichier en utilisant la bibliothèque XML.

    10 lignes à tout péter.

  5. #5
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    C'est pas encore tout net, mais pourquoi ne pas lire ligne par ligne, et récupérer les valeurs de X et Y à l'aide de sscanf ?

    Ça travaille avec les notions de C, mais bon le passage du C au C++ ici c'est un peu dommage,

    En C, ça donnerait un truc du genre,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
     
    int main(void){
     
        const char *s = "<attr value=\"X4Y2\">";
     
        int x, y;
     
        sscanf(s, "<attr value=\"X%dY%d\">", &x, &y);
     
        printf("x -> %d et y-> %d\n", x, y);
     
        return 1;
    }
    En C++

    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
    #include <string>
    #include <cstdio>
     
    using namespace std;
     
    int main(){
     
        string s = "<attr value=\"X4Y2\">";
     
        int x, y;
     
        sscanf(s.c_str(), "<attr value=\"X%dY%d\">", &x, &y);
     
        cout << "x -> " << x << " y -> " << y << endl;
     
        return 1;
    }
    Du coup dans la lecture d'un fichier si on adapte

    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
    #include <iostream>
    #include <string>
    #include <fstream>
     
    #include <cstdio>
     
    using namespace std;
     
    int main(){
     
        ifstream ifs ("text"); // mettre le chemin de ton fichier
     
        string line;
     
        int x, y;
     
        while (getline(ifs, line)){
     
            if (line.find("<attr value=")==0){
                sscanf(line.c_str(), "<attr value=\"X%dY%d\">", &x, &y);
                cout << "x -> " << x << " y -> " << y << endl;
            }
        }
     
        ifs.close();
     
        return 0;
    }
    Le résultat semble être ce que tu souhaites

    x -> 8 y -> 2
    x -> 4 y -> 2
    x -> 9 y -> 2
    De là, je te laisse tester, il faudra parser (analyser) tes lignes, les modifier, etc...

    L'autre possibilité est aussi d'utiliser les expressions régulières, ou comme le dit le VDD, une librairie réservée à ce format de fichier (XML).

    Et d'autres solutions existent encore, c'est au choix...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Si le fichier est de taille raisonnable et tient en mémoire, un bibliothèque XML DOM sera certainement le plus simple (récemment, j'ai un peu utilisé pugi qui a une interface sympa). Si le fichier peut être énorme, une bibliothèque XML avec une interface SAX ou autre du même type sera plus adaptés, mais aussi plus complexe à utiliser.

    D'où viens ton écart ? Je ne sais pas trop, j'ai l'impression que tu ne nous montre pas tout. Est-ce que par hasard tu additionne un entier que tu calcules avec le résultat de tellp ? Si tel est le cas, ça peut être ça : Un retour chariot, sur certains OS, c'est 2 caractères. Mais les flux se chargent de n'en faire plus qu'un seul caractère en mémoire. Donc avancer de 1 en mémoire n'est pas équivalent à avancer du 1 dans le fichier.

    Mais quoi qu'il en soit, ta stratégie ne pourrait fonctionner que si le nombre de caractères de remplacement est absolument identique à celui de caractères initial, sinon, tu devras quoi qu'il arrive quand même réécrire tout ce qui vient derrière ton insertion/suppression. C'est pour ça qu'en général on part plutôt sur un schéma :
    - Je charge tout, puis j'écris tout (après avoir fait un backup au cas où l'écriture plante) (ce que fera du XML DOM)
    ou
    - Je lis dans un fichier source, et au fur et à mesure j'écris dans un fichier de destination (ce que fera du XML SAX)
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2016
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Salut, le programme marche bien, je suis passé de codeblocks à visual studio.

    J'aimerais savoir pourquoi le résultat diffère d'un compilateur à un autre, mais je ne vais pas perdre plus de temps dessus (et vous faire perdre le vôtre)
    Donc bon, merci à tous d'avoir pris le temps de m'aider.
    Pour info, je ne peux pas passer en XML, car le programme sur lequel je travaille sera réutilisé plus tard par d'autres personnes, et surtout je ne connais absolument rien de ce format. Rester en c++ était une obligation.

    Merci encore

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    J'aimerais savoir pourquoi le résultat diffère d'un compilateur à un autre
    Pourquoi voulez-vous qu'il en soit ainsi.
    Chaque compilateur implémente la norme du C++ à sa manière et donc le résultat n'a que peu de chance d'être identique à l'octet prés.

    je ne peux pas passer en XML, car le programme sur lequel je travaille sera réutilisé plus tard par d'autres personnes
    Raison de plus pour utiliser un standard de l'informatique qu'est le XML.
    Le XML est un formatage des données, pas un langage informatique.

    et surtout je ne connais absolument rien de ce format.
    Bin, c'est le moment de vous y mettre.

    Rester en c++ était une obligation.
    Toutes nos propositions sont dans le cadre du langage C++.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Encodage] caractères bizarres affichés après récupération de mails en imap
    Par PHPspartan dans le forum Langage
    Réponses: 0
    Dernier message: 15/05/2014, 09h45
  2. position d'une chaine après un caractère
    Par bellak dans le forum C#
    Réponses: 1
    Dernier message: 25/05/2010, 02h49
  3. Réponses: 2
    Dernier message: 25/08/2008, 11h23
  4. [TstringGrid] et position curseur
    Par petitcoucou31 dans le forum Composants VCL
    Réponses: 10
    Dernier message: 01/11/2005, 22h28
  5. Réponses: 4
    Dernier message: 07/06/2005, 15h14

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