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 :

Déboger C rudimentaire


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut Déboger C rudimentaire
    Bonjour à tous, je débute le C. Je viens de créer mon propre déboger C et j’aurai aimé avoir vos avis sur mon code source

    Le voici.

    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
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
     
     
    main.h
    #include <stdio.h>
    #include <stdlib.h>
     
    /*******************************************************************************
     
    Programme de détection d'érreurs de syntaxe C rudimentaire.
        Controle:   les parenthèses, les crochets, les guillemets, les commentaires,
                    les apostrophes,les accolades et le point virgule a la fin des lignes.
     
    Ce programme retourne les érreurs a l'écran ex:
    "
        Ligne 13 erreur';'.
        2 erreur(s) trouvée(s).
    "
    Ce programme ne tolère pas de entré au millieu d'un for if ou else
     
    exemple:
        for(i = 0; memoireLigne[i] == '\t' || memoireLigne[i] == ' ' ||
             memoireLigne[i] == '\n' || memoireLigne[i] == '\0' ; i ++)
     
    Edité par Florian.
     
    *******************************************************************************/
     
    void pause(void);
     
    main.c
    #include "main.h"
    #include "debugger.h"
     
    int main(void)
    {
        FILE *codeSource = NULL;
     
        if((codeSource = fopen("Code Source.txt", "r")) == NULL)
        {
            fprintf(stderr, "Erreur Code Source.txt introuvable.\n");
            pause();
            return EXIT_FAILURE;
        }
        printf("\nIl y a %d erreur(s) dans ce code source.\n", nombre_Derreurs(codeSource));
     
        fclose(codeSource);
        return EXIT_SUCCESS;
     
    }
     
    void pause(void)
    {
        puts("Appuyer sur une touche pour continer...\n");
        getchar();
    }
     
    Debbuger .h
    #define DEDANS 1
    #define DEHORS 0
     
    #define TRUE 1
    #define FALSE 0
     
    //type d'erreurs
    enum    erreur{PARENTHESE = 2, CROCHET, GUILLEMET, APOSTROPHE, POINT_VIRGULE,
                POINT, MOT, LETTRE_H, FLECHE};
     
    #define TAILLE_MAX_LIGNE 1000
     
    int     nombre_Derreurs(FILE *cs);
     
    int     nombre_Pair(const int nb);
    int     recherche_Chaine_Dans_Chaine(const char chaineBase[], const char chaineA_Trouver[]);
     
    int     check_Ligne_Diese(const char t[], int *commentaireP);
    int     check_Ligne(const char t[], int *commentaire, FILE *cS, int *accolade, int *ligne);
    int     check_Ligne_Accolade(const char t[],int * commentaire);
    int     check_Point_Virgule(const char t[], FILE **cs, const int nbPV, int **commentaire);
     
    debugger .c
     
    #include "main.h"
    #include "debugger.h"
     
     
    int nombre_Derreurs(FILE *cs)//retourne le nombre d'érreurs trouvées
    {
        /*
            Retourne le nombre d'érreurs trouvées dans le code source.
            à chaque érreur, la ligne est indiquée et le type d'érreur
        */
        char memoireLigne[TAILLE_MAX_LIGNE] = "";
        int ligne = 0, nbErreur = 0, commentaire = DEHORS, kindErreur = TRUE, i = 0, accolade = 0;
     
        while(fgets(memoireLigne, TAILLE_MAX_LIGNE, cs) != NULL)
        {
            ligne ++;
     
            for(i = 0;memoireLigne[i] == '\t' || memoireLigne[i] == ' ' || memoireLigne[i] == '\n' ; i ++)//je place le curseur a la première lettre de la ligne et saute les entrés
                ;
     
            //verifie le genre de teste a faire
            if(memoireLigne[i] == '#')
                kindErreur = check_Ligne_Diese(memoireLigne, &commentaire);
            else if(!(memoireLigne[i] == '\t' || memoireLigne[i] == ' ' || memoireLigne[i] == '\n' || memoireLigne[i] == '\0'))
                kindErreur = check_Ligne(memoireLigne, &commentaire, cs, &accolade, &ligne);
     
            if(kindErreur != TRUE)
            {
                nbErreur ++;
     
                printf("Erreur ligne: %d,", ligne);
                if(kindErreur == FALSE)
                    printf("ligne invalide.\n");
                else if(kindErreur == FLECHE)
                    printf("'<' ou '>'.\n");
                else if(kindErreur == GUILLEMET)
                    printf("'\"'.\n");
                else if(kindErreur == POINT)
                    printf("'.'.\n");
                else if(kindErreur == MOT)
                    printf("nombre mot invalide.\n");
                else if(kindErreur == LETTRE_H)
                    printf("'h' abs apres '.'.\n");
                else if(kindErreur == APOSTROPHE)
                    printf("'''.\n");
                else if(kindErreur == PARENTHESE)
                    printf("'(' ou ')'.\n");
                else if(kindErreur == CROCHET)
                    printf("'[' ou ']'.\n");
                else if(kindErreur == POINT_VIRGULE)
                    printf("';'.\n");
     
                printf("%s", memoireLigne);
                kindErreur = TRUE;
            }
        }
     
        if(accolade == 0)
            return nbErreur;
        else
        {
            printf("Erreur '{' ou '}', dans le code source.\n");
            nbErreur ++;
            return nbErreur;
        }
     
    }
     
    int check_Ligne_Diese(const char t[], int *commentaire)//controle quand la ligne du code source commence par un #
    {
        int i = 0, guillemet, mot, point, curseur = DEDANS, signe = 0, com = (*commentaire);
     
        for(;t[i] == ' ' || t[i] == '\t'; i ++)//place le curseur a la première lettre de la ligne, ici le #.
            ;
     
        // intialise les variables en fonction de si c'est un défine ou un include
        if(recherche_Chaine_Dans_Chaine(t, "include"))//#include .....
        {
            guillemet = mot = 2;
            point = 1;
        }
        else
        {
            if(recherche_Chaine_Dans_Chaine(t, "define"))//#define .....
            {
                mot = 3;
                point = guillemet = 0;
            }
            else//Erreur
                return FALSE;
        }
     
        for(; t[i] != '\0'; i ++)//lit la chaine jusqu'a la fin
        {
        //cette partie controle si le curseur est dans un commentaire.
            if(t[i-1] == '/' && (t[i] == '/' || t[i] == '*'))//controle si le curseur est dans un commentaire
            {
                if(t[i] == '*')
                    (*commentaire) = DEDANS;//regle le pointeur si le commentaire est sur plusieur lignes
                if(t[i-2] != ' ')
                    mot --;
                com = DEDANS;
            }
     
            else if(t[i-1] == '*' && t[i] == '/')
                com = (*commentaire) = DEHORS;//sort du commentaire
     
        //controle les caractères si le curseur n'est pas dans un commentaire
            if((t[i] == '<' || t[i] == '"' || t[i] == '>') && com == DEHORS)//controle les guillemets ex '<' ou '>' ou '"'
            {
                if(t[i] == '"')
                    signe = GUILLEMET;
                else
                    signe = FLECHE;
                    guillemet --;
            }
     
     
            else if((t[i] == ' ' || t[i] == '\n')  && com == DEHORS)
            //controle le nombre de mot et dit si le curseur est dans un mot
            {
                mot --;
                curseur = DEHORS;
            }
            else if (((t[i] >= 'A' && t[i] <= 'Z') || (t[i] >= 'a' && t[i] <= 'z') || (t[i] >= '0' && t[i] <= '9')) && com == DEHORS)
                curseur = DEDANS;
     
     
            else if(t[i] == '.' && com == DEHORS)
            {
                point --;
                if(t[i+1] != 'h')
                    return LETTRE_H;
            }
     
        }
        if(guillemet == 0 && point == 0 && mot == 0)
            return TRUE;
        else
        {
            if(guillemet != 0)
            {
                if(signe == FLECHE)
                    return FLECHE;
                else
                    return GUILLEMET;
            }
     
            else if(point != 0)
                return POINT;
            else
                return MOT;
        }
    }
     
    int check_Ligne(const char t[], int *commentaire, FILE *cS, int *accolade, int *ligne)//controle les autres sortes de lignes
    {
        int parenthese = 0, crochet = 0, apostrophe = 0, guillemet = 0, pointVirgule = 0,
            dansApostrophe = DEHORS, com = (*commentaire), i = 0, finApostrophe =  -1, c = 0;
     
        for(;t[i] == ' ' || t[i] == '\t'; i ++)//place le curseur au debut des caractères
            ;
     
        for(;t[i] != '\0'; i ++)//boucle jusqu'a la fin de la chaine
        {
        //cette partie controle si le curseur est dans un commentaire.
            if(t[i-1] == '/' && (t[i] == '/' || t[i] == '*'))//controle si le curseur est dans un commentaire
            {
                if(t[i] == '*')
                    (*commentaire) = DEDANS;//regle le pointeur si le commentaire est sur plusieur lignes
                com = DEDANS;
            }
     
            else if(t[i-1] == '*' && t[i] == '/')
                com = (*commentaire) = DEHORS;//sort du commentaire
     
        //cette partie vérifie si le curseur est dans apostrophe.
            if(t[i] == '\'' && com == DEHORS)
            {
                //controle si le curseur est dans des apostrophes
                if(dansApostrophe == DEHORS)
                {
                    if(t[i+3] == '\'')
                        finApostrophe = i + 3;
                    else if(t[i+2] == '\'')
                        finApostrophe = i + 2;
                    else
                        return APOSTROPHE;
     
                    if(finApostrophe == i + 3)//controle si il y a que 1 seul caractère dans les apostrophes
                    {
                        if(t[i+1] != '\\')
                            return FALSE;
                    }
     
                    apostrophe ++;
                    dansApostrophe = DEDANS;
                }
                else if(i == finApostrophe)
                {
                    dansApostrophe = DEHORS;
                    apostrophe ++;
                }
     
     
            }
     
            else if(t[i] == '(' && dansApostrophe == DEHORS && com == DEHORS)
                parenthese ++;
            else if(t[i] == ')' && dansApostrophe == DEHORS && com == DEHORS)
                parenthese --;
            else if(t[i] == '[' && dansApostrophe == DEHORS && com == DEHORS)
                crochet ++;
            else if(t[i] == ']' && dansApostrophe == DEHORS && com == DEHORS)
                crochet --;
            else if(t[i] == '"' && dansApostrophe == DEHORS && com == DEHORS)
                guillemet ++;
            else if(t[i] == ';' && dansApostrophe == DEHORS && com == DEHORS)
                pointVirgule ++;
            else if(t[i] == '}' && dansApostrophe == DEHORS && com == DEHORS)
                (*accolade) --;
            else if(t[i] == '{' && dansApostrophe == DEHORS && com == DEHORS)
                (*accolade) ++;
     
            if(i > 0 && com == DEHORS &&(!(t[i] == ' ' || t[i] == '\t' || t[i] == '\n')))
                c = t[i];
     
        }
        if(parenthese != 0)
            return PARENTHESE;
        else if(crochet != 0)
            return CROCHET;
        else if(!(nombre_Pair(apostrophe)))
            return APOSTROPHE;
        else if(!(nombre_Pair(guillemet)))
            return GUILLEMET;
        else if(pointVirgule != 1 && com == DEHORS && c != '/')
            return check_Point_Virgule(t, &cS, pointVirgule, &commentaire);
        else
            return TRUE;
    }
     
    int recherche_Chaine_Dans_Chaine(const char chaineBase[], const char chaineA_Trouver[])
    {
    /*
        Je n'utilise pas strystr() car je dois passer les commentaires ;)
    */
        int i = 0, j = 0, trouve = FALSE, com = DEHORS;
     
        for(;chaineBase[i] != '\0'; i ++)
        {
            if((chaineBase[i - 1] == '/' && (chaineBase[i] == '/' || chaineBase[i] == '*')))
                com = DEDANS;
     
            else if(chaineBase[i - 1] == '*' && chaineBase[i] == '/')
                com = DEHORS;
     
            if((chaineA_Trouver[j] == chaineBase[i]) && com == DEHORS)
            {
                for(j = 0;chaineA_Trouver[j] == chaineBase[i] && (chaineA_Trouver[j] != '\0' || chaineBase[i] != '\0'); j ++, i ++)
                    ;
                if(chaineA_Trouver[j] == '\0')
                {
                    trouve = TRUE;
                    break;
                }
            }
        }
        if(trouve)
            return TRUE;
        else
            return FALSE;
    }
     
    int nombre_Pair(const int nb)
    {
        if((nb % 2) == 0)
            return TRUE;
        else
            return FALSE;
    }
     
    int check_Point_Virgule(const char t[], FILE **cs, const int nbPV, int **commentaire)
    {
        int find = FALSE, com = (**commentaire), i;
        char nextLigne[TAILLE_MAX_LIGNE] = "";
     
        if(nbPV == 0)
        {
            find = recherche_Chaine_Dans_Chaine(t, "while");
            if(find == FALSE)
            {
                find = recherche_Chaine_Dans_Chaine(t, "else");
                if(find == FALSE)
                {
                    find = recherche_Chaine_Dans_Chaine(t, "if");
                    if(find == FALSE)
                    {
                        find = recherche_Chaine_Dans_Chaine(t, "}");
                        if(find == FALSE)
                        find = recherche_Chaine_Dans_Chaine(t, "{");
                            if(find == FALSE)
                            {
                                fgets(nextLigne, TAILLE_MAX_LIGNE, *cs);
                                for(i = 0; nextLigne[i] != '\0'; i ++)//conte le nombre de caractère pour le décalage future
                                {
                                //cette partie controle si le curseur est dans un commentaire.
                                    if(nextLigne[i-1] == '/' && (nextLigne[i] == '/' || nextLigne[i] == '*'))//controle si le curseur est dans un commentaire
                                        com = DEDANS;
                                    else if(nextLigne[i-1] == '*' && nextLigne[i] == '/')
                                        com = DEHORS;//sort du commentaire
     
                                    else if(nextLigne[i] == '{'&& com == DEHORS)
                                        find = TRUE;
                                }
                                fseek(*cs,0 - (i + 1),SEEK_CUR);
                            }
                    }
                }
            }
        }
        else if(nbPV == 2)
            find = recherche_Chaine_Dans_Chaine(t, "for");
        else
            return POINT_VIRGULE;
     
        if(find == TRUE)
            return TRUE;
        else
            return POINT_VIRGULE;
    }
    Si vous voyez des erreurs dites le moi

    Merci de me consacrer du temps

  2. #2
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Je te conseille d'utiliser la signature complète du main et de passer le nom du programme à tester en paramètre, comme ceci:

    debugger.exe source_a_tester.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
    18
    19
    20
    21
    22
    23
    24
    25
    int main(int argc, char** argv)
    {
        FILE *codeSource = NULL;
     
        if(argc > 1)
        {
            codeSource = fopen(argv[1], "r");
            if(codeSource == NULL)
            {
                printf("Erreur d'ouverture de %s\n", argv[1]);
                return EXIT_FAILURE;
            }
            else
            {
                printf("\nIl y a %d erreur(s) dans ce code source.\n", nombre_Derreurs(codeSource));
                fclose(codeSource);
                return EXIT_SUCCESS;
            }
        }
        else
        {
            printf("nom de fichier a analyser manquant\n");
            return EXIT_FAILURE;
        }
    }
    Sinon, ce n'est pas un débogueur (qui permettrait de tester des .exe avec des point d'arrêts, des visualisations de variables etc..), plutôt un parseur, non? Tu as été plutôt chiche sur les explications de ce que fait ton programme. après avoir truffé un source d'erreur, il me l'a parsé en annonçant imperturbablement "0 erreur"'. j'ai parcouru le code rapidement, tes commentaires apportent une aide réelle. Tu as une série de else/if qui gagnerait à être remplacée par un switch/case et une machine d'état aiderait beaucoup pour structurer tout ça.

    A+

    Pfeuh

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Bonjour,
    Techniquement, ce n'est pas un débuggeur, mais un valideur syntaxique.

    Chouette projet pour un débutant. D'ailleurs, vu l'aspect du code, je dirai que tu n'es plus si débutant que ca.

    Je vais jeter un œil attentif à ton code.

    Mes premières suggestions pour continuer:
    • tu pourrais paramétriser le nom du fichier en utilisant les arguments de ligne de commande
    • j'aurais réparti pause() dans un util.h et util.c, plutot qu'un main.h et main.c. L'idée étant qu'ainsi, main() est dans le seul fichier sans .h attenant.
    • si tu ajouter TRUE et FALSE dans l'enumération erreur, tu pourras remplacer les else if(kindErreur == …) par un switch.


    fais attention, cependant, les noms de fichiers sont sensibles à la casse sur certains systèmes.

    edit: zut, doublé.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par leternel Voir le message
    L'idée étant qu'ainsi, main() est dans le seul fichier sans .h attenant.
    Oui, je l'avais écrit, aussi étant partisan de déclarer les variables dans le main.c... Mais je me suis auto-censuré, ayant eu peur que ce soit considéré comme du troll... Sinon, c'est vrai que l'aspect du code ne fait pas débutant.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut
    Déjà merci de vos réponses, ça me fait plaisir .

    Sisi, je suis toujours débutant lol, en programmes intéressant, j'ai codé un résolveur de sudoku, une IA de bataille navale, un snake console et un programme un peu bizarre qui affiche les mots écrits dans un fichier .txt de la sorte (voir en dessous) avec un nombre de mot variable en nombre et en longueur. Enfin voilà je suis débutant. (Si vous voulez les Codes sources pas de problèmes )

    4|
    3| *
    2| *
    1|_ *_
    M
    o
    i

    Maintenant me vient quelques questions.

    En premier, j’utilise Code Block pour debugger compiler… et j’aurai aimé savoir si il est possible de passer des arguments pour fonction int main (int argc, char **argv) Ce n’est pas très claire mon truc la…
    En gros, comment donner mon code source au pointeur de pointeur argv ?

    Ensuite, c’est quoi une machine d’état ?!

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    en gros, argv recoit la commande d'exécution.

    argv[0] est "le nom du programme", selon les systemes, soit le chemin complet, soit l'exacte commande tapée. soit "mon_prog", soit "../../mon_prog", soit "le/chemin/absolu/vers/mon_prog"

    les autres cases de argv contiennent les arguments, tels que interprété par la ligne de commande.

    Classiquement, la commande "mon_prog -f -d --super-option=2" donnera argv={ "mon_prog", "-f", -"d", "--super-option=2"}.
    Les EDI permet de définir ces "options de lignes d'exécutions", "paramètres d'exécution", ou autre variantes.

    Une machine à état est un objet mathématique/logique que tu peux/vas utiliser.

    En gros, c'est un ensemble d'états, dont un état inital, et un système de transitions.

    Imagine un jeu de l'oie.
    Les positions des joueurs sont les états.
    Les transitions sont les déplacements d'un joueur. Elles sont provoquées par le jet de dé et la transition effectuée est choisie fonction de la valeur du dé.


    Le fonctionnement classique en C est plus ou moins la suivante.
    Supposons une machine à état sensé reconnaitre la présence de la sous-chaine "un" dans l'entrée standard.

    tout d'abord, quelques utilitaires:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //une énumération d'états
    enum state_t {state_initial = 0, state_partial, state_final};
     
    //une fonction de événement, pour savoir quand faire la transition.
    char wait_transition_event(){
        //le type et le code de cette fonction dépend de la situation. (SDL, socket, CLI, GUI?)
        //ici, une simple lecture au clavier
        return getc();
    }
    Et une boucle principale (parfois appelée boucle d'événements)
    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
    int run_state_machine(){
        enum state_t state=state_inital;
        char event;
        while ( (event=wait_transition_event())!=EOF) {
            switch (state) {
                case state_initial:
                    if(event='u') {
                        state=state_partial;
                    }
                    break;
     
                case state_partial:
                    switch(event) {
                        case 'u': break;
                        case 'n': state=state_final; break;
                        default: state=state_initial; break;
                    }
                    break;
     
                case state_final:
                    break;
            }
        }
        return (state==state_final);
    }
    Une autre variante, c'est d'avoir des fonctions pour chaque état, respectant la signature enum state_t traitement(int event); et de finalement avoir une machine codée par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        switch (state) {
                case state_initial: etat = traitement_initial(event); break;
                case state_partial: etat = traitement_partial(event); break;
                case state_final: etat = traitement_final(event); break;
    }
    Pour plus d'informations, wikipédia contient des articles sur les machines à états.

    En théorie, on définit les machines à états avec des fonctions à exécuter à l'entrée des états, à la sorte des états, et pendant chaque transition possible.

    Une machine à état permet de garder une information (construite) pendant une boucle linéaire (parcours d'une liste ou lecture, en général)

    Pour ta culture scientifique, il existe des variantes nommées "machine à pile", et "transducteur", chacune apportant des possibilitées supplémentaires.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par Dev 37C Voir le message
    En premier, j’utilise Code Block pour debugger compiler… et j’aurai aimé savoir si il est possible de passer des arguments pour fonction int main (int argc, char **argv)
    Dans le menu "project" l'option "Set program's arguments".

    Citation Envoyé par Dev 37C Voir le message
    c’est quoi une machine d’état ?!
    C'est ça: une grosse boucle infinie avec un switch à l'intérieur qui fait des traitements dépendants de l'état actuel... Leternel m'a grillé sur ce coup là, il décrit très bien une machine d'états.
    A+

    Pfeuh

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut
    Ah ouai, c'est top les arguments de main . Je ne m’en étais jamais servi. Désolé, je vais être un peu lourd mais l'autre argument "argc" il prend quoi comme valeur ? Ah aussi, comment je suis sûr que l’argument envoyé dans « argv » est bien un fichier .txt et pas autre chose ? Car si j’ai bien compris, j’envoie ce que je veux c’est ça ?

    Je vais maintenant me pencher sur les machines d'états. J'ai lu en diagonal, et jai sérieusement rien compris

    Je vais aussi faire un switch, même si je ne comprends pas pourquoi tout le monde préfère cette méthode
    Un grand merci à vous pheuf et leternel

  9. #9
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par Dev 37C Voir le message
    l'autre argument "argc" il prend quoi comme valeur ? Ah aussi, comment je suis sûr que l’argument envoyé dans « argv » est bien un fichier .txt et pas autre chose ?
    argc est le nombre d'arguments. argv est un pointeur vers un tableau de pointeurs vers des chaines. Le premier élement de argv, donc argv[0] pointe toujours sur le nom du programme

    Citation Envoyé par Dev 37C Voir le message
    comment je suis sûr que l’argument envoyé dans « argv » est bien un fichier .txt et pas autre chose ?
    Ce n'est pas un fichier mais un nom de fichier. Pour être sûr, il suffit de l'ouvrir et de voir si le FILE* retourné est différent de NULL

    Citation Envoyé par Dev 37C Voir le message
    Je vais aussi faire un switch, même si je ne comprends pas pourquoi tout le monde préfère cette méthode
    Alors je crois qu'il vaut mieux essayer de comprendre la machine d'états que d'en coder une parce que les autres font comme ça. Une machine d'états doit répondre à certaines règles qui sont abondamment décrites sur le web. C'est une question de robustesse et de lisibilité. Si dans ta boucle principale il y a une suite de if/else et plusieurs flags, même toi tu ne pourras plus le comprendre dans quelques jours.

    A+

    Pfeuh

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut
    Voici mes modifications:

    - contrôle a présenté les boucles switch

    - les suites de if else if... ont été modifiées

    - l'argument contrôlé est à présent argv[1]

    Je n'ai pas fait de machine d'état, je ne comprends pas son fonctionnement

    Vraiment merci à pfeuh et a leternel pour toutes ces remarques tres constructive

    Juste si un jour leternel tu as 5 min, je veux bien que tu me modifies mon code source avec une machine d'état. en privé, que je sois sur de le voir

    Voici le code complet
    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
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    main.c#include "util.h"
    #include "debugger.h"
     
    int main(int argc, char** argv)
    {
        FILE *codeSource = NULL;
     
        if(argc > 1)
        {
            if((codeSource = fopen(argv[1], "r")) == NULL)
            {
                fprintf(stderr, "Erreur Code Source.txt introuvable.\n");
                pause();
                return EXIT_FAILURE;
            }
            printf("\nIl y a %d erreur(s) : dans ce code source.\n", nombre_Derreurs(codeSource));
     
            fclose(codeSource);
            pause();
            return EXIT_SUCCESS;
        }
        else
        {
            printf("Nom de fichier a analyser manquant\n");
            pause();
            return EXIT_FAILURE;
        }
    }util.h#include <stdio.h>
    #include <stdlib.h>
     
    /*******************************************************************************
     
    Programme de détection d'érreurs de syntaxe C rudimentaire.
        Controle:   les parenthèses, les crochets, les guillemets, les commentaires,
                    les apostrophes,les accolades, les 2 points dans les lignes case et le point virgule a la fin des lignes.
     
    Ce programme retourne les érreurs a l'écran ex:
    "
        Ligne 13 erreur';'."%s" ligne avec erreur
     
        2 erreur(s) trouvée(s) dans le code source.
    "
    Ce programme ne tolère pas:
     
    _entré au millieu d'un for if ou else...
     
        exemple:
            for(i = 0; memoireLigne[i] == '\t' || memoireLigne[i] == ' ' ||
                memoireLigne[i] == '\n' || memoireLigne[i] == '\0' ; i ++)
     
    _ Imbrication de ligne
     
        exemple:
            case '(': parenthese ++; break;
     
     
    Edité par Florian.
     
    *******************************************************************************/
     
    void pause(void);util.c#include "util.h"
     
    void pause(void)
    {
        puts("Appuyer sur une touche pour continer...\n");
        getchar();
    }debugger.h#include <ctype.h>
    #define DEDANS 1
    #define DEHORS 0
     
    #define TRUE 1
    #define FALSE 0
     
    //type d'erreurs
    enum    erreur{PARENTHESE = 2, CROCHET, GUILLEMET, APOSTROPHE, POINT_VIRGULE,
                POINT, MOT, LETTRE_H, FLECHE, POINT_2_POINT};
     
    #define TAILLE_MAX_LIGNE 1000
     
    int     nombre_Derreurs(FILE *cs);
     
    int     nombre_Pair(const int nb);
    int     recherche_Chaine_Dans_Chaine(const char chaineBase[], const char chaineA_Trouver[]);
     
    int     check_Ligne_Diese(const char t[], int *commentaireP);
    int     check_Ligne(const char t[], int *commentaire, FILE *cS, int *accolade, int *ligne);
    int     check_Ligne_Accolade(const char t[],int * commentaire);
    int     check_Point_Virgule(const char t[], FILE **cs, const int nbPV, int **commentaire);debugger.c#include "util.h"
    #include "debugger.h"
     
     
    int nombre_Derreurs(FILE *cs)//retourne le nombre d'érreurs trouvées
    {
        /*
            Retourne le nombre d'érreurs trouvées dans le code source.
            à chaque érreur, la ligne est indiquée et le type d'érreur
        */
        char memoireLigne[TAILLE_MAX_LIGNE] = "";
        int ligne = 0, nbErreur = 0, commentaire = DEHORS, kindErreur = TRUE, i = 0, accolade = 0;
     
        while(fgets(memoireLigne, TAILLE_MAX_LIGNE, cs) != NULL)
        {
            ligne ++;
     
            for(i = 0;memoireLigne[i] == '\t' || memoireLigne[i] == ' ' || memoireLigne[i] == '\n' ; i ++)//je place le curseur a la première lettre de la ligne et saute les entrés
                ;
     
            //verifie le genre de teste a faire
            if(memoireLigne[i] == '#')
                kindErreur = check_Ligne_Diese(memoireLigne, &commentaire);
            else if(!(memoireLigne[i] == '\t' || memoireLigne[i] == ' ' || memoireLigne[i] == '\n' || memoireLigne[i] == '\0'))
                kindErreur = check_Ligne(memoireLigne, &commentaire, cs, &accolade, &ligne);
     
            if(kindErreur != TRUE)
            {
                nbErreur ++;
                printf("Erreur ligne: %d,", ligne);
     
                switch(kindErreur)
                {
                    case FALSE: printf("ligne invalide.\n"); break;
                    case FLECHE: printf("'<' ou '>'.\n"); break;
                    case GUILLEMET: printf("'\"'.\n"); break;
                    case POINT: printf("'.'.\n"); break;
                    case MOT: printf("nombre mot invalie.\n"); break;
                    case LETTRE_H: printf("'h' abs apres '.'.\n"); break;
                    case APOSTROPHE: printf("'''.\n"); break;
                    case PARENTHESE: printf("'(' ou ')'.\n"); break;
                    case CROCHET: printf("'[' ou ']'.\n"); break;
                    case POINT_2_POINT: printf("':'.\n"); break;
                    case POINT_VIRGULE: printf("';'.\n"); break;
                }
     
                printf("%s", memoireLigne);
                kindErreur = TRUE;
            }
        }
     
        if(accolade == 0)
            return nbErreur;
        else
        {
            printf("Erreur '{' ou '}', dans le code source.\n");
            nbErreur ++;
            return nbErreur;
        }
     
    }
     
    int check_Ligne_Diese(const char t[], int *commentaire)//controle quand la ligne du code source commence par un #
    {
        int i = 0, guillemet, mot, point, curseur = DEDANS, signe = 0, com = (*commentaire);
     
        for(;t[i] == ' ' || t[i] == '\t'; i ++)//place le curseur a la première lettre de la ligne, ici le #.
            ;
     
        // intialise les variables en fonction de si c'est un défine ou un include
        if(recherche_Chaine_Dans_Chaine(t, "include"))//#include .....
        {
            guillemet = mot = 2;
            point = 1;
        }
        else
        {
            if(recherche_Chaine_Dans_Chaine(t, "define"))//#define .....
            {
                mot = 3;
                point = guillemet = 0;
            }
            else//Erreur
                return FALSE;
        }
     
        for(; t[i] != '\0'; i ++)//lit la chaine jusqu'a la fin
        {
        //cette partie controle si le curseur est dans un commentaire.
            if(t[i-1] == '/' && (t[i] == '/' || t[i] == '*'))//controle si le curseur est dans un commentaire
            {
                if(t[i] == '*')
                    (*commentaire) = DEDANS;//regle le pointeur si le commentaire est sur plusieur lignes
                if(t[i-2] != ' ')
                    mot --;
                com = DEDANS;
            }
     
            else if(t[i-1] == '*' && t[i] == '/')
                com = (*commentaire) = DEHORS;//sort du commentaire
     
        //controle les caractères si le curseur n'est pas dans un commentaire
            if((t[i] == '<' || t[i] == '"' || t[i] == '>') && com == DEHORS)//controle les guillemets ex '<' ou '>' ou '"'
            {
                if(t[i] == '"')
                    signe = GUILLEMET;
                else
                    signe = FLECHE;
                    guillemet --;
            }
     
     
            else if((t[i] == ' ' || t[i] == '\n')  && com == DEHORS)
            //controle le nombre de mot et dit si le curseur est dans un mot
            {
                mot --;
                curseur = DEHORS;
            }
            else if (isalnum(t[i]) && com == DEHORS)
                curseur = DEDANS;
     
     
            else if(t[i] == '.' && com == DEHORS)
            {
                point --;
                if(t[i+1] != 'h')
                    return LETTRE_H;
            }
     
        }
        if(guillemet == 0 && point == 0 && mot == 0)
            return TRUE;
        else
        {
            if(guillemet != 0)
            {
                if(signe == FLECHE)
                    return FLECHE;
                else
                    return GUILLEMET;
            }
     
            else if(point != 0)
                return POINT;
            else
                return MOT;
        }
    }
     
    int check_Ligne(const char t[], int *commentaire, FILE *cS, int *accolade, int *ligne)//controle les autres sortes de lignes
    {
        int parenthese = 0, crochet = 0, apostrophe = 0, guillemet = 0, pointVirgule = 0, ligneCase = 0,
            dansApostrophe = DEHORS, com = (*commentaire), i = 0, finApostrophe =  -1, c = 0;
     
        for(;t[i] == ' ' || t[i] == '\t'; i ++)//place le curseur au debut des caractères
            ;
     
        for(;t[i] != '\0'; i ++)//boucle jusqu'a la fin de la chaine
        {
        //cette partie controle si le curseur est dans un commentaire.
            if(t[i-1] == '/' && (t[i] == '/' || t[i] == '*'))//controle si le curseur est dans un commentaire
            {
                if(t[i] == '*')
                    (*commentaire) = DEDANS;//regle le pointeur si le commentaire est sur plusieur lignes
                com = DEDANS;
            }
     
            else if(t[i-1] == '*' && t[i] == '/')
                com = (*commentaire) = DEHORS;//sort du commentaire
     
        //cette partie vérifie si le curseur est dans apostrophe.
            if(t[i] == '\'' && com == DEHORS)
            {
                //controle si le curseur est dans des apostrophes
                if(dansApostrophe == DEHORS)
                {
                    if(t[i+3] == '\'')
                        finApostrophe = i + 3;
                    else if(t[i+2] == '\'')
                        finApostrophe = i + 2;
                    else
                        return APOSTROPHE;
     
                    if(finApostrophe == i + 3)//controle si il y a que 1 seul caractère dans les apostrophes
                    {
                        if(t[i+1] != '\\')
                            return FALSE;
                    }
     
                    apostrophe ++;
                    dansApostrophe = DEDANS;
                }
                else if(i == finApostrophe)
                {
                    dansApostrophe = DEHORS;
                    apostrophe ++;
                }
            }
     
            if(dansApostrophe == DEHORS && com == DEHORS)
            {
                switch(t[i])
                {
                    case '(': parenthese ++; break;
                    case ')': parenthese --; break;
                    case '[': crochet ++; break;
                    case ']': crochet --; break;
                    case '"': apostrophe ++; break;
                    case ';': pointVirgule ++; break;
                    case '{': (*accolade) ++; break;
                    case '}': (*accolade) --; break;
                    case ':':
                        if(recherche_Chaine_Dans_Chaine(t, "case"))
                            ligneCase = 1;
                    break;
     
                }
                c = t[i];
            }
        }
        if(parenthese != 0)
            return PARENTHESE;
        else if(crochet != 0)
            return CROCHET;
        else if(!(nombre_Pair(apostrophe)))
            return APOSTROPHE;
        else if(!(nombre_Pair(guillemet)))
            return GUILLEMET;
        else if(pointVirgule != 1 && com == DEHORS && c != '/' && ligneCase != 1)//gère aussi les ':' manquand aux lignes avec "case"
            return check_Point_Virgule(t, &cS, pointVirgule, &commentaire);
        else
            return TRUE;
    }
     
    int recherche_Chaine_Dans_Chaine(const char chaineBase[], const char chaineA_Trouver[])
    {
    /*
        Je n'utilise pas strystr() car je dois passer les commentaires ;)
    */
        int i = 0, j = 0, trouve = FALSE, com = DEHORS;
     
        for(;chaineBase[i] != '\0'; i ++)
        {
            if((chaineBase[i - 1] == '/' && (chaineBase[i] == '/' || chaineBase[i] == '*')))
                com = DEDANS;
     
            else if(chaineBase[i - 1] == '*' && chaineBase[i] == '/')
                com = DEHORS;
     
            if((chaineA_Trouver[j] == chaineBase[i]) && com == DEHORS)
            {
                for(j = 0;chaineA_Trouver[j] == chaineBase[i] && (chaineA_Trouver[j] != '\0' || chaineBase[i] != '\0'); j ++, i ++)
                    ;
                if(chaineA_Trouver[j] == '\0')
                {
                    trouve = TRUE;
                    break;
                }
            }
        }
        if(trouve)
            return TRUE;
        else
            return FALSE;
    }
     
    int nombre_Pair(const int nb)
    {
        if((nb % 2) == 0)
            return TRUE;
        else
            return FALSE;
    }
     
    int check_Point_Virgule(const char t[], FILE **cs, const int nbPV, int **commentaire)
    {
        int find = FALSE, com = (**commentaire), i;
        char nextLigne[TAILLE_MAX_LIGNE] = "";
     
        if(nbPV == 0)
        {
            find = recherche_Chaine_Dans_Chaine(t, "while");
            if(find == FALSE)
            {
                find = recherche_Chaine_Dans_Chaine(t, "else");
                if(find == FALSE)
                {
                    find = recherche_Chaine_Dans_Chaine(t, "if");
                    if(find == FALSE)
                    {
                        find = recherche_Chaine_Dans_Chaine(t, "switch");
                        if(find == FALSE)
                        {
                            find = recherche_Chaine_Dans_Chaine(t, "case");
                            if(find == TRUE)
                            {
                                find = recherche_Chaine_Dans_Chaine(t, ":");
                                if(find != TRUE)
                                    return POINT_2_POINT;//si une ligne case n'a pas de ':'
                            }
                            if(find == FALSE)
                            {
                            find = recherche_Chaine_Dans_Chaine(t, "*/");
                                if(find == FALSE)
                                {
                                    find = recherche_Chaine_Dans_Chaine(t, "}");
                                    if(find == FALSE)
                                    find = recherche_Chaine_Dans_Chaine(t, "{");
                                        if(find == FALSE)
                                        {
                                            fgets(nextLigne, TAILLE_MAX_LIGNE, *cs);
                                            for(i = 0; nextLigne[i] != '\0'; i ++)//conte le nombre de caractère pour le décalage future
                                            {
                                            //cette partie controle si le curseur est dans un commentaire.
                                                if(nextLigne[i-1] == '/' && (nextLigne[i] == '/' || nextLigne[i] == '*'))//controle si le curseur est dans un commentaire
                                                    com = DEDANS;
                                                else if(nextLigne[i-1] == '*' && nextLigne[i] == '/')
                                                    com = DEHORS;//sort du commentaire
     
                                                else if(nextLigne[i] == '{'&& com == DEHORS)
                                                    find = TRUE;
                                            }
                                            fseek(*cs,0 - (i + 1),SEEK_CUR);
                                        }
                                }
                            }
                        }
                    }
                }
            }
        }
        else if(nbPV == 2)
            find = recherche_Chaine_Dans_Chaine(t, "for");
        else
            return POINT_VIRGULE;
     
        if(find == TRUE)
            return TRUE;
        else
            return POINT_VIRGULE;
    }

  11. #11
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par Dev 37C Voir le message
    Je n'ai pas fait de machine d'état, je ne comprends pas son fonctionnement
    Ce n'est vraiment pas compliqué. Par contre, il faut savoir exactement ce que tu veux faire. Si je me réfère à ce qu'il y a dans tes commentaires:
    Controle: les parenthèses, les crochets, les guillemets, les commentaires,
    les apostrophes,les accolades, les 2 points dans les lignes case et le point virgule a la fin des lignes.
    Avant de vouloir coder la machine, il faudrait définir ce qu'il faut faire. Par exemple les commentaires. A un moment donné, tu vas être dans l'état "DANS_LE_COMMENTAIRE". Dans cet état, ce qu'il faut faire c'est tout ignorer jusqu'à trouver "*/" qui est la fin de commentaire. Quand tu l'as trouvé, tu passes à l'état "NORMAL". Si tu arrives à la fin du fichier et que tu es dans l'état "DANS_LE_COMMENTAIRE", c'est qu'il manque la fin de commentaire "*/", il faut générer une erreur. De même, si dans dans l'état "DANS_LE_COMMENTAIRE" tu trouves "/*", c'est un commentaire dans un commentaire, c'est une erreur aussi. Et là, tu te rends rapidement compte qu'on ne peut pas aisément travailler par caractère, mais qu'il faut travailler par avec un tableau de mots... Pire que ça, il faudrait que ce soit récursif, par exemple pour tester
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getValue(textToFloat(words[index], &myfloat))
    on passe par l'état "ENTRE_PARENTHESES", on rentre ensuite dans un 2ème état "ENTRE_PARENTHESES", mais en se rappelant d'où on vient, on va ensuite dans l'état "ENTRE_CROCHETS" mais en se rappelant les 2 états précedents...

  12. #12
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    En fait, tu va avoir plusieurs machines à états parallèles, dont quelques unes à pile.

    Il faut en effet surveiller:
    • les directives préprocesseur (# ... \n)
    • les imbrications de parentheses
    • les imbrications de crochets
    • les imbrications de guillemets et d'apostrophes
    • les suites d'instructions (enchainement de ;, présence de return?)

    Et certaines de ces choses sont dépendantes entre elles.
    En conséquence, j'ai entamé un projet personnel: recoder cpp, le préprocesseur de GCC.

    Je vais cependant voir pour reformuler ton code en machine à états, mais je le posterai ici, en t'envoyant un mp pour te le signaler.


    Pour les petites remarques
    En général, on préfère return ((nb % 2) == 0) ? TRUE : FALSE; à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if ((nb % 2) == 0)
            return TRUE;
        else
            return FALSE;
    Pour une recherche, plutot qu'une boucle avec if (...) { trouve=TRUE; break;} suivi d'un return, on ferait directement le return dans le if, et un return false inconditionnel.

    Utilise plus d'accolades, surtout dans les chaines de "else if"

    On ne place pas les includes requis par une fonction dans son .h mais dans son .c, cela permet de ne pas faire les inclusions partout, réduisant ainsi les temps de compilation.

    Dans l'absolu, la pause n'est pas une bonne idée, il suffit de régler ton EDI pour que la console ne soit pas fermée immédiatement après la fin du programme.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  13. #13
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    En fait, ton programme semble bon, mais il est incapable de valider certains programmes, tels que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define MAX(a,b) ( ( (a) < (b)) ? (b) : (a) )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    printf("%s: %s %s",
            tag,
            content
            value,
    );

    Ton code demande trop de reconstructions, et contient quelques erreurs, je n'arriverai pas à le convertir à une machine à états.
    • il manque une accolade fermante dans check_Point_Virgule
    • au niveau des lignes 100 de debugger.c, il faut peut-être une paire d'accolade autour du else
    • ton code contient des commentaires, c'est bien. mais chacun disant ce que fait un bout de code, ce devrait être autant de fonctions
    • il te manque des commentaire décrivant la logique du traitement (en terme de données)


    Si tu comptes retravailler le tout, il faut entre autre utiliser une analyse dite en ligne, ou tu lis caractere par caractere.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  14. #14
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Par ailleurs, il existe des programmes qui font ce que tu veux. L'un des exemples est cpplint
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  15. #15
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par leternel Voir le message
    Par ailleurs, il existe des programmes qui font ce que tu veux. L'un des exemples est cpplint
    Mais c'est du python!

    A+

    Pfeuh

  16. #16
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Sinon, tu peux regarder du coté de cpp lui-même. Quoi de plus efficace que le préprocesseur du C pour valider du C?
    Avant la version 4.7 de GCC, je pense qu'il était (encore) codé en C.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

Discussions similaires

  1. Solution pour site web rudimentaire
    Par halina dans le forum Débuter
    Réponses: 3
    Dernier message: 18/08/2011, 09h40
  2. Impossible de déboger un projet ASP.Net sous VS 2005
    Par Maren00 dans le forum Visual Studio
    Réponses: 2
    Dernier message: 07/05/2009, 00h10
  3. Compilation rudimentaire à la volée
    Par bohlinger dans le forum Assembleur
    Réponses: 9
    Dernier message: 03/05/2006, 12h11
  4. qq' expl. rudimentaires de CreateFile ?
    Par JuanLopez1966 dans le forum Windows
    Réponses: 5
    Dernier message: 07/09/2004, 11h06

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