Partage
  • Partager sur Facebook
  • Partager sur Twitter

zIdentificator

Exercice de niveau intermédiaire

    18 juin 2010 à 11:30:49

    Voici ce que j'ai produit dans le train entre Paris et Nantes... :p

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    static char const *keywords[] =
    {
            "auto",
            "break",
            "case",
            "char",
            "const",
            "continue",
            "default",
            "do",
            "double",
            "else",
            "enum",
            "extern",
            "float",
            "for",
            "goto",
            "if",
            "inline",
            "int",
            "long",
            "register",
            "restrict",
            "return",
            "short",
            "signed",
            "sizeof",
            "static",
            "struct",
            "switch",
            "typedef",
            "union",
            "unsigned",
            "void",
            "volatile",
            "while"
    };
    
    int is_inchars(char const *foo) /* Retourne 1 si l'ident. est ok avec les caractères */
    {
            while(*foo && (isalnum((unsigned char) *foo) || *foo == '_'))
                    foo++;
    
            return !(*foo);
    }
    
    int is_underok(char const *foo) /* Retourne 1 si la règle des _ est respectée */
    {
            return *foo == '_' ? (*(foo + 1) != '_' && !isupper((unsigned char) *(foo + 1))) : 1;
    }
    
    int is_keyword(char const *foo) /* Retourne 1 si l'ident. est un keyword du C */
    {
            int i, rtn = 0, siz = sizeof keywords / sizeof *keywords;
    
            for(i = 0; i < siz && rtn == 0; i++)
                    rtn = !strcmp(foo, keywords[i]);
    
            return rtn;
    }
    
    
    int zIdentificator(char const *id) /* Renvoie 1 si id valide, 0 sinon */
    {
            int rtn = 0;
    
            if(id != NULL && *id)
                    if(!isdigit((unsigned char) *id) && is_inchars(id) && is_underok(id))
                            rtn = !is_keyword(id);
            return rtn;
    }
    
    int main(void)
    {
            char const *test[] =
            {
                    "toto42",
                    "toto_42",
                    "_toto",
                    "_42toto",
                    "goto_toto",
                    "42_toto",
                    "__toto",
                    "to-to",
                    "_Toto",
                    "goto",
                    "static",
                    "register",
                    "",
                    "es pa ce"
            };
            int i, siz = sizeof test / sizeof *test;
    
            for(i = 0; i < siz; i++)
                    printf("%-10s : %-2d\n", test[i], zIdentificator(test[i]));
    
            return 0;
    }
    


    J'avais aussi pensé à une recherche dichotomique vu que le tableau est déjà trié, mais j'ai estimé que c'était se donner du mal pour finalement pas grand chose. On pourrait éventuellement rajouter la condition && *foo < keywords[i] à la ligne 61, dans le for.
    • Partager sur Facebook
    • Partager sur Twitter
      18 juin 2010 à 13:44:27

      Citation : Eusebus


      int is_keyword(char const *foo) /* Retourne 1 si l'ident. est un keyword du C */
      {
              int i, rtn = 0, siz = sizeof keywords / sizeof *keywords;
      
              for(i = 0; i < siz && rtn == 0; i++)
                      rtn = !strcmp(foo, keywords[i]);
      
              return rtn;
      }
      


      Juste un détail (je n'ai pas regardé le reste). Il vaut mieux parcourir conditionnellement la liste des mots-clés plutôt que de TOUT lire : il se peut que tu trouves un mot-clé en début de recherche auquel cas il est inutile de poursuivre la recherche.

      EDIT : j'avais pas vu le rtn == 0 , mes excuses.
      • Partager sur Facebook
      • Partager sur Twitter
        19 juin 2010 à 3:52:18

        Citation : Marc Mongenet

        Citation : mob

        Pouet_forever: Pourquoi il crée un tableau à chaque appel ? C'est simplement l'adresse du premier élément qui est passé en paramètre, ou bien j'ai raté quelque chose ?


        Il me semble que lorsqu'on définit une variable automatique (aussi dite non statique) dans une fonction

        void f(void) { int t[] = { 1, 2, 3}; }
        


        elle est créée sur la pile, y compris si la variable est un tableau. Cela dit, si le compilateur voit que c'est inutile, je pense qu'il peut créer statiquement le tableau ailleurs, mais je ne sais pas si ce type d'optimisation de compilation existe.


        Il ne crée pas son tableau dans la fonction, il le reçoit en paramètre, c'est l'adresse du premier élément du tableau qui est ajoutée sur la pile, pas tous les éléments du tableau à chaque fois.
        • Partager sur Facebook
        • Partager sur Twitter
          19 juin 2010 à 10:50:56

          Citation : Eusebus

          Voici ce que j'ai produit dans le train entre Paris et Nantes... :p



          Moi je n'ai presque rien à redire à ton code. Tu as découpé en petites fonctions, ça chacun fait comme il veut. Tu as bien casté les arguments de fonctions de ctype.h. Peut-être juste un détail : au lieu de

          int rtn = 0;
          
                  if(id != NULL && *id)
                          if(!isdigit((unsigned char) *id) && is_inchars(id) && is_underok(id))
                                  rtn = !is_keyword(id);
                  return rtn;
          


          est-ce que ceci


          return (id != NULL && *id)
              && (!isdigit((unsigned char) *id) && is_inchars(id) && is_underok(id))
              && !is_keyword(id);
          



          ne serait pas plus simple ?


          D'autre part, je pense que le résultat de la fonction doit rester indéterminé si on entre un pointeur NULL, c'est dans le sens de toute la sémantique des fonctions de la bibliothèque standard (on attend une chaîne et NULL n'est pas une chaîne). Donc, moi, j'ignorerais le cas où id est NULL.
          • Partager sur Facebook
          • Partager sur Twitter
            19 juin 2010 à 11:20:13

            Citation : mob

            Il ne crée pas son tableau dans la fonction, il le reçoit en paramètre, c'est l'adresse du premier élément du tableau qui est ajouté sur la pile, pas tous les éléments du tableau à chaque fois.


            Il a modifié son code, dans le premier il passe un tableau en paramètre, dans le deuxième il crée un tableau dans la fonction. :)
            • Partager sur Facebook
            • Partager sur Twitter
              19 juin 2010 à 13:18:53

              Ah d'accord, my bad, j'avais pas vu le "Premier jet".
              • Partager sur Facebook
              • Partager sur Twitter
                19 juin 2010 à 18:34:11

                @candide : Ah oui, en effet, et c'est plus dans le style de code que j'aime. :)

                Pour le cas de NULL, c'est vrai ; juste un réflexe de traiter ce genre de cas.
                • Partager sur Facebook
                • Partager sur Twitter
                  23 juin 2010 à 20:42:44

                  J'espère que je ne poste pas trop tard.

                  Voici une solution naïve qui je pense, réponds au problème posé :


                  #include <stdio.h>
                  #include <stdlib.h>
                  #include <string.h>
                  #include <ctype.h>
                  
                  const char *C_idents[] = {
                     "auto", "break", "case", "char", "const", "continue", "default",
                     "do", "double", "else", "enum", "extern", "float", "for", "goto",
                     "if", "inline", "int", "long", "register", "restrict", "return",
                     "short", "signed", "sizeof", "static", "struct", "switch",
                     "typedef", "union", "unsigned", "void", "volatile", "while",
                     "_Bool", "_Complex", "_Imaginary", NULL
                  };
                  
                  int is_C_word (char *ident)
                  {
                     int i;
                     for (i = 0; C_idents[i] != NULL; i++)
                     {
                        if (!strcmp (ident, C_idents[i]))
                           return 1;
                     }
                     return 0;
                  }
                  
                  int zIdentificator (char *ident)
                  {
                     if (ident[0] == 0 || is_C_word (ident)
                         || (ident[0] == '_' && ident[1] == '_') || isdigit (ident[0])
                         || (ident[0] == '_' && isupper (ident[1])))
                        return 0;
                  
                     for (; *ident; ident++)
                     {
                        if (!isalnum (*ident) && *ident != '_')
                           return 0;
                     }
                  
                     return 1;
                  }
                  
                  int main (void)
                  {
                  
                     char *id[] =
                        { "a", "toto42", "toto_42", "_toto", "_42toto_", "goto_toto", "42_toto",
                        "__toto", "to-to", "_Toto", "", NULL
                     };
                     int i;
                     for (i = 0; id[i] != NULL; i++)
                     {
                        printf ("%s = %d\n", id[i], zIdentificator (id[i]));
                     }
                     return EXIT_SUCCESS;
                  }
                  



                  Je n'ai pas lu les 4 pages du topic par contre... :)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    24 juin 2010 à 1:23:20

                    Citation : Tosh



                    Voici une solution naïve qui je pense, réponds au problème posé :



                    D'une part

                    tosh.c: In function ‘zIdentificator’:
                    tosh.c:28: warning: implicit declaration of function ‘isdigit’
                    tosh.c:28: warning: implicit declaration of function ‘isupper’
                    tosh.c:33: warning: implicit declaration of function ‘isalnum’


                    et d'autre part




                    toto       : 1
                    toto42     : 1
                    Toto       : 1
                    c          : 1
                    to         : 1
                    _          : 1
                    _t         : 1
                    _toto      : 1
                    _bool      : 1
                    _4         : 1
                    _42_toto   : 1
                               : 1
                    4          : 0
                    42         : 0
                    4_         : 0
                    to-to      : 0
                    __         : 0
                    __toto     : 0
                    _Toto      : 0
                    _____      : 0
                    goto       : 0
                    return     : 0
                    _Bool      : 0
                    • Partager sur Facebook
                    • Partager sur Twitter
                      24 juin 2010 à 9:30:18

                      C'est juste pour la chaîne vide que ça pose problème si j'ai bien compris?

                      J'ai édité mon poste en conséquence. :)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        24 juin 2010 à 11:17:18

                        Citation : Tosh


                        J'ai édité mon poste en conséquence. :)



                        Ça roule mais un point quand même : je vois pas l'intérêt de mettre une sentinelle NULL dans ta liste de mots-clés si c'est pour utiliser un indice entier, l'idée étant de transposer l'idiomatisme des parcours de chaînes. Donc j'aurais plutôt écrit ceci :

                        int is_C_word (char *ident)
                        {
                           const char **p=&C_idents[0];
                           for (; *p; p++)
                              if (!strcmp (ident, *p))
                                 return 1;
                        
                           return 0;
                        }
                        


                        voire

                        int is_C_word(char *ident)
                        {
                          const char **p = &C_idents[0];
                          while (*p && strcmp(ident, *p++))
                            ;
                          return *p != NULL;
                        }
                        
                        • Partager sur Facebook
                        • Partager sur Twitter
                          24 juin 2010 à 11:25:42

                          Le NULL sert juste à indiquer la fin des mots clefs.

                          Je ne trouve pas particulièrement tes suggestions plus claires que la mienne :)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            24 juin 2010 à 12:13:20

                            Citation : Tosh

                            Le NULL sert juste à indiquer la fin des mots clefs.



                            J'ai bien compris. Mais personne ne t'oblige à le mettre et on peut très bien s'en passer :

                            int is_C_word (char *ident)
                            {
                               int i;
                               int n=sizeof C_idents/sizeof *C_idents;
                               for (i = 0; i<n; i++)
                               {
                                  if (!strcmp (ident, C_idents[i]))
                                     return 1;
                               }
                               return 0;
                            }
                            



                            L'intérêt de rajouter NULL est que NULL devient une sentinelle de même que le caractère nul est une sentinelle des chaînes statiques. Quel est l'intérêt de la sentinelle des chaînes ? Réponse : on peut parcourir une chaîne
                            1) sans en connaître la longueur à l'avance
                            2) sans utiliser d'indice entier et en utilisant à la place un pointeur.

                            Le point 2) est la manière idiomatique de parcourir une chaîne.

                            Or toi tu as utilisé un indice entier. Cela ne me paraît pas cohérent.


                            Citation : Tosh


                            Je ne trouve pas particulièrement tes suggestions plus claires que la mienne :)



                            La clarté est relative. Il ne s'agit pas d'être clair ou didactique ici, il s'agit d'être idiomatique et cohérent.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 juillet 2010 à 15:29:40

                              Bonjour à vous :)

                              Je n'ai pas le niveau de la plupart des gens qui ont posté ici, mais j'essaye de vous montrer mon code et j'attends les critiques (pas trop acides s'il vous plait) sur ce que j'ai pondu.

                              Je vous demande à l'avance de m'excuser si mon code vous parait moche, ou alors si une remarque a déjà été faite plus tôt dans le topic (en effet, j'ai évité de lire les commentaires pour pas pomper d'indice et écrire -mon-truc-à-moi-).

                              Autre chose : Dans mon main la boucle for parcoure les éléments du tableau de pointeurs testwords. Y-a-t-il un autre moyen d'arrêter la boucle qui me permettrais de ne pas changer la condition de loop si je rajoute un mot à tester? J'ai essayé quelque chose du genre (*testwords)++ mais belle erreur :p


                              Voici mon code :

                              main.c :

                              #include <stdio.h>
                              #include <stdlib.h>
                              #include "fonctions.h"
                              
                              
                              
                              int main()
                              {
                                  const char* testwords[]={"struct","_bonjour","héhé","__nn","j42k","42jk","_Manger","Restrict","____","4","te-st","",NULL};
                                  int i=0;
                                  for(i=0;testwords[i]!=NULL;i++)
                                      printf("%s : %d\n",testwords[i],zIdentificator(testwords[i]));
                              
                                  return 0;
                              }
                              


                              zIdentificator =>
                              #include <stdio.h>
                              #include <stdlib.h>
                              #include <string.h>
                              #include "fonctions.h"
                              
                              int zIdentificator(char *word)
                              {
                                  const char *keywords[]={"auto", /*0*/
                                                          "break",
                                                          "case",
                                                          "char",
                                                          "const",
                                                          "continue", /*5*/
                                                          "default",
                                                          "do",
                                                          "double",
                                                          "else",
                                                          "enum",
                                                          "extern",
                                                          "float",
                                                          "for",
                                                          "goto",
                                                          "if",
                                                          "inline",
                                                          "int",
                                                          "long",
                                                          "register",
                                                          "restrict",
                                                          "return",
                                                          "short",
                                                          "signed",
                                                          "sizeof",
                                                          "static",
                                                          "struct",
                                                          "switch",
                                                          "typedef",
                                                          "union",
                                                          "unsigned",
                                                          "void",
                                                          "volatile",
                                                          "while",
                                                          "_Bool",
                                                          "_Complex",
                                                          "_Imaginary"};
                                  int i=0, flag=1;
                              
                                  for(i=0;(i<NB_KEY)&&(flag!=0);i++) /*Vérification des mots de keywords*/
                                  {
                                      if(strcmp(word,keywords[i])==0)
                                          flag=0;
                                  }
                              
                                  if(word[0]=='_' && (word[1]=='_' || (word[1] <= 90 && word[1] >=65))) /* test pour le double underscore*/
                                      flag=0;                                                           /* ou le simple + majuscule*/
                              
                                  if(word[0] <= 0x39 && word[0] >= 0x30) /*test pour les caractères numériques au début du mot*/
                                      flag=0;
                              
                                  for(i=0;i<strlen(word);i++) /*test pour la validité des caractères.*/
                                  {
                                      if(word[i]<65||word[i]>90) /*le char n'est pas minuscule*/
                                          if(word[i]<97||word[i]>122) /*le char n'est pas majuscule*/
                                              if(word[i]<48||word[i]>57) /*le char n'est pas un des 10 chiffres*/
                                                  if(word[i] != 95) /*le char n'est pas un underscore*/
                                                      flag=0;
                                  }
                              
                                  if(*word == 0 || word==NULL) /*est-ce un mot??*/
                                      flag=0;
                              
                              
                                  return flag;
                              }
                              


                              et le .h (que j'ai fait par pure habitude et qui ne sers à rien ^^')
                              #ifndef DEF_FONCTIONS_H
                              #define DEF_FONCTIONS_H
                              
                              #define NB_KEY 37
                              
                              int zIdentificator(char *word); /*Renvoie 1 si word est utilisable, 0 si réservé*/
                              
                              #endif
                              


                              Merci d'avance pour vos commentaires constructifs, j'attends avec impatience :D

                              EDIT : j'ai lu le commentaire du dessus, merci pour l'idée de la sentinelle je vais implémenter ça de suite :D
                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 juillet 2010 à 15:51:15

                                Citation : quentin-fait-du-c


                                if(word[i]<65||word[i]>90) /*le char n'est pas minuscule*/
                                            if(word[i]<97||word[i]>122) /*le char n'est pas majuscule*/
                                                if(word[i]<48||word[i]>57) /*le char n'est pas un des 10 chiffres*/
                                                    if(word[i] != 95) /*le char n'est pas un underscore*/
                                



                                Ce genre de truc est à éviter, ce n'est pas clair du tout que tu es en train de tester des caractères avec ces nombres qui sortent de nulle part, d'ailleurs tu es obligé de commenter assez lourdement pour que ça reste lisible.
                                Utilises if(word[i] != '_') plutot que if(word[i] != 95) dans ce genre de cas, c'est beaucoup plus lisible. En plus, ça permet d'avoir du code portable, indépendant de l'encodage.
                                Et quand il s'agit des plages de caractere, tu as déjà tout un tas de fonctions très utiles dans ctype.h.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 juillet 2010 à 15:55:12

                                  Je n'avais pas inclus ctype.h pour ne pas m'empêtrer dans les trucs bizarres, je vais donc aller voir la doc etc etc, et éditer tout ça.

                                  PS : les nombres sortent de la table ASCII, y-a-t-il des endroits (espaces-temps) où cette table n'est plus valable en informatique?


                                  EDIT : voilà la nouvelle boucle :

                                  for(i=0;i<strlen(word);i++) /*test pour la validité des caractères.*/
                                      {
                                          if((!isalpha(word[i])) || /*le char n'est pas un alphabétique*/
                                            (!isdigit(word[i])) ||/*le char n'est pas un des 10 chiffres*/
                                            (word[i] != '_')) /*le char n'est pas un underscore*/
                                              flag=0;
                                      }
                                  


                                  EDIT2 : Hé ben avec cette fonction ça ne fonctionne plus...
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    1 juillet 2010 à 16:36:06

                                    De mémoire, rien ne te garantie que c'est l'ASCII qui est utilisé. Même si en pratique, ton premier code fonctionne sans problème sous windows/linux/macos.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      1 juillet 2010 à 16:56:36

                                      Bon revoilà la fonction zIdentificator en entier avec les tests de ctype.h.

                                      int zIdentificator(const char *word)
                                      {
                                          const char *keywords[]={"auto", /*0*/
                                                                  "break",
                                                                  "case",
                                                                  "char",
                                                                  "const",
                                                                  "continue", /*5*/
                                                                  "default",
                                                                  "do",
                                                                  "double",
                                                                  "else",
                                                                  "enum",
                                                                  "extern",
                                                                  "float",
                                                                  "for",
                                                                  "goto",
                                                                  "if",
                                                                  "inline",
                                                                  "int",
                                                                  "long",
                                                                  "register",
                                                                  "restrict",
                                                                  "return",
                                                                  "short",
                                                                  "signed",
                                                                  "sizeof",
                                                                  "static",
                                                                  "struct",
                                                                  "switch",
                                                                  "typedef",
                                                                  "union",
                                                                  "unsigned",
                                                                  "void",
                                                                  "volatile",
                                                                  "while",
                                                                  "_Bool",
                                                                  "_Complex",
                                                                  "_Imaginary"};
                                          int i=0, flag=1;
                                      
                                          for(i=0;(i<NB_KEY)&&(flag!=0);i++) /*Vérification des mots de keywords*/
                                          {
                                              if(strcmp(word,keywords[i])==0)
                                                  flag=0;
                                          }
                                      
                                          if(word[0]=='_' && (word[1]=='_' || (isupper(word[1])))) /* test pour le double underscore*/
                                              flag=0;                                              /* ou le simple + majuscule*/
                                      
                                          if(isdigit(word[0])) /*test pour les caractères numériques au début du mot*/
                                              flag=0;
                                      
                                          for(i=0;i<strlen(word);i++) /*test pour la validité des caractères.*/
                                          {
                                              if((!isalpha(word[i])) && /*le char n'est pas un alphabétique*/
                                                (!isdigit(word[i])) &&/*le char n'est pas un des 10 chiffres*/
                                                (word[i] != '_')) /*le char n'est pas un underscore*/
                                                  flag=0;
                                          }
                                      
                                          if(*word == 0 || word==NULL) /*est-ce un mot??*/
                                              flag=0;
                                      
                                      
                                          return flag;
                                      }
                                      
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        1 juillet 2010 à 19:05:48

                                        Salut, voici mon code :
                                        #include <stdio.h>
                                        #include <stdlib.h>
                                        #include <ctype.h>
                                        #include <string.h>
                                        
                                        #define T 37
                                        char *keywords[T] =
                                        {
                                            "auto", "break", "case", "char", "const", "continue", "default",
                                            "do", "double", "else", "enum", "extern", "float", "for", "goto",
                                            "if", "inline", "int", "long", "register", "restrict", "return",
                                            "short", "signed", "sizeof", "static", "struct", "switch",
                                            "typedef", "union", "unsigned", "void", "volatile", "while",
                                            "_Bool", "_Complex", "_Imaginary"
                                        };
                                        
                                        int zIdentificator(char *s) /* retourne 0 si incorrect */
                                        {
                                            int i = 0;
                                        
                                            for (; i < T; ++i)
                                                if (strcmp(s, keywords[i]) == 0)
                                                    return 0;
                                        
                                            if (isupper(*s) ||
                                                (*s == '_' && *(s+1) == '_') ||
                                                (*s == '_' && isupper(*(s+1))) ||
                                                isdigit(*s))
                                                    return 0;
                                        
                                            for (; *s; s++)
                                                if (*s != '_' && !isalnum(*s))
                                                    return 0;
                                        
                                        
                                            return 1;
                                        }
                                        
                                        int main(void)
                                        {
                                            int i= 0;
                                            char *id[] = {"truc", "_truc", "__truc", "truc1", "truc+1", "_Truc","truc_bool","case"};
                                        
                                            for(; i < 8; i++)
                                                printf("%s : %d\n", id[i], zIdentificator(id[i]));
                                        
                                            return 0;
                                        }
                                        

                                        Qu'en pensez vous ?
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          1 juillet 2010 à 19:12:58

                                          Citation : Colb-Seton

                                          Qu'en pensez vous ?


                                          Comment dire... toujours la même chose. Viens pas te plaindre encore une fois quand tes boucles ne fonctionneront pas.
                                          Tu considères que "Truc" est incorrect -> pas bon. :)
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            1 juillet 2010 à 20:48:48

                                            Oui, exact pour Truc, c'est rectifié.
                                            #include <stdio.h>
                                            #include <ctype.h>
                                            #include <string.h>
                                            
                                            #define T 37
                                            char *keywords[T] =
                                            {
                                              "auto", "break", "case", "char", "const", "continue", "default",
                                              "do", "double", "else", "enum", "extern", "float", "for", "goto",
                                              "if", "inline", "int", "long", "register", "restrict", "return",
                                              "short", "signed", "sizeof", "static", "struct", "switch",
                                              "typedef", "union", "unsigned", "void", "volatile", "while",
                                              "_Bool", "_Complex", "_Imaginary"
                                            };
                                            
                                            int zIdentificator(char *s) /* retourne 0 si incorrect */
                                            {
                                              int i = 0;
                                            
                                              for (; i < T; ++i) /* recherche d'un mot interdit */
                                                if (strcmp(s, keywords[i]) == 0)
                                                  return 0;
                                            
                                                /* si deux '_' ou '_' suivi d'une majuscule */
                                            
                                              if ((*s == '_' && *(s+1) == '_') ||
                                                  (*s == '_' && isupper(*(s+1))) ||
                                                  isdigit(*s))
                                                return 0;
                                            
                                                /* recherche d'un caractère alphanumérique différent de '_' */
                                            
                                              for (; *s; s++)
                                                if (*s != '_' && !isalnum(*s))
                                                  return 0;
                                            
                                                return 1;
                                            }
                                            
                                            int main(void)
                                            {
                                              int i = 0;
                                              char *id[] = {"truc", "_truc", "__truc", "truc1", "truc+1", "_Truc", "Truc", "case", "truc_bool"};
                                            
                                              for (; i < 9; i++)
                                                printf("%s : %d\n", id[i], zIdentificator(id[i]));
                                            
                                              return 0;
                                            }
                                            
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              1 juillet 2010 à 21:13:59

                                              Je n'ai pas testé, mais il me semble que ton code ne gère pas le cas de la chaîne vide :)

                                              @Pouet_forever : elles ont quoi ses boucles?
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                1 juillet 2010 à 21:34:23

                                                La chaîne vide peut être un identificateur ?
                                                Pour mes boucles, je ne me sers pas souvent de l'initialisation ce qui provoquait des erreurs, dans le cas où j'avais deux boucles l'une à la suite de l'autre avec la même variable du genre :
                                                int f(int t[], int t2[])
                                                {
                                                  int i = 0;
                                                
                                                  for(; i < truc; i++)
                                                  [...]
                                                
                                                  for(; i < machin; i++)
                                                  [...]
                                                }
                                                
                                                Pouet, ça l'a marqué.
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  1 juillet 2010 à 21:36:55

                                                  Citation : Tosh

                                                  @Pouet_forever : elles ont quoi ses boucles?


                                                  Bah, un exemple :

                                                  #include <stdio.h>
                                                  #include <stdlib.h>
                                                  
                                                  int main(void) {
                                                    int i = 0;
                                                    
                                                    for (; i < 10; i++)
                                                      printf("%d\n", i);
                                                    for (; i < 10; i++)
                                                      printf("%d\n", i);
                                                    return EXIT_SUCCESS;
                                                  }
                                                  

                                                  Mince alors, ce code n'affiche que 10 chiffres. :(
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    1 juillet 2010 à 21:46:03

                                                    La chaîne vide peut être un identificateur ?


                                                    Non justement, mais ton code renvoi 1 si on lui donne une chaîne vide.

                                                    @Pouet_forever : effectivement, il faut faire attention à ce genre de choses, mais là ça me semble maîtrisé.
                                                    C'est vrai que j'utilise plutôt cette forme de for() pour les pointeurs, plutôt que pour un indice...
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      1 juillet 2010 à 22:08:16

                                                      Ok, j'ai fait ça alors, ça devrait marcher :
                                                      #include <stdio.h>
                                                      #include <ctype.h>
                                                      #include <string.h>
                                                      
                                                      #define T 37
                                                      char *keywords[T] =
                                                      {
                                                        "auto", "break", "case", "char", "const", "continue", "default",
                                                        "do", "double", "else", "enum", "extern", "float", "for", "goto",
                                                        "if", "inline", "int", "long", "register", "restrict", "return",
                                                        "short", "signed", "sizeof", "static", "struct", "switch",
                                                        "typedef", "union", "unsigned", "void", "volatile", "while",
                                                        "_Bool", "_Complex", "_Imaginary"
                                                      };
                                                      
                                                      int isempty(char *s) /* retourne 1 si vide */
                                                      {
                                                        return strcmp("", s) == 0;
                                                      }
                                                      
                                                      int zIdentificator(char *s) /* retourne 0 si incorrect */
                                                      {
                                                        int i = 0;
                                                      
                                                        if (isempty(s))
                                                          return 1;
                                                      
                                                        for (; i < T; ++i) /* recherche d'un mot interdit */
                                                          if (strcmp(s, keywords[i]) == 0)
                                                            return 0;
                                                      
                                                          /* si deux '_' ou '_' suivi d'une majuscule */
                                                      
                                                        if ((*s == '_' && *(s+1) == '_') ||
                                                            (*s == '_' && isupper(*(s+1))) ||
                                                            isdigit(*s))
                                                          return 0;
                                                      
                                                          /* recherche d'un caractère alphanumérique différent de '_' */
                                                      
                                                        for (; *s; s++)
                                                          if (*s != '_' && !isalnum(*s))
                                                            return 0;
                                                      
                                                        return 1;
                                                      }
                                                      
                                                      int main(void)
                                                      {
                                                        int i = 0;
                                                        char *id[] = {"truc", "_truc", "__truc", "truc1", "truc+1", "_Truc", "Truc", "case", "truc_bool", ""};
                                                      
                                                        for (; i < 10; i++)
                                                          printf("%s : %d\n", id[i], zIdentificator(id[i]));
                                                      
                                                        return 0;
                                                      }
                                                      
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        1 juillet 2010 à 22:12:34

                                                        Ça me paraît un peu lourd de faire une fonction pour tester la chaîne vide :)

                                                        Ce n'est pas plus simple comme ceci?

                                                        if(!(*s))
                                                           return 0;
                                                        

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Anonyme
                                                          1 juillet 2010 à 23:01:22

                                                          On parle de la chaine vide là...
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            1 juillet 2010 à 23:03:57

                                                            Et pour moi vous n'avez rien à dire?
                                                            J'dois être flatté ou ... ?

                                                            C'est juste que je sais que j'peux condenser le code pour le rendre plus lisible et plus performant (des if dans des for c'est mauvais parait-il), j'aimerais m'améliorer :)
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            zIdentificator

                                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                            • Editeur
                                                            • Markdown