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 :

Simplification de fonction


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 30
    Par défaut Simplification de fonction
    Bonjour à tous,
    j'utilise un afficheur et pour ce dernier j'ai plein de fonctions utiles pour me permettre d'afficher une liste déroulante, une liste à choix simples, choix multiples etc... Mon objectif est de réussir à simplifier ces fonctions, simplifier dans le sens : 'un code plus simple à relire et sur moins de ligne'.

    J'ai réalisé pas mal de modification mais j'ai l'intime conviction que mes fonctions utilisent des principes qui pourrait être réécrit sur beaucoup moins de ligne, comme par exemple ici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (currentSelect > 1) //si lelement nest pas le premier de la liste
                {
            buffer[0] = '[';
            if (state[currentSelect - 2]) //on verifie letat de lelement du dessus, currentSelect est incrementé donc
                // -2 signifie que l'on regarde l'etat de l'element de la liste avant lelement courant
                buffer[1] = '*';
            else
                buffer[1] = ' ';
            buffer[2] = ']';
            buffer[3] = ' ';
        strncpy((char *) &buffer[4], (char *) label[currentSelect - 2],
                    COLUMN_N - 4);
    où je met tout dans un buffer un par un, je trouve ça pas très propre et je suis quasi sur qu'il y a un autre moyen de le faire plus simplement mais je ne sais comment :/ !

    Voilà j'espère avoir été assez clair sur mes besoins ! Si vous avez des astuces de simplification pour mon code ci-dessous je suis preneur.

    Merci beaucoup d'avance pour votre temps et votre générosité ! A bientôt je l’espère !

    (Ci-dessous le code en brut où j'ai au maximum essayé de commenter, mais bien sur vous n'êtes pas obliger de tous regarder)

    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
    /**
     * @brief Display visible elements of a scrolling list
     *
     * @param[in]   label           Array with strings for all possible choices of the scrolling list
     * @param[in]   nbElem          Number of possible choices
     * @param[in]   currentSelect   The current selected index in the list
     */
    void displayScrollingListVisibleElements(const unsigned char * const label[],
            unsigned char nbElem, unsigned char currentSelect) {
        unsigned char buffer[COLUMN_N + 1];
        unsigned char length;
     
        if (currentSelect > 0) //si l'index de la liste est supérieur à 0
                { //cest que l'on nest pas au debut donc on affiche a la ligne 2
                  //lelement precedent car notre selection courante est a la ligne 3
            displayOled(2, label[currentSelect - 1]);
            if (currentSelect > 1)       //si notre ligne courante est superieur a 1
                //cest que il ya des menus a afficher au dessus
                addSymbol(2, 19, SYMBOL_UPARROW);//on ajoute donc le symbole fleche du haut
        } else
            //sinon si index[0] c'est quon est au debut du menu donc on le montre avec la ligne 2 vide
            clearOledLine(2);
     
        buffer[0] = SYMBOL_RIGHTARROW; //on place la fleche vers la droite dans le buffer[0]
        strncpy((char *) &buffer[1], (char *) label[currentSelect], COLUMN_N - 3); //on copie le menu a partir de buffer[1] jusqua la colonne 17
        length = (unsigned char) strlen((char *) buffer); //on place la longueur du buffer dans la var lenght
        buffer[length] = SYMBOL_LEFTARROW; //on ajoute une fleche vers la gauche au buffer equivalent a la longueur du menu plus la fleche vers la droite
        buffer[length + 1] = 0x00; //la colonne suivant vaut une case vide
        displayOled(3, buffer); //on affiche a la ligne 3 le buffer
     
        if (currentSelect < (nbElem - 1)) //si lelement courant est inferieur au nombre delem -1
                { //autrement dit si il y a encore un element derriere lelement courant
            displayOled(4, label[currentSelect + 1]); //on affiche a la ligne 4, lelement courant +1
            if (currentSelect < (nbElem - 2)) //si lelement courant est inferieur au nombre delem -2
                //autrement dit sil il y a encore deux elements derriere lelement courant
                addSymbol(4, 19, SYMBOL_DOWNARROW);     //on affiche fleche du bas
        } else
            //si il n'y a pas delement derriere lelement courant
            clearOledLine(4); //clear la ligne 4
    }
    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
    60
    61
    62
    63
    64
    65
    66
    /**
     * @brief Display a menu scrolling list
     *
     * @param[in]   title           Title of the menu
     * @param[in]   label           Array with strings for all possible choices of the scrolling list
     * @param[in]   nbElem          Number of possible choices
     * @param[in]   lastChoice      The last selected element to display the correct page
     *
     * @return <tt>MENU_TIMEOUT</tt> if there is a menu timeout, <tt>MENU_ESCAPE</tt> if the user escape the menu
     *        The number of currentSelect is return when the enter button is pressed
     */
    unsigned char scrollingList(const unsigned char * const title, const unsigned char * const label[],
                                                        unsigned char nbElem, unsigned char lastChoice) {
        unsigned char currentSelect = lastChoice;
        unsigned short timeOut = 0;
        unsigned char validChoice = FALSE;
     
        clearDisplay();                     // Clears display
        displayCenterLine(1, title);        //title on first line
     
        if (nbElem > 0)
            displayScrollingListVisibleElements(label, nbElem, currentSelect);
        waitAllButtonsRelases();
        while (timeOut < MENU_TIMEOUTVALUE && !validChoice) {
            switch (getButtonPress()) {
            case BUTTON_UP:                             //previous element in list
                timeOut = 0;
                if (nbElem > 0 && currentSelect > 0) {
                    currentSelect--;
                    displayScrollingListVisibleElements(label, nbElem, currentSelect);
                }
                softDelay(MENU_TOUCHDELAY);
                break;
            case BUTTON_DOWN:                           //next element in list
                timeOut = 0;
                if (nbElem > 0 && currentSelect < nbElem - 1) {
                    currentSelect++;
                    displayScrollingListVisibleElements(label, nbElem, currentSelect);
                }
                softDelay(MENU_TOUCHDELAY);
                break;
            case BUTTON_ENTER:                          //valid current choice
                if (nbElem > 0)
                    validChoice = TRUE;
                //currentSelect = MENU_VALID; //permet de revenir sur lelement courant quand on revient sur le menu
                break;
            case BUTTON_CLEAR:                          //escape menu
                validChoice = TRUE;
                currentSelect = MENU_ESCAPE; //permet de revenir sur lelement courant quand on revient sur le menu
                break;
            default:
                softDelay(20);
                timeOut++;
                break;
            }
    #ifdef WATCHDOG_IS_USED
            IWDG_ReloadCounter();
    #endif
        }
        clearDisplay();         // Clears display
     
        if (timeOut == MENU_TIMEOUTVALUE)
            return MENU_TIMEOUT;
        else
            return currentSelect;
    }
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    /**
     * @brief Display visible elements of a single or multiple choice list
     *
     * @param[in]   label           Array with strings for all possible choices of the list
     * @param[in]   state           Array with state for all possible choices of the list (<tt>TRUE</tt> for checked, <tt>FALSE</tt> otherwise)
     * @param[in]   nbElem          Number of possible choices
     * @param[in]   currentSelect   The current selected index in the list (starting at 1, 0 and <tt>nbElem</tt>+1 correspond to valid/cancel option)
     */
    void displaySingleOrMultipleChoiceListVisibleElements(const unsigned char * const label[],
                      unsigned char state[], unsigned char nbElem, unsigned char currentSelect) {
        unsigned char buffer[COLUMN_N + 1];
        unsigned char length;
     
        if (currentSelect > 1) //si lelement nest pas le premier de la liste
                {
            buffer[0] = '[';
            if (state[currentSelect - 2]) //on verifie letat de lelement du dessus, currentSelect est incrementé donc
                // -2 signifie que l'on regarde l'etat de l'element de la liste avant lelement courant
                buffer[1] = '*';
            else
                buffer[1] = ' ';
            buffer[2] = ']';
            buffer[3] = ' ';
            strncpy((char *) &buffer[4], (char *) label[currentSelect - 2],
                    COLUMN_N - 4);
            displayOled(2, buffer);
            addSymbol(2, 19, SYMBOL_UPARROW);
        } else if (currentSelect == 1) //si on est sur le premier element de la liste (currentSelect à 1)
            displayOled(2, STR_VALID_CANCEL[0]); //on ajoute a la ligne 2 VALIDER/ANNULER
        else
            clearOledLine(2); //si lelement courant est valider/annuler (donc curentSelect à 0) on clear la ligne 2
     
        buffer[0] = SYMBOL_RIGHTARROW;
        if (currentSelect == 0 || currentSelect == nbElem + 1) //si lelement courant est le premier ou le dernier : valider/annuler
            strncpy((char *) &buffer[1], (char *) STR_VALID_CANCEL[0],
                    COLUMN_N - 3);
        else {
            buffer[1] = '[';
            if (state[currentSelect - 1]) //element courant incrementé donc -1 permet de vérif l'état de lelement courant
                buffer[2] = '*';
            else
                buffer[2] = ' ';
            buffer[3] = ']';
            buffer[4] = ' ';
            strncpy((char *) &buffer[5], (char *) label[currentSelect - 1],
                    COLUMN_N - 7);
        }
        length = (unsigned char) strlen((char *) buffer);
        buffer[length] = SYMBOL_LEFTARROW;
        buffer[length + 1] = 0x00;
        displayOled(3, buffer);
     
        if (currentSelect < nbElem) //si lelement courant n'est pas le dernier de la liste
                {
            buffer[0] = '[';
            if (state[currentSelect])
                buffer[1] = '*';
            else
                buffer[1] = ' ';
            buffer[2] = ']';
            buffer[3] = ' ';
            strncpy((char *) &buffer[4], (char *) label[currentSelect],
                    COLUMN_N - 4);
            displayOled(4, buffer);
            addSymbol(4, 19, SYMBOL_DOWNARROW);
        } else if (currentSelect == nbElem) //si element courant est le dernier de la liste
            displayOled(4, STR_VALID_CANCEL[0]); //on affiche valider/quitter a la ligne 4
        else
            clearOledLine(4); //valider/annuler en element courant donc clear la ligne 4
    }
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    /**
     * @brief Display and process a multiple choices list
     *
     * @param[in]       title           Title of the menu
     * @param[in]       label           Array with strings for all possible choices of the list
     * @param[in]       nbElem          Number of possible choices (limited by <tt>MENU_MAXELEM</tt>)
     * @param[in,out]   values          For each element, TRUE to check, FALSE otherwise
     *
     * @return <tt>MENU_TIMEOUT</tt> if there is a menu timeout, <tt>MENU_ESCAPE</tt> if the user escape the menu
     *         or <tt>MENU_VALID</tt> if an IP address was read
     */
    unsigned char multipleChoicesList(const unsigned char * const title, const unsigned char * const label[],
                                        unsigned char nbElem,unsigned char *values) {
        unsigned char currentElement = 0;
        unsigned short timeOut = 0;
        unsigned char validChoice = FALSE;
        unsigned char returnValue = MENU_ESCAPE;
        unsigned char newValues[MENU_MAXELEM];
        unsigned char index;
     
        for (index = 0; index < nbElem; ++index)
            newValues[index] = values[index];
     
        clearDisplay();                                     //clear all screen
        displayCenterLine(1, title);                        //title on first line
     
        displaySingleOrMultipleChoiceListVisibleElements(label, newValues, nbElem,
                currentElement);
        waitAllButtonsRelases();
        while (timeOut < MENU_TIMEOUTVALUE && !validChoice) {
            switch (getButtonPress()) {
            case BUTTON_UP:                             //previous element in list
                timeOut = 0;
                if (currentElement > 0) //si lelement courant nest pas valider/annuler
                        {
                    currentElement--;
                    displaySingleOrMultipleChoiceListVisibleElements(label,
                            newValues, nbElem, currentElement);
                }
                softDelay(MENU_TOUCHDELAY);
                break;
            case BUTTON_DOWN:                           //next element in list
                timeOut = 0;
                if (currentElement < nbElem + 1) //si lelement courant nest pas valider/annuler
                        {
                    currentElement++;
                    displaySingleOrMultipleChoiceListVisibleElements(label,
                            newValues, nbElem, currentElement);
                }
                softDelay(MENU_TOUCHDELAY);
                break;
            case BUTTON_ENTER:
                if (currentElement == 0 || currentElement == nbElem + 1) //si lelement courant est valider/annuler
                {
                    validChoice = TRUE; // valid choice
                    uint8_t count = 0;
                    for (index = 0; index < nbElem; ++index) //on enregistre les valeurs true et false correspondant au cas
                    {   //coché du tableau newValues dans le tableau values
                        values[index] = newValues[index];
                        if (values[index] == FALSE)
                            count++;
                    }
                    if (nbElem == count) //si tous mes elements sont a faux (pas coché)
                        returnValue = MENU_NOCHOICE; //on réaffiche le menu config
                    else //sinon on a un ou des elements a vrai (coché)
                        returnValue = MENU_VALID;    //on affiche le menu suivant
     
                } else //si lelement courant est un champ du tableau
                {
                    newValues[currentElement - 1] = TRUE;       // add choice
                    displaySingleOrMultipleChoiceListVisibleElements(label,
                            newValues, nbElem, currentElement);
                }
                break;
            case BUTTON_CLEAR:
                if (currentElement == 0 || currentElement == nbElem + 1) {
                    validChoice = TRUE;                 // escape manu
                    returnValue = MENU_ESCAPE;
                } else {
                    newValues[currentElement - 1] = FALSE;      // remove choice
                    displaySingleOrMultipleChoiceListVisibleElements(label,
                            newValues, nbElem, currentElement);
                }
                break;
            default:
                softDelay(20);
                timeOut++;
                break;
            }
    #ifdef WATCHDOG_IS_USED
            IWDG_ReloadCounter();
    #endif
        }
        clearDisplay();                                     //clear all screen
     
        if (timeOut == MENU_TIMEOUTVALUE)
            return MENU_TIMEOUT;
        else
            return returnValue;
    }

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par LEROYLudovic Voir le message
    j'utilise un afficheur et pour ce dernier j'ai plein de fonctions utiles pour me permettre d'afficher une liste déroulante, une liste à choix simples, choix multiples etc... Mon objectif est de réussir à simplifier ces fonctions, simplifier dans le sens : 'un code plus simple à relire et sur moins de ligne'.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (currentSelect > 1) //si lelement nest pas le premier de la liste
               {
            buffer[0] = '[';
            if (state[currentSelect - 2]) //on verifie letat de lelement du dessus, currentSelect est incrementé donc
                // -2 signifie que l'on regarde l'etat de l'element de la liste avant lelement courant
                buffer[1] = '*';
            else
                buffer[1] = ' ';
            buffer[2] = ']';
            buffer[3] = ' ';
        strncpy((char *) &buffer[4], (char *) label[currentSelect - 2],
                    COLUMN_N - 4);
    Très louable objectif. Mais déjà un code lisible c'est au minimum un code correctement indenté. Dans le code ci-dessus tu ne fermes même pas ton premier "if"...


    Citation Envoyé par LEROYLudovic Voir le message
    où je met tout dans un buffer un par un, je trouve ça pas très propre et je suis quasi sur qu'il y a un autre moyen de le faire plus simplement mais je ne sais comment :/ !
    Ben peut-être via strcat, memcpy ou même sprint...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (currentSelect > 1) //si lelement nest pas le premier de la liste
    {
    	sprintf(buffer, "[%c] %.*s", state[currentSelect - 2] ?'*' :' ', COLUMN_N - 4, label[currentSelect - 2]);
    }

    Citation Envoyé par LEROYLudovic Voir le message
    (Ci-dessous le code en brut où j'ai au maximum essayé de commenter, mais bien sur vous n'êtes pas obliger de tous regarder)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        buffer[0] = SYMBOL_RIGHTARROW; //on place la fleche vers la droite dans le buffer[0]
        strncpy((char *) &buffer[1], (char *) label[currentSelect], COLUMN_N - 3); //on copie le menu a partir de buffer[1] jusqua la colonne 17
        length = (unsigned char) strlen((char *) buffer); //on place la longueur du buffer dans la var lenght
        // Question: peux-tu garantir que "buffer" est une chaine (c.a.d. qu'il contient bien un '\0') ??? Parce que sinon strlen() partira en torche
        buffer[length] = SYMBOL_LEFTARROW; //on ajoute une fleche vers la gauche au buffer equivalent a la longueur du menu plus la fleche vers la droite
        buffer[length + 1] = 0x00; //la colonne suivant vaut une case vide      Non !!! On positionne le flag "fin de chaine". Accessoirement on écrit plutôt '\0' pour plus de lisibilité mais c'est un détail
    Voir mes commentaires en rouge. Accessoirement évite de tout caster systématiquement. Laisse plutôt faire le cast implicite. Déjà 1) ça te cassera moins les c... 2) ça sera plus lisible 3) ça suivra automatiquement l'évolution des outils et 4) s'il y a un vrai souci tu le verras à la compilation (à ce sujet voir les multiples discussions sur "faut-il caster malloc", où certains arguments contre le cast peuvent s'appliquer ici).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 30
    Par défaut
    Bonjour, merci beaucoup dans un premier temps pour ta réponse et ton aide apportée !

    Pour le premier '}' oui j'ai oublié de le mettre ici mais il est bien présent

    Je souhaite donc utiliser sprintf comme tu me le montre ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	sprintf(buffer, "[%c] %.*s", state[currentSelect - 2] ?'*' :' ', COLUMN_N - 4, label[currentSelect - 2]);
    Je n'ai pas tout saisi le fonctionnement. (là tu va me dire RTFM mais je m'explique) D'abord je met dans mon buffer[*] ou [] selon l'état de state, ensuite j'ai les deux arguments que je ne comprend pas très bien :
    Si il y a deux arguments pourquoi je n'ai qu'un seul % après le [%c] ?
    COLUMN_N - 4 représente la taille possible ou je peut écrire et label[currentSelect - 2] le char que je doit écrire, mais aurai-je pu les inverser ? Car si l’on se réfère à int sprintf(char *str, const char *format, ...) , l'ordre n'est pas préciser.

    Et finalement je n'ai pas compris le %.*s (comment et pourquoi le deuxième % appel label[] et pas COLUMN_4 ?) :
    .* : The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. On fait ça sur une chaine de caractère, là encore je suis paumé x) J'ai essayé sans le . et à chaque passage dans le code mon élément se décale vers la droite.


    Sinon pour répondre à tes questions :
    // Question: peux-tu garantir que "buffer" est une chaine (c.a.d. qu'il contient bien un '\0') ??? Parce que sinon strlen() partira en torche
    buffer est déclaré comme ceci : unsigned char buffer[21], donc oui on peut garantir que c'est une chaine finissant par \0 si je ne me trompe pas :p !

    buffer[length + 1] = 0x00; //la colonne suivant vaut une case vide Non !!! On positionne le flag "fin de chaine". Accessoirement on écrit plutôt '\0' pour plus de lisibilité mais c'est un détail
    Dac merci je comprend beaucoup mieux maintenant !

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Effectivement, tout est dans la doc http://www.cplusplus.com/reference/cstdio/printf/
    printf("%.*s", 4, "une_super_longue_chaine"); sortira une_ puisqu'il y a le formattage de longueur de la chaîne, via paramètre ici puisque c'est * et non un chiffre.

    buffer est déclaré comme ceci : unsigned char buffer[21], donc oui on peut garantir que c'est une chaine finissant par \0 si je ne me trompe pas :p !
    Cette déclaration n'inclut en aucun cas un caractère de fin de chaîne, donc rien n'est garanti et si tu te trompes ici.

    Accessoirement on écrit plutôt '\0' pour plus de lisibilité mais c'est un détail
    '\0' == 0 == 0x00 == plein d'autres écritures.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 30
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Effectivement, tout est dans la doc http://www.cplusplus.com/reference/cstdio/printf/
    printf("%.*s", 4, "une super longue chaine"); sortira une puisqu'il y a le formattage de longueur de la chaîne, via paramètre ici puisque c'est * et non un chiffre.
    Ah oui d'accord je comprend mieux ! Merci. La précision n'est pas spécifiée dans la chaîne de format mais en tant qu'argument de valeur entière supplémentaire précédant l'argument devant être formaté.
    Cela répond à plusieurs de mes questions en même temps c'est parfait. Cependant il me reste une dernière question. La différence entre .* et * c'est la largeur et la précision mais quel est exactement cette différence pour sprintf ?
    La largeur c'est le nombre minimum que doit prendre ma chaine de caractère en taille et la précision c'est le nombre de chiffre après la virgule.
    printf("%4d", 123); ==> _123
    printf("%4d", 12345); ==> 12345
    printf("%f", 100.123); ==> 100.123000
    printf("%12f", 100.123); ==> __100.123000
    printf("%.2f", 100.123); ==> 100.12
    printf("%5.0f", 100.123); ==> __100
    printf("%10.3f", 100.123);==> ___100.123
    printf("%.4f", 1.23456); ==> 1.2346


    Mais quel est le lien avec mon COLUMN_N c'est une largeur que je veut pas une précision ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	sprintf(buffer, "[%c] %.*s", state[currentSelect - 2] ?'*' :' ', COLUMN_N - 4, label[currentSelect - 2]);
    Si j'inverse en mettant %*s au lieu de %.*s cela ne fonctionne plus et décale ma chaine a chaque déplacement sur mon afficheur.
    Pour résumé ma question est simple comment on peut déterminer dans cette situation qu'il faut utiliser la précision de mon label[] que je dois mettre dans mon buffer et non sa largeur ?

    Merci beaucoup

    Voici ma fonction qui me parait déjà bien plus propre
    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
     
     
    void displaySingleOrMultipleChoiceListVisibleElements(const unsigned char * const label[],
    		          unsigned char state[], unsigned char nbElem, unsigned char currentSelect) {
    	unsigned char buffer[COLUMN_N + 1];
    	unsigned char length;
     
    	if (currentSelect > 1) 
    	{
    		sprintf((char *)buffer, "[%c] %.*s", state[currentSelect - 2] ?'*' :' ', COLUMN_N - 4, label[currentSelect - 2]);
    		displayOled(2, buffer);
    		addSymbol(2, 19, SYMBOL_UPARROW);
    	} else if (currentSelect == 1) 
    		displayOled(2, STR_VALID_CANCEL[FRENCH]); 
    	else
    		clearOledLine(2); 
     
    	buffer[0] = SYMBOL_RIGHTARROW;
    	if (currentSelect == 0 || currentSelect == nbElem + 1) 
    		strncpy((char *) &buffer[1], (char *) STR_VALID_CANCEL[FRENCH], COLUMN_N - 3);
    	else {
    		sprintf((char *)buffer, "[%c] %.*s", state[currentSelect - 1] ?'*' :' ', COLUMN_N - 7, label[currentSelect - 1]);
    	}
    	length = (unsigned char) strlen((char *) buffer);
    	buffer[length] = SYMBOL_LEFTARROW;
    	buffer[length + 1] = '\0';
    	displayOled(3, buffer);
     
    	if (currentSelect < nbElem) 
    	{
    		sprintf((char *)buffer, "[%c] %.*s", state[currentSelect] ?'*' :' ', COLUMN_N - 4, label[currentSelect]);
    		displayOled(4, buffer);
    		addSymbol(4, 19, SYMBOL_DOWNARROW);
    	} else if (currentSelect == nbElem)
    		displayOled(4, STR_VALID_CANCEL[0]);
    	else
    		clearOledLine(4);
    }

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 851
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LEROYLudovic Voir le message
    Mais quel est le lien avec mon COLUMN_N c'est une largeur que je veut pas une précision ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	sprintf(buffer, "[%c] %.*s", state[currentSelect - 2] ?'*' :' ', COLUMN_N - 4, label[currentSelect - 2]);
    "." (point) signifie que tu veux une troncature (l'équivalent de strncpy). C'est donc bien une largeur. Et "*" signifie que la valeur n'est pas écrite en dur (comme quand on écrit par exemple "%.4s") mais proviendra d'une expression, expression indiquée donc dans les paramètres suivants de printf.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Simplification de fonction
    Par Quentin.vdv dans le forum VBScript
    Réponses: 1
    Dernier message: 08/02/2013, 09h26
  2. Dérivation et simplification de fonctions
    Par sunlover dans le forum Prolog
    Réponses: 1
    Dernier message: 07/12/2011, 22h48
  3. Simplification des fonctions de callback
    Par Gouhouf dans le forum Interfaces Graphiques
    Réponses: 7
    Dernier message: 02/05/2009, 11h32
  4. Simplification de fonction
    Par omman95 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 10/02/2008, 19h37
  5. Simplification de fonction logique - le famous tableau karnaugh
    Par tariq_qui dans le forum VB 6 et antérieur
    Réponses: 20
    Dernier message: 29/04/2007, 13h31

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