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

Discussion :

QFile : récupérer une chaîne entre guillemets

  1. #1
    Membre du Club
    Femme Profil pro
    Apprentie Développeuse
    Inscrit en
    Février 2013
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Apprentie Développeuse
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2013
    Messages : 106
    Points : 44
    Points
    44
    Par défaut QFile : récupérer une chaîne entre guillemets
    Bonjour à tous ,

    voila j'ai un petit (méga) soucis un peu bête je pense..
    J'ai un fichier .txt avec à l'intérieur des coordonnées
    Bouton1 ("Bonjour",100,50);
    Bouton2("Hello",50,200);
    etc...


    Je sais créer des boutons dynamiquement mais la j'aimerais les créer et les placer en fonction de ma fenêtre mais je n'arrive pas je bloque un peu

    Voici mon code

    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
     
    void Carte::fichierConfigration_Projet()
    {
        int  compteur_ligne=0 , valeurFicLigne=0;
        QString nombtn;
        QFile fichierConfiguration_qf("/Appli/Fic.txt");
         QTextStream lecture(&fichierConfiguration_qf);
            long nombreLignes=0;
            while(!lecture.atEnd()){
                QString nom_Projet_str = lecture.readLine();
               // btn_nomProjet = new QPushButton(nom_Projet_str);
                if(nom_Projet_str.contains("PovSite('",Qt::CaseSensitive)){
                    QStringList listeLigne_strl = nom_Projet_str.split("PovSite('");
                    listeLigne_strl.removeFirst();
     
                    QString ligneValeur = listeLigne_strl.join(QString("'"));
                     QMessageBox::information(this, "Fichier de configuration", "Le fi"+ligneValeur);
                     nombtn = ligneValeur;
                     if(ligneValeur.contains("',",Qt::CaseSensitive)){
                         QStringList listeLigne2 = nom_Projet_str.split("',");
                         listeLigne2.removeFirst();
                         QString ligneValeur2 = listeLigne2.join(QString(","));
                          QMessageBox::information(this, "Fichier de configuration", "Le fi"+ligneValeur2);
                          listeLigne2.removeLast();
                     }
                   // btn_nomProjet = new QPushButton(nom_Projet_str);
                    // on récupère le chiffre nous indiquant le nombre de ligne
                   // valeurFicLigne = ligneValeur.toInt();
     
                       btn_nomProjet->setGeometry(valeurFicLigne, valeurFicLigne,10,10);
                       // grilleBouton->addWidget(btn_nomProjet);
                }
     
     
     
                nombreLignes++;
     
            }
            compteur_ligne = nombreLignes;
     
        }
    }
    c'est un peu la confusion..
    J'aimerais que mon bouton s'appelle bonjour et qu'il soit placé à la coordonnée(100,50)
    mais je n'arrive pas à récupérer bien mes valeurs

    Merci par avance pour avoir lu mon problème !!

  2. #2
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut Solution possible
    Bonjour,

    Je ne suis pas sûre de comprendre le code. En effet, dans le fichier texte on est censé retrouvé ce format :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Bouton1 ("Bonjour",100,50);
    Bouton2("Hello",50,200);
    Pourtant dans votre code, on recherche la string :
    De plus le caractère après l'ouverture de parenthèse est un guillemet ("), et dans split, une apostrophe est utilisée ('). Donc cela ne va pas fonctionner.

    J'imagine que le "PovSite" remplace "Bouton" ? enfin ce n'est pas très clair. De plus je ne pense pas que l'utilisation de la fonction "QStringList::split()" soit la meilleur approche dans ce cas. Même si cela doit être faisable.

    Peut être est-il possible de simplifer le format du fichier ?
    Ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Bouton, Bonjour, 100, 50
    Bouton, Hello, 50, 200
    etc...
    Voici une des solution possible, en utilisant QString::indexOf() (J'ai fait un petit programme test, il faudra l'adapter, mais je ne pense pas que cela pose problème):
    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
     
    QString filetxt = "Bouton1(\"Bonjour\", 100, 50);\nBouton2(\"Hello\", 50, 200);\n";
        QTextStream txtStream(&filetxt, QIODevice::ReadOnly);
     
     
        int lineCount = 0;
        QString argumentsStr;
        QStringList arguments;
        while(!txtStream.atEnd()){
     
              QString line = txtStream.readLine();
              qDebug() << "line " << lineCount << ": " << line;
     
              //On prend uniquement ce qui se trouve entre ()
              int start, stop;
              start = line.indexOf("(");
              stop = line.indexOf(")");
              if(start != -1 && stop != -1 && stop > start){
                   //on prend ce qui se trouve entre parenthèse
                  argumentsStr = line.mid(start, stop - start);
                  //On enlève les caractères non désirés ", ( , ) et espace
                  argumentsStr.remove("\"").remove("(").remove(")").remove(" ");
                  //On sépare les éléments
                  arguments = argumentsStr.split(",");
                  //On obtiens les 3 éléments (Il faut encore convertir les valeurs numériques avec QString::toInt())
                  if(arguments.size() >= 3){
                    qDebug() << "Button - name: " << arguments.at(0) << "  x: " << arguments.at(1) << "  y: " << arguments.at(2);
                  }
              } else {
                  //On passe à ligne suivante
                  //Affichage erreur si nécessaire
                  continue;
              }
              lineCount ++;
        }
    et voici ce que j'obtiens en sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    line  0 :  "Bouton1("Bonjour", 100, 50)"
    Button - name:  "Bonjour"   x:  "100"   y:  "50"
    line  1 :  "Bouton2("Hello", 50, 200)"
    Button - name:  "Hello"   x:  "50"   y:  "200"


    Une autre solution, plus efficace selon moi (c'est un avis personnel je ne prétends pas apporter la meilleure solution), serait d'utiliser les expression régulière, qui sont parfaites pour ce genre de cas. Je vais faire un deuxième post avec les expressions régulières pour ne pas que cela devienne confus.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Points : 421
    Points
    421
    Par défaut Autre solution : expressions régulières
    Voici une deuxième possibilité utilisant les expressions régulières. Je ne vais pas expliquer ici ce qu'est une expression régulière, on trouve plein de doc concernant ce "language" sur le net.


    Par exemple, voici l'expression régulière qui permet d'extraire les données du fichier text (selon format du fichier texte).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ^[\w\s]*?\("(\w*?)",[ ]*?(\d*?),[ ]*?(\d*?)\);$
    Ça à l'air barbare comme ça mais en fait c'est plutôt simple une fois que l'on connais la syntaxe.
    Par exemple pour celle ci-dessus, voici l'explication en détail :
    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
     
    ^           : Début de string. Pas forcément nécessaire, vu que 
                  l'on travail sur sur une seule ligne à la fois.
    [\w\s]*?    : un ou plusieurs (*?) caractères (\w) ou espace (\s)
                  le ? sert à indiquer que l'expression n'est pas "greedy" 
                  (gourmande) voir doc des expressions régulières
    \(          : Ouverture de la parenthèse (échappé avec \ car c'est un caractère 
                  utiliser dans les expression régulières pour indiquer le 
                  début d'un groupe de capture)
    "           : Caractère guillement
    (\w*?)      : Group de capture pour le nom du bouton, un ou plusieurs caractères. 
    "           : Caractère guillement. correspond à regExp.cap(1) dans le code. 
    ,[ ]*?      : Virgule, puis un ou plusieurs espaces (utiliser \s pour être plus générique)
    (\d*?)      : Groupe de capture pour la coordonée x, un ou plusieurs caractère(s) décimal(s)
                   correspond à regExp.cap(2) dans le code.   
    ,[ ]*?      : Virgule, puis un ou plusieurs espaces (utiliser \s pour être plus générique)
    (\d*?)      : Groupe de capture pour la coordonée y, un ou plusieurs caractère(s) décimal(s)
                  correspond à regExp.cap(3) dans le code. 
    \)          : Fermeture de la parenthèse
    ;           : point virgule
    $           : Fin de string. Lui aussi n'est pas nécessaire dans notre cas.

    Voici ce que cela donne avec QRegExp, class de Qt permettant d'utiliser les expressions régulières:
    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
     
    #include <QRegExp>
    ...
     
    int lineCount = 0;
        QRegExp regExp("^[\\w\\s]+\\(\"(\\w+)\",[ ]*(\\d+),[ ]*(\\d+)\\);$");
        regExp.setMinimal(true); //Remplace les ? de l'expression régulière originale
     
        while(!txtStream.atEnd()){
     
            QString line = txtStream.readLine();
            qDebug() << "line " << lineCount << ": " << line;
           //regExp.cap(0) contient la string complète qui est "matché"
            if(regExp.exactMatch(line) && regExp.captureCount() == 3){
                qDebug() << "Button: (QRegExp)";
                qDebug() << "Name: " << regExp.cap(1);
                qDebug() << "X: " << regExp.cap(2);
                qDebug() << "Y: " << regExp.cap(3);
            }
            lineCount ++;
        }
    Ce que j’obtiens en sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    line  0 :  "Bouton1("Bonjour", 100, 50);"
    Button: (QRegExp)
    Name:  "Bonjour"
    X:  "100"
    Y:  "50"
    line  1 :  "Bouton2("Hello", 50, 200);"
    Button: (QRegExp)
    Name:  "Hello"
    X:  "50"
    Y:  "200"
    Voici ce que cela donne avec QRegularExpression, nouvelle classe de apparue dans la version 5 de Qt ( je ne connais pas bien les différences entre les 2 classes mais je crois que QRegularExpression s'approche plus du fonctionnement "standard" des expressions régulière (Perl) alors que QRegExp est quelque peu différent, mais c'est à vérifier):
    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
     
    #include <QRegExp>
    ...
     
    int lineCount = 0;
        QRegularExpression regularExp("^[\\w\\s]*?\\(\"(\\w*?)\",[ ]*?(\\d*?),[ ]*?(\\d*?)\\);$");
     
        while(!txtStream.atEnd()){
     
            QRegularExpressionMatch match = regularExp.match(line);
            if(match.hasMatch()){
                qDebug() << "Button: (QRegularExpression)";
                qDebug() << "Name: " << match.captured(1);
                qDebug() << "X: " << match.captured(2);
                qDebug() << "Y: " << match.captured(3);
            }
     
            lineCount ++;
        }
    Ce que j'obitens en sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    line  0 :  "Bouton1("Bonjour", 100, 50);"
    Button: (QRegularExpression)
    Name:  "Bonjour"
    X:  "100"
    Y:  "50"
    line  1 :  "Bouton2("Hello", 50, 200);"
    Button: (QRegularExpression)
    Name:  "Hello"
    X:  "50"
    Y:  "200"
    Comme tu peux le voir cela réduit pas mal le code, et est surtout très puissant. De plus si le format change il n'est pas trop compliqué de s'adapter.

    Personnellement j'utilise quasiment systématiquement les expression régulières dans ce genre de cas. Je ne cherche bien entendu pas à te forcer à les utiliser dans ton cas, mais plutôt à te montrer une autre possibilité pour résoudre ton problème.

    Pour info j'utilise The Regulator afin de construire et tester les expressions régulière, par contre je crois qu'il n'est plus maintenu à jour, mais il en existe d'autre (Expresso par exemple).

    Voila j'espère que cela n'est pas trop confus et t'aidera.

  4. #4
    Membre du Club
    Femme Profil pro
    Apprentie Développeuse
    Inscrit en
    Février 2013
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Apprentie Développeuse
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2013
    Messages : 106
    Points : 44
    Points
    44
    Par défaut
    Merci de ta réponse !! ça m'a beaucoup éclairé mais j'ai changé le format de mon fichier de configuration

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 03/11/2009, 07h19
  2. récupérer une donnée entrée au clavier
    Par simouSQL dans le forum SQL
    Réponses: 7
    Dernier message: 26/06/2007, 14h50
  3. [RegEx] Récuperer une chaîne entre deux tags
    Par tixweb dans le forum Langage
    Réponses: 12
    Dernier message: 23/04/2007, 12h46
  4. [Tableaux] Extraire une chaîne entre des < et >
    Par DocCoinCoin dans le forum Langage
    Réponses: 4
    Dernier message: 02/11/2006, 14h54
  5. [OS Perso] Récupérer une chaîne de caractères
    Par log2n dans le forum Programmation d'OS
    Réponses: 31
    Dernier message: 14/02/2006, 13h56

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