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

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut Ouverture d'un fichier .h et actualisation d'un QLineEdit
    Bonsoir à tous,

    Dans le cadre d'un projet, j'aimerais ouvrir un fichier .h, récupérer un mot/caractère via une expression régulière et si c'est le cas actualiser le QLineEdit correspondant par le mot récupéré.

    Exemple :

    Si dans mon fichier j'ai une ligne : " Salut je m'appelle Toto"
    Je veux ouvrir mon fichier, récupérer le mot : Toto et afficher dans la zone de saisie de mon interface (qui s'intitule "Nom :" ) Toto.

    Je suis débutant en C++, j'ai tenté plusieurs choses 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
    void FenPrincipale::ouvrirFichier()
    {
        QString fichier = QFileDialog::getOpenFileName(this,"Ouvrir",QString(),".../test(*.txt)");
     
        bool valid  = QFile::exists(".../test.txt");
        QString code;
     
        //if(valid == true)
        //{
            QString fileName = "fichier.txt";
            QFile fichier1(fileName);
            fichier1.open(QIODevice::ReadOnly | QIODevice::Text);
            QTextStream flux(&fichier);
     
            QString ligne;
            while(!flux.atEnd())
            {
                ligne = flux.readLine(); //traitement de la ligne
                QRegularExpressionMatch *match=new QRegularExpressionMatch;
                QRegularExpression re("class[ \t]+(?<name>\\w+)([ \t]*:[ \t]*public[ \t]+(?<nameParent>\\w+))?");
                QMessageBox::information(this,"",fichier);
                if(ligne.contains(re, match))
                {
                    QStringList stringList = ligne.split(" ");
                    nom->setText(stringList[1]);
                    //nom->insert(stringList[1]);
                    this->update();
                    printf(" Ca a marché !");
     
                    //QString className = match.captured("name");
                    //QString classeMere = match->captured("nameParent");
                }
     
                this->update();
            }
    Merci d'avance et bonne soirée à tous.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    25 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : mai 2008
    Messages : 25 655
    Points : 200 564
    Points
    200 564
    Billets dans le blog
    80
    Par défaut
    Bonjour,

    Si vous avez la main sur le projet dans lequel est inclut le fichier .h, je vous propose de faire autrement en extrayant le nom de ce fichier, en le mettant en tant que define dans un fichier .h dédié.
    Comme ça, la lecture du fichier sera beaucoup plus simple.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Bonsoir LittleWhite,

    Je vais t'expliquer ce que je cherche à faire, ca sera plus simple pour tout le monde

    J'ai une interface de ce type :

    Nom : Capture.PNG
Affichages : 51
Taille : 11,0 Ko

    Le but de cette interface est de générer un texte dans une nouvelle fenêtre en fonction des choix et des données entrées.

    Exemple :
    Nom : Capture1.PNG
Affichages : 51
Taille : 29,6 Ko

    Pour l'instant l'interface fonctionne bien.
    J'arrive à sauvegarder le texte de la nouvelle fenêtre dans un fichier .h sur mon ordinateur (avec un bouton sauvegarder que j'ai créée).

    Mon problème c'est que maintenant je souhaite :
    - Réaliser l'étape inverse, c'est à dire qu'en partant d'un fichier texte lambda je souhaite qu'avec des expressions régulières le programme soit capable de remplir les zones de saisies de mon interface.

    Exemple :
    Nom : exemple.png
Affichages : 54
Taille : 139,3 Ko

    Voilà un exemple de ce que je souhaite obtenir en partant du fichier .h pour aboutir à un remplissage automatique de l'interface.

    Je souhaite ouvrir (à l'aide du bouton "ouvrir" ) le fichier .h fruit_salad et utiliser un bouton "remplissage automatique" (par exemple) afin que les champs de saisies et les cases à cocher de mon interface s'actualisent en fonction du contenu du fichier chargé.

    Sais tu comment je pourrais m'y prendre ? J'ai vu qu'il fallait utiliser les expressions régulières mais je suis totalement perdu au niveau du fonctionnement !

    Bonne soirée à toi et à tous les lecteurs !

    matmaat.

  4. #4
    Modérateur

    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 10 718
    Points : 65 254
    Points
    65 254
    Par défaut
    Bonsoir,

    Pour commencer, si tu veux pouvoir ouvrir des fichiers d'extension .h, alors il te faut donner le bon filtre à la fonction statique getOpenFileName() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    QString fichier = QFileDialog::getOpenFileName(this, "Ouvrir", QString(), "Headers (*.h)");
                                                                                        ~~~
    À noter que l'utilisateur peut choisir d'annuler cette ouverture, auquel cas le QString retourné sera nul. Il est donc judicieux de tester ce cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (fichier.isNull()) {
        return; // On quitte de suite la fonction sans rien faire d'autre
    }
    Ensuite, (c'est peut-être lié à un test que tu as fait, mais je préfère m'en assurer) QString fileName = "fichier.txt"; n'a aucun lien avec le fichier sélectionné ci-dessus. Il s'agit littéralement d'un fichier très précisément nommé fichier.txt que tu vas tenter d'ouvrir à la place de celui sélectionné à l'aide de la boîte de dialogue.

    QTextStream flux(&fichier); : (possiblement une confusion due aux deux variables fichier et fichier1 aux noms proches mais désignant deux choses distinctes) là encore ça ne va pas faire ce que tu attends. Au lieu de travailler sur le contenu du fichier sélectionné, tu vas simplement travailler sur son chemin.

    while(!flux.atEnd()) fait partie des erreurs classiques : il ne faut pas tester si on est ou non arrivé à la fin, mais si la lecture s'est bien passée. La version Qt 5.5 a apporté la fonction readLineInto() qui permet d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (flux.readLineInto(&ligne)) {
    QRegularExpressionMatch *match=new QRegularExpressionMatch; : allocation inutile et qui mène à une fuite mémoire qui plus est (à chaque itération, tu ne le deletes jamais). Contente-toi de créer une variable locale et de passer son adresse.

    Enfin, tu crées des groupes de capture nommés dans ton expression régulière, je vois cette partie censée les récupérer commentée et tu pars sur un split… il est dommage de ne pas t'en servir.

    Le tout corrigé nous donne :

    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
    void FenPrincipale::ouvrirFichier()
    {
        const QString chemin = QFileDialog::getOpenFileName(this, "Ouvrir", QString(), "Headers (*.h)");
        if (chemin.isNull()) { // Si l'utilisateur a annulé l'ouverture
            return;
        }
     
        QFile fichier(chemin); // On passe directement le chemin retourné par getOpenFileName()
        fichier.open(QIODevice::ReadOnly | QIODevice::Text);
        QTextStream flux(&fichier); // C'est le QFile qu'il faut passer, pas le chemin
     
        // C'est plutôt couteux à créer, évitons de le recréer inutilement à chaque itération
        const QRegularExpression re("class[ \t]+(?<name>\\w+)([ \t]*:[ \t]*public[ \t]+(?<nameParent>\\w+))?");
     
        QString ligne;
        while (flux.readLineInto(&ligne)) {
            QRegularExpressionMatch match;
            if(ligne.contains(re, &match)) {
                const QString className = match.captured("name");
                const QString classeMere = match.captured("nameParent");
     
                nom->setText(className);
                if (!classeMere.isNull()) {
                    // Présence d'héritage d'une classe mère
                    // je te laisse le mettre dans le bon champ
                }
     
                this->update();
                return; // Si tu n'as rien d'autre à récupérer, inutile de continuer le parcours
            }
        }
    }
    Avant de poser votre question : FAQ, Tutoriels et recherche sur le forum
    Une erreur ? Messages d'erreur et avertissements
    "Ça ne marche pas" n'apporte aucune information utile permettant de vous aider. Expliquez clairement votre problème (erreurs entières, résultat souhaité vs obtenu...).
    En essayant continuellement on finit par réussir. Donc: plus ça rate, plus on a de chance que ça marche. - Jacques Rouxel
    L'expérience, c'est le nom que chacun donne à ses erreurs - Oscar Wilde
    Mes extensions FireDVP (Firefox), ChroDVP (Chrome) : suivi des nouveaux messages, boutons/raccourcis et bien plus !

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Bonjour Winjerome !

    Merci pour ta réponse, ca m'a grandement aidé et j'ai pu nettement améliorer mon code !
    J'ai un petit problème qui persiste dans mon code, j'aimerais parcourir mon fichier texte ligne par ligne (comme tu m'as aidé à le faire) et en plus de ca tester plusieurs conditions.

    Exemple :
    Lorsque je parcours mon fichier texte si certaines expression sont identifiées mon interface s'actualise par exemple, si un mot est présent après le mot class le mot en question apparaitra dans la zone de saisie Nom : de mon interface, etc...

    Le problème c'est que mon code s'arrete apès avoir lu la première ligne de mon fichier texte et donc, il ne vérifie qu'une seule condition... Je pense qu'il ne nécessite que quelques ajustements mais je suis un peu perdu !
    Je mets mon code ci-dessous pour plus de clarté !
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    void FenPrincipale::ouvrirFichier()
    {
        const QString chemin = QFileDialog::getOpenFileName(this, "Ouvrir", QString(), "Headers (*.h)");
        if (chemin.isNull()) { // Si l'utilisateur a annulé l'ouverture
            return;
        }
     
        QFile fichier(chemin); // On passe directement le chemin retourné par getOpenFileName()
        fichier.open(QIODevice::ReadOnly | QIODevice::Text);
        QTextStream flux(&fichier); // C'est le QFile qu'il faut passer, pas le chemin
     
        // C'est plutôt couteux à créer, évitons de le recréer inutilement à chaque itération
        const QRegularExpression re("class[ \t]+(?<name>\\w+)([ \t]*:[ \t]*public[ \t]+(?<nameParent>\\w+))?");
        const QRegularExpression header("#ifndef");
        const QRegularExpression defaultconstructor("<name>()");
        const QRegularExpression defaultdestructor("~<name>()");
        QString ligne;
        while (!flux.atEnd()) //flux.readLineInto(&ligne)
        {
            QRegularExpressionMatch match;
            ligne = flux.readLine();
            if(ligne.contains(re, &match))
            {
                const QString className = match.captured("name");
                const QString classMere = match.captured("nameParent");
     
                //if (!classMere.isNull()) {
                    // Présence d'héritage d'une classe mère
                    // je te laisse le mettre dans le bon champ
                //}
     
                this->update();
                nom->setText(className);
                classeMere->setText(classMere);
                return; // Si tu n'as rien d'autre à récupérer, inutile de continuer le parcours
            }
     
            else if(ligne.contains(header, &match))
            {
                this->update();
                protections->setChecked(1);
                return; // Si tu n'as rien d'autre à récupérer, inutile de continuer le parcours
            }
     
            else if(ligne.contains(defaultconstructor, &match))
            {
                this->update();
                genererConstructeur->setChecked(1);
                return; // Si tu n'as rien d'autre à récupérer, inutile de continuer le parcours
            }
     
            else if(ligne.contains(defaultdestructor, &match))
            {
                this->update();
                genererDestructeur->setChecked(1);
                return; // Si tu n'as rien d'autre à récupérer, inutile de continuer le parcours
            }
        }
    Merci d'avance pour votre aide à tous et bonnes fêtes à tous !

    Matmaat.

  6. #6
    Modérateur

    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 10 718
    Points : 65 254
    Points
    65 254
    Par défaut
    Tu n'as pas dû bien lire le commentaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return; // Si tu n'as rien d'autre à récupérer, inutile de continuer le parcours
    Là, tu as bien autre chose à récupérer (tu as plusieurs conditions) alors il ne faut justement pas le mettre. Car son effet est justement de quitter directement la fonction sans continuer la lecture et la vérification des lignes suivantes.

    Plutôt que d'exécuter this->update(); sur chaque condition, tu peux te contenter de l'exécuter une seule fois après la boucle.

    const QRegularExpression header("#ifndef"); : ici un simple QString suffit.

    Par contre tes deux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        const QRegularExpression defaultconstructor("<name>()");
        const QRegularExpression defaultdestructor("~<name>()");
    ne vont pas fonctionner. Avec, tu vas littéralement rechercher <name> et ~<name>. Et note qu'il te faut échapper les () en \(\). (Après je pourrais t'embêter en te disant qu'un constructeur par défaut peut aussi avoir des paramètres avec des valeurs par défaut. Par ex. QWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())).

    L'expression régulière utilisée jusque là, c'est précisément (?<nomDonnéAuGroupe>expression) qui va servir à trouver l'expression et la récupérer par le biais du nom donné. Mais là le <name> ne va pas se transformer tout seul en nom de la classe className trouvée. Il va falloir le faire toi-même au moment où tu le trouves.
    Avant de poser votre question : FAQ, Tutoriels et recherche sur le forum
    Une erreur ? Messages d'erreur et avertissements
    "Ça ne marche pas" n'apporte aucune information utile permettant de vous aider. Expliquez clairement votre problème (erreurs entières, résultat souhaité vs obtenu...).
    En essayant continuellement on finit par réussir. Donc: plus ça rate, plus on a de chance que ça marche. - Jacques Rouxel
    L'expérience, c'est le nom que chacun donne à ses erreurs - Oscar Wilde
    Mes extensions FireDVP (Firefox), ChroDVP (Chrome) : suivi des nouveaux messages, boutons/raccourcis et bien plus !

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Salut Winjerome,

    Oui en effet j'avais mal lu ton commentaire

    J'ai retravaillé mon code d'après tes instructions (ci-dessous pour exemple )et il marche déjà beaucoup mieux merci !

    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
    44
    45
    46
    47
    48
    49
    50
    51
     
    void FenPrincipale::ouvrirFichier()
    {
        const QString chemin = QFileDialog::getOpenFileName(this, "Ouvrir", QString(), "Headers (*.h)");
        if (chemin.isNull()) { // Si l'utilisateur a annulé l'ouverture
            return;
        }
     
        QFile fichier(chemin); // On passe directement le chemin retourné par getOpenFileName()
        fichier.open(QIODevice::ReadOnly | QIODevice::Text);
        QTextStream flux(&fichier); // C'est le QFile qu'il faut passer, pas le chemin
     
        // C'est plutôt couteux à créer, évitons de le recréer inutilement à chaque itération
        const QRegularExpression re("class[ \t]+(?<name>\\w+)([ \t]*:[ \t]*public[ \t]+(?<nameParent>\\w+))?");
        const QRegularExpression header("#ifndef");
        const QRegularExpression defaultconstructor("(?<name>\\w+)()");
        const QRegularExpression defaultdestructor("(?<name>\\w+) + /( + /)");
        QString ligne;
        while (!flux.atEnd()) //flux.readLineInto(&ligne)
        {
            QRegularExpressionMatch match;
            ligne = flux.readLine();
     
            if(ligne.contains(re, &match))
            {
                const QString className = match.captured("name");
                const QString classMere = match.captured("nameParent");
     
                nom->setText(className);
                classeMere->setText(classMere);
     
            }
     
            else if(ligne.contains(header, &match))
            {
                protections->setChecked(1);
            }
     
            else if(ligne.contains(defaultconstructor, &match))
            {
                genererConstructeur->setChecked(1);
            }
     
            else if(ligne.contains(defaultdestructor, &match))
            {
                genererDestructeur->setChecked(1);
            }
        }
        this->update();
        return;
    }
    J'ai encore un détail qui m'embête ! Je ne trouve pas comment symboliser ce caractère : ~..... J'ai essayé avec /S puisqu'il semble que cette expression prenne en compte n'importe quel caractère qui n'est pas blanc mais ca ne fonctionne pas Aurais tu une idée ?

    Le principe est de cocher une case si le code détecte une expression du type : "/S + (?<name>\\w+) + /( + /)" ce qui donne : ~NomDeLaClasse().

    Je ne vois vraiment pas comment m'en sortir avec le symbole ~, même en regardant sur plusieurs sites et sur la documentation je ne vois rien de particulièrement adapté (ou alors je programme mal ce qui est tout à fait possible aussi !).

    Merci beaucoup pour le temps que tu prends afin de m'aider !

    Bonnes fêtes,

    Matmaat.

  8. #8
    Modérateur

    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 10 718
    Points : 65 254
    Points
    65 254
    Par défaut
    Alors attention, pour l'échappement, ce sont des backslashs \ et non des slashs /.
    Citation Envoyé par matmaat Voir le message
    J'ai encore un détail qui m'embête ! Je ne trouve pas comment symboliser ce caractère : ~...
    Tu veux plutôt parler de son absence, non ? Pour cela, tu peux utiliser [^~] (= tout sauf ~).
    Sinon \\w+ est déjà mieux, mais… si on a une fonction membre : void foo(); ?

    N'hésite pas à effectuer tes tests sur les expressions régulières sur ce site, il inclut un très bon mémento des expressions régulières en bas à droite.

    Bonne fêtes à toi également .
    Avant de poser votre question : FAQ, Tutoriels et recherche sur le forum
    Une erreur ? Messages d'erreur et avertissements
    "Ça ne marche pas" n'apporte aucune information utile permettant de vous aider. Expliquez clairement votre problème (erreurs entières, résultat souhaité vs obtenu...).
    En essayant continuellement on finit par réussir. Donc: plus ça rate, plus on a de chance que ça marche. - Jacques Rouxel
    L'expérience, c'est le nom que chacun donne à ses erreurs - Oscar Wilde
    Mes extensions FireDVP (Firefox), ChroDVP (Chrome) : suivi des nouveaux messages, boutons/raccourcis et bien plus !

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Salut Winjerome,

    Merci pour tes explications ! J'ai bien retravaillé les expressions régulières depuis ton message et j'ai pu dissiper beaucoup de zones d'ombres ! Avec tes explications j'ai pu corriger ce qui n'allait pas merci à toi !
    Je suis confronté à un problème depuis hier sur lequel je m'arrache littéralement les cheveux..

    Je souhaite récupérer grâce à une expression régulière une date dans un fichier que j'ouvre depuis mon interface. La date se présente de cette manière : Date de création : 25/12/20

    Donc le fonctionnement que je souhaite obtenir est celui décrit ci-dessous :
    - La date de départ de mon interface est la date du jour soit le : 27/12/2020
    - Si l'expression régulière détecte une date dans le fichier que j'ouvre correspondant au format que j'ai décrit plus haut, elle est censée actualisée la date de mon interface.

    Je te mets ci dessous mon code :
    - Mon expression régulière est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const QRegularExpression dateComments("Date de cr.ation : ([0-9]{2}/[0-9]{2}/[0-9]{4})");
    - Mon code est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    QString capturedDate = match.captured("([0-9]{2}/[0-9]{2}/[0-9]{4})"); //(\\d[0-3]\\d[0-9]/\\d[0-1]\\d[0-2])/\\d[0-2]\\d[0-9])\\d[0-9])\\d[0-9])
    QDate actualizedDate = QDate::fromString(capturedDate, "dd/MM/yyyy");
    date->setDate(actualizedDate);
    Comme tu peux t'en douter, il ne fonctionne pas.. Lorsque j'ouvre mon fichier la date affichée dans mon interface est toujours la date du jour.
    Je souhaiterais surtout comprendre pourquoi mon code ne fonctionne pas afin d'éviter de reposter un message à chaque fois (sachant qu'avant chaque message posté je fais des recherches et je décortique plusieurs sites sans succès).

    Afin de résoudre le problème, j'ai d'abord vérifier que le programme entrait dans la conditiond if dans laquelle les lignes de mon code sont écrites (avec un printf) et c'est le cas.
    Le soucis c'est qu'ensuite j'ai essayé d'afficher actualizedDate qui est censée stocker la date que le programme a détectée dans mon fichier mais sans succès étant donné que je pars d'un type QDtae vers un type String...

    Je te mets quand même mes pistes :

    Piste 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    QString datee = actualizedDate.toString("dd/MM/yyyy");
    printf("La date capturée est la suivante :",datee);
    Erreur :
    error: cannot pass object of non-trivial type 'QString' through variadic function; call will abort at runtime (elle concerne la variable datee dans le printf).

    Piste 2 :
    Je ne comprends pas pourquoi ce que je fais ne fonctionne pas et ca me frustre pas mal au fur et à mesure


    Merci d'avance pour ton temps je te souhaite de bonnes fêtes !

    Matmaat.

  10. #10
    Modérateur

    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 10 718
    Points : 65 254
    Points
    65 254
    Par défaut
    Ton soucis vient de la partie match.captured("([0-9]{2}/[0-9]{2}/[0-9]{4})").
    Il ne faut pas confondre le nom que l'on peut (éventuellement) donner à un groupe de capture et l'expression qui le compose.
    L'entrée de la fonction membre capture() correspond au nom que l'on donne dans (?<nomDonnéAuGroupe>expression).

    Mais ce n'est pas la seule façon de récupérer un groupe (constitué avec des parenthèses (...)). La fonction membre capture() possède une autre surcharge qui prend un int et qui permet de récupérer un groupe à partir de son indice (0 pour l'expression entière, 1 pour le premier groupe de l'expression, 2 pour le deuxième groupe, etc.).
    Avec ton expression :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const QRegularExpression dateComments("Date de cr.ation : ([0-9]{2}/[0-9]{2}/[0-9]{4})");
    tu peux récupérer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    match.capture(0) // "Date de création : 27/12/2020"
    match.capture(1) // "27/12/2020"
    En ce qui concerne l'affichage avec printf, tourne-toi plutôt vers qDebug().
    printf n'accepte qu'un nombre limité de types primitifs, chacun ayant son format %… (cf. le tableau de la documentation). Mais ça reste possible avec la macro qPrintable() qui facilite la conversion QString => const char * :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("La date capturée est la suivante : %s\n", qPrintable(datee));
    Avant de poser votre question : FAQ, Tutoriels et recherche sur le forum
    Une erreur ? Messages d'erreur et avertissements
    "Ça ne marche pas" n'apporte aucune information utile permettant de vous aider. Expliquez clairement votre problème (erreurs entières, résultat souhaité vs obtenu...).
    En essayant continuellement on finit par réussir. Donc: plus ça rate, plus on a de chance que ça marche. - Jacques Rouxel
    L'expérience, c'est le nom que chacun donne à ses erreurs - Oscar Wilde
    Mes extensions FireDVP (Firefox), ChroDVP (Chrome) : suivi des nouveaux messages, boutons/raccourcis et bien plus !

  11. #11
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Salut Winjerome,

    Merci pour ta réponse ! Je ne connaissais pas ce fonctionnement de groupe avec les expressions régulières, c'est beaucoup plus clair grâce à toi !!

    Ma date de création ne s'actualise pas lorsque j'ouvre mon fichier et je ne vois pas pourquoi, as tu une idée ?

    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
     
    if(ligne.contains(groupComments, &match))
            {
                printf("Le programme est bien entré dans la boucle qui m'intéresse !");
                groupCommentaires->setChecked(1);
                const QString comments = match.captured("author");
                auteur->setText(comments);
     
                if(ligne.contains(dateComments, &match))
                {
                    QString capturedDate = match.captured(1);
                    QDate actualizedDate = QDate::fromString(capturedDate, "dd/MM/yy");
                    date->setDate(actualizedDate);
                    QString datee = actualizedDate.toString("dd/MM/yy");
                    printf("La date capturée est la suivante : %s",qPrintable(datee));
                }
            }
        }
    Mon code (avec tes ajustements) me semble correct mais j'ai l'impression que date->setDate(actualizedDate); ne me permets pas d'actualiser la "valeur" de la date. Une fonction précédée de "set" permet pourtant bien de modifier la valeur considérée (ici ma date) non ?

    Merci d'avance,

    Matmaat.

  12. #12
    Modérateur

    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 10 718
    Points : 65 254
    Points
    65 254
    Par défaut
    Ton expression dateComments est-elle incluse dans groupComments ? L'auteur et la date sont-ils sur la même ligne ?
    Si ce n'est pas le cas, ton if(ligne.contains(dateComments, &match)) ne devrait pas être à l'intérieur mais au même niveau.
    Avant de poser votre question : FAQ, Tutoriels et recherche sur le forum
    Une erreur ? Messages d'erreur et avertissements
    "Ça ne marche pas" n'apporte aucune information utile permettant de vous aider. Expliquez clairement votre problème (erreurs entières, résultat souhaité vs obtenu...).
    En essayant continuellement on finit par réussir. Donc: plus ça rate, plus on a de chance que ça marche. - Jacques Rouxel
    L'expérience, c'est le nom que chacun donne à ses erreurs - Oscar Wilde
    Mes extensions FireDVP (Firefox), ChroDVP (Chrome) : suivi des nouveaux messages, boutons/raccourcis et bien plus !

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Salut Winjerome,

    Pour que la date de création soit accessible, il faut que la case "Ajouter des commentaires" soit cochée comme tu peux le voir ci-dessous :
    Nom : Interface.PNG
Affichages : 37
Taille : 9,4 Ko
    J'ai donc pensé qu'il fallait d'abord que groupComments soit détecté pour qu'ensuite dateComments soit détectée.

  14. #14
    Modérateur

    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    10 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 10 718
    Points : 65 254
    Points
    65 254
    Par défaut
    Certes, mais cette détection ne se fait pas sur la même ligne du fichier. Pour arriver dans ton if imbriqué il te faudra matcher les deux groupComments ET dateComments à la fois sur une seule et même ligne.

    On pourrait aussi s'interroger sur l'ordre des lignes ou encore s'il n'y en a qu'une…

    Tu peux par exemple utiliser un flag qui s'activera dès qu'on rencontrera une de ces lignes. Puis à la fin du parcours, on vérifiera sa valeur pour activer ou non la zone de commentaires.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    bool hasComments = false;
    while (...)
    {
        ...
        if (ligne.contains(groupComments, &match)) {
            ...
            hasComments = true;
        } else if (ligne.contains(dateComments, &match)) {
            ...
            hasComments = true;
        }
    }
     
    groupCommentaires->setChecked(hasComments);
    Avant de poser votre question : FAQ, Tutoriels et recherche sur le forum
    Une erreur ? Messages d'erreur et avertissements
    "Ça ne marche pas" n'apporte aucune information utile permettant de vous aider. Expliquez clairement votre problème (erreurs entières, résultat souhaité vs obtenu...).
    En essayant continuellement on finit par réussir. Donc: plus ça rate, plus on a de chance que ça marche. - Jacques Rouxel
    L'expérience, c'est le nom que chacun donne à ses erreurs - Oscar Wilde
    Mes extensions FireDVP (Firefox), ChroDVP (Chrome) : suivi des nouveaux messages, boutons/raccourcis et bien plus !

  15. #15
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2020
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2020
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Si j'ai bien compris ton message le code ressemblerait à quelque chose comme ca ?
    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
     
    const QRegularExpression groupComments("Auteur : (?<author>\\w+)"); //Auteur : //Date de cr.ation
    const QRegularExpression dateComments("Date de cr.ation : ([0-9]{2}/[0-9]{2}/[0-9]{2})");
    QString ligne;
    bool hasComments = false;
    ....
    ....
    ....
    if(ligne.contains(groupComments, &match))
    {            
           const QString comments = match.captured("author");
           auteur->setText(comments);
           hasComments = true;
    }
     
    if(ligne.contains(dateComments, &match))
    {
           QString capturedDate = match.captured(1);
           QDate actualizedDate = QDate::fromString(capturedDate, "dd/MM/yy");
           date->setDate(actualizedDate);
           QString datee = actualizedDate.toString("dd/MM/yy");
           printf("La date capturée est la suivante : %s",qPrintable(datee));
           hasComments = true;
    }
     
    if(hasComments == true)
    {
           groupCommentaires->setChecked(1);
    }
    La date ne s'actualise toujours pas malgré ce fonctionnement, elle reste fixée à la date du jour.

  16. #16
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2020
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : décembre 2020
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Bonsoir à tous,

    Moi aussi je suis tombé sur la même problématique avec la date en utilisant les expressions régulières.
    J'ai modifié mon code avec vos indications mais le résultat n'est pas concluant
    Toute réponse m'aidant à remplir la date dans mon interface depuis un fichier .h est la bienvenue.

    Bonne soirée à tous.

Discussions similaires

  1. Ouverture d'un fichier excel predefini
    Par nberthonneau dans le forum Access
    Réponses: 10
    Dernier message: 13/06/2007, 23h14
  2. [Système] ouverture d'un fichier pdf
    Par joneil dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 17/05/2005, 11h36
  3. Réponses: 2
    Dernier message: 06/04/2005, 13h01
  4. Réponses: 5
    Dernier message: 27/07/2004, 18h04
  5. Réponses: 2
    Dernier message: 22/07/2002, 13h13

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