Partage
  • Partager sur Facebook
  • Partager sur Twitter

utilisation du printf scanf

Bataille navale et d'autres jeux dans le futur

    26 décembre 2023 à 10:33:03

    #ifndef INSAIO_H
    #define INSAIO_H
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #ifndef INSAIO_ERROR_AT_COMPILE_TIME
    #define INSAIO_ERROR_AT_COMPILE_TIME 1
    #endif
    
    #define NOUVELLE_LIGNE "\n"
    
    /* the macros can expand to several statements; we enclose them in MACRO_BEGIN and
     * MACRO_END, rather than '{' and '}'. The reason is that we want to be able to use
     * the macro in a context such as `if (...) macro(...); else ...`. If we didn't use
     * this obscure trick, we'd have to omit the ";" in such cases.
     * credit: taken from Peter Selinger's potrace implementation */
    #define MACRO_BEGIN do {
    #define MACRO_END   } while (0)
    
                          /***  array and type checking  ***/
    
    #define IS_ARRAY(arg) \
    ( \
        __builtin_types_compatible_p(typeof(arg), int*) || \
        __builtin_types_compatible_p(typeof(arg), float*) || \
        __builtin_types_compatible_p(typeof(arg), double*) || \
        __builtin_types_compatible_p(typeof(arg), const int*) || \
        __builtin_types_compatible_p(typeof(arg), const float*) || \
        __builtin_types_compatible_p(typeof(arg), const double*) || \
        __builtin_types_compatible_p(typeof(arg), int[]) || \
        __builtin_types_compatible_p(typeof(arg), float[]) || \
        __builtin_types_compatible_p(typeof(arg), double[]) \
    )
    
    #define IS_VALID_TYPE(arg) \
    ( \
        __builtin_types_compatible_p(typeof(arg), int*) || \
        __builtin_types_compatible_p(typeof(arg), float*) || \
        __builtin_types_compatible_p(typeof(arg), double*) || \
        __builtin_types_compatible_p(typeof(arg), const int*) || \
        __builtin_types_compatible_p(typeof(arg), const float*) || \
        __builtin_types_compatible_p(typeof(arg), const double*) || \
        __builtin_types_compatible_p(typeof(arg), int[]) || \
        __builtin_types_compatible_p(typeof(arg), float[]) || \
        __builtin_types_compatible_p(typeof(arg), double[]) || \
        __builtin_types_compatible_p(typeof(arg), char) || \
        __builtin_types_compatible_p(typeof(arg), int) || \
        __builtin_types_compatible_p(typeof(arg), float) || \
        __builtin_types_compatible_p(typeof(arg), double) || \
        __builtin_types_compatible_p(typeof(arg), char*) || \
        __builtin_types_compatible_p(typeof(arg), const char*) || \
        __builtin_types_compatible_p(typeof(arg), char[]) \
    )
    
    #if INSAIO_ERROR_AT_COMPILE_TIME
        #define CHK_ARRAY(arg, num, name, action) \
            _Static_assert(!IS_ARRAY(arg), \
                "Argument " num " de " name " `" #arg "` non valide : " \
                "on ne peut pas directement " action " un tableau.");
        #define CHK_TYPE(arg, num, name) \
            _Static_assert(IS_VALID_TYPE(arg), \
                "Argument " num " de " name " `" #arg "` non valide : " \
                "les types autorises sont `char`, `int`, `float`, `double`, ou " \
                "les chaines de caracteres.");
        #define CHK_CONST(arg, num) \
            _Static_assert(!(__builtin_constant_p(arg) || \
                __builtin_types_compatible_p(typeof(arg), const char*)), \
                "Argument " num " de SAISIR `" #arg "` non valide : " \
                "on ne peut pas modifier une constante.");
    #else
        #define CHK_ARRAY(arg, num, name, action) \
            if (IS_ARRAY(arg)){ \
                printf("\nDans %s, ligne %i : argument %s de %s `%s` non " \
                    "valide ; on ne peut pas directement %s un tableau.\n\n", \
                    __FILE__, __LINE__, #arg, num, name, action); \
                exit(EXIT_FAILURE); \
            }
        #define CHK_TYPE(arg, num, name) \
            if (!IS_VALID_TYPE(arg)){ \
                printf("\nDans %s, ligne %i : argument %s de %s `%s` non " \
                    "valide ; les types autorisés sont `char`, `int`, `float`, " \
                    "`double`, ou les chaînes de caractères.\n\n", __FILE__, \
                    __LINE__, #arg, num, name); \
                exit(EXIT_FAILURE); \
            }
        #define CHK_CONST(arg, num) \
            if (__builtin_constant_p(arg) || \
                __builtin_types_compatible_p(typeof(arg), const char*)){ \
                printf("\nDans %s, ligne %i : argument %s de SAISIR `%s` non " \
                "valide ; on ne peut pas modifier une constante.\n\n", \
                __FILE__, __LINE__, #arg, num); \
                exit(EXIT_FAILURE); \
            }
    #endif
    
    /* unfortunately with __builtin_choose_expr, even if the conditional argument
     * is a compile time constant, so that one of the branches is not compiled,
     * both branches are still checked for syntax errors; the following pragma
     * suppresses invalid format warnings */
    #pragma GCC diagnostic ignored "-Wformat"
    
                             /***  output to stdout  ***/
    
    #define _AFFICHER_1(arg, num) \
        CHK_ARRAY(arg, num, "AFFICHER", "afficher") \
        CHK_TYPE(arg, num, "AFFICHER") \
        if (__builtin_types_compatible_p(typeof(arg), char)){ \
            printf("%c", (arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), int)){ \
            printf("%i", (arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), float)){ \
            printf("%f", (arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), double)){ \
            printf("%lf", (arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), char*)){ \
            printf("%s", (arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), const char*)){ \
            printf("%s", (arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), char[])){ \
            printf("%s", (arg)); \
        } fflush(stdout)
    
    /* in order to carry on the right argument number, it is necessary to make the
     * recursion in the right order and drop arguments recursively */
    #define _AFFICHER_2(num, drop, arg, ...) _AFFICHER_1(arg, num)
    #define _AFFICHER_3(num, drop, ...) _AFFICHER_2(num, __VA_ARGS__)
    #define _AFFICHER_4(num, drop, ...) _AFFICHER_3(num, __VA_ARGS__)
    #define _AFFICHER_5(num, drop, ...) _AFFICHER_4(num, __VA_ARGS__)
    #define _AFFICHER_6(num, drop, ...) _AFFICHER_5(num, __VA_ARGS__)
    #define _AFFICHER_7(num, drop, ...) _AFFICHER_6(num, __VA_ARGS__)
    #define _AFFICHER_8(num, drop, ...) _AFFICHER_7(num, __VA_ARGS__)
    #define _AFFICHER_9(num, drop, ...) _AFFICHER_8(num, __VA_ARGS__)
    
    /* the recursive calls with the right argument number */
    #define _AFFICHER1(arg, ...) _AFFICHER_1(arg, "1")
    #define _AFFICHER2(...) _AFFICHER1(__VA_ARGS__); _AFFICHER_2("2", __VA_ARGS__)
    #define _AFFICHER3(...) _AFFICHER2(__VA_ARGS__); _AFFICHER_3("3", __VA_ARGS__)
    #define _AFFICHER4(...) _AFFICHER3(__VA_ARGS__); _AFFICHER_4("4", __VA_ARGS__)
    #define _AFFICHER5(...) _AFFICHER4(__VA_ARGS__); _AFFICHER_5("5", __VA_ARGS__)
    #define _AFFICHER6(...) _AFFICHER5(__VA_ARGS__); _AFFICHER_6("6", __VA_ARGS__)
    #define _AFFICHER7(...) _AFFICHER6(__VA_ARGS__); _AFFICHER_7("7", __VA_ARGS__)
    #define _AFFICHER8(...) _AFFICHER7(__VA_ARGS__); _AFFICHER_8("8", __VA_ARGS__)
    #define _AFFICHER9(...) _AFFICHER8(__VA_ARGS__); _AFFICHER_9("9", __VA_ARGS__)
    
    /* the actual macro */
    #define _AFFICHER(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
    #define AFFICHER(...) MACRO_BEGIN _AFFICHER(__VA_ARGS__, _AFFICHER9, \
            _AFFICHER8, _AFFICHER7, _AFFICHER6, _AFFICHER5, _AFFICHER4, \
            _AFFICHER3, _AFFICHER2, _AFFICHER1) (__VA_ARGS__); MACRO_END
    
                             /***  input from std in  ***/
    
    /* unfortunately with __builtin_choose_expr, even if the conditional argument 
     * is a compile time constant, so that one of the branches is not compiled,
     * both branches are still checked for syntax errors; the following workaround 
     * avoids taking the adress of something that is not a valid l-value */
    char __protected_var;
    #define _ADRESS_IF_NOT_CONST(arg) \
        &(__builtin_choose_expr(__builtin_constant_p(arg) || \
          __builtin_types_compatible_p(typeof(arg), int*) || \
          __builtin_types_compatible_p(typeof(arg), float*) || \
          __builtin_types_compatible_p(typeof(arg), double*) || \
          __builtin_types_compatible_p(typeof(arg), const int*) || \
          __builtin_types_compatible_p(typeof(arg), const float*) || \
          __builtin_types_compatible_p(typeof(arg), const double*), \
          __protected_var, (arg)))
    
    /* with %c or %[] specifications, any leading spacing caracter is read
     * unless format preceded by space; special thanks to Moncef Hidane */
    #define _SAISIR_1(arg, num) \
        CHK_ARRAY(arg, num, "SAISIR", "saisir") \
        CHK_TYPE(arg, num, "SAISIR") \
        CHK_CONST(arg, num) \
        if (__builtin_types_compatible_p(typeof(arg), char)){ \
            scanf(" %c", _ADRESS_IF_NOT_CONST(arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), int)){ \
            scanf("%i", _ADRESS_IF_NOT_CONST(arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), float)){ \
            scanf("%f", _ADRESS_IF_NOT_CONST(arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), double)){ \
            scanf("%lf", _ADRESS_IF_NOT_CONST(arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), char*)){ \
            scanf(" %[^\n]", (arg)); \
        }else if (__builtin_types_compatible_p(typeof(arg), char[])){ \
             scanf(" %[^\n]", (arg)); \
        }
    
    /* in order to carry on the right argument number, it is necessary to make the
     * recursion in the right order and drop arguments recursively */
    #define _SAISIR_2(num, drop, arg, ...) _SAISIR_1(arg, num)
    #define _SAISIR_3(num, drop, ...) _SAISIR_2(num, __VA_ARGS__)
    #define _SAISIR_4(num, drop, ...) _SAISIR_3(num, __VA_ARGS__)
    #define _SAISIR_5(num, drop, ...) _SAISIR_4(num, __VA_ARGS__)
    #define _SAISIR_6(num, drop, ...) _SAISIR_5(num, __VA_ARGS__)
    #define _SAISIR_7(num, drop, ...) _SAISIR_6(num, __VA_ARGS__)
    #define _SAISIR_8(num, drop, ...) _SAISIR_7(num, __VA_ARGS__)
    #define _SAISIR_9(num, drop, ...) _SAISIR_8(num, __VA_ARGS__)
    
    /* the recursive calls with the right argument number */
    #define _SAISIR1(arg, ...) _SAISIR_1(arg, "1")
    #define _SAISIR2(...) _SAISIR1(__VA_ARGS__); _SAISIR_2("2", __VA_ARGS__)
    #define _SAISIR3(...) _SAISIR2(__VA_ARGS__); _SAISIR_3("3", __VA_ARGS__)
    #define _SAISIR4(...) _SAISIR3(__VA_ARGS__); _SAISIR_4("4", __VA_ARGS__)
    #define _SAISIR5(...) _SAISIR4(__VA_ARGS__); _SAISIR_5("5", __VA_ARGS__)
    #define _SAISIR6(...) _SAISIR5(__VA_ARGS__); _SAISIR_6("6", __VA_ARGS__)
    #define _SAISIR7(...) _SAISIR6(__VA_ARGS__); _SAISIR_7("7", __VA_ARGS__)
    #define _SAISIR8(...) _SAISIR7(__VA_ARGS__); _SAISIR_8("8", __VA_ARGS__)
    #define _SAISIR9(...) _SAISIR8(__VA_ARGS__); _SAISIR_9("9", __VA_ARGS__)
    
    /* the actual macro */
    #define _SAISIR(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
    #define SAISIR(...) MACRO_BEGIN _SAISIR(__VA_ARGS__, _SAISIR9, _SAISIR8, \
        _SAISIR7,  _SAISIR6, _SAISIR5, _SAISIR4, _SAISIR3, _SAISIR2, _SAISIR1) \
        (__VA_ARGS__); MACRO_END
    
    #endif
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void init(int t[][10]){int i,j;
      for(i=0;i<10;i++){
        for(j=0;j<10;j++){t[i][j]=0;}}
      return;}
    
    void post(int t[][10],int s[][10]){int i,j;
      for(i=0;i<10;i++){printf("|");
        for(j=0;j<10;j++){
          if (t[i][j] == -1){printf(" O ");}
          if (t[i][j] == 0){printf("   ");}
          if (t[i][j] == 1){printf(" X ");}
          if (t[i][j] == 2){printf(" T ");}
          if (t[i][j] == 3){printf(" S ");}
          if (t[i][j] == 4){printf(" C ");}
          if (t[i][j] == 5){printf(" A ");}}
        printf("|           |");
        for(j=0;j<10;j++){
          if (s[i][j] == 1){printf(" X ");}
          else if (s[i][j] == -1){printf(" O ");}
          else{printf("   ");}}
        printf("|\n ");}
      return;}
    
    int boat(int b,int t[][10],int bs[][6]){int i,e,a1,a2,b1,b2;
      float d1,d2;
      char c1='A',c2='A';
      printf("\nAvant du navire : \nLigne (A-J) & Colonne (1-10) : ");
      scanf("%c",&c1);
      if (c1>='a' && c1<='j'){c1=c1-'a'+'A';}
      a1=c1;
      scanf("%f",&d1);
      b1=d1;
      printf("\nArriere du navire : \nLigne (A-J) & Colonne (1-10) : ");
      scanf("%c",&c2);
      if (c2>='a' && c2<='j'){c2=c2-'a'+'A';}
      a2=c2;
      scanf("%f",&d2);
      b2=d2;
      if (a1<'A' || a1>'J' || a1!=c1 || b1<1 || b1>10 || b1!=d1 || a2<'A' || a2>'J' || a2!=c2 || b2<1 || b2>10 || b2!=d2 || (a1!=a2 && b1!=b2)){return 0;}
      else if (a1==a2){
        if (b1>b2){e=b2;
          b2=b1;
          b1=e;}
        if (b1>11-b || b2<b || b2-b1!=b-1){return 0;}
        else{
          for(i=0;i<b;i++){
            if (t[a1-'A'][b1-1+i]!=0){return 0;}}
          for(i=0;i<b;i++){t[a1-'A'][b1-1+i]=b;}
          return 1;}}
      else if (b1==b2){
        if (a1>a2){e=a2;
          a2=a1;
          a1=e;}
        if (a1-'A'>10-b || a2-'A'<b-1 || a2-a1!=b-1){return 0;}
        else{
          for(i=0;i<b;i++){
            if (t[a1-'A'+i][b1-1]!=0){return 0;}}
          for(i=0;i<b;i++){t[a1-'A'+i][b1-1]=b;}
          return 1;}}}
    
    void place(int tx[][10],int b[][10],int bs[][6],int x){int a=5,c=4,s=3,t=2,i;
      printf("Joueur %i\nL'ennemi se prepare a nous faire la guerre.\nPlacez votre flotte :\n",x);
      post(tx,b);
      for(i=0;i<5;i++){
        if(i==0){printf("\nPorte-avion de 5 cases : ");
          if (boat(a,tx,bs)==0){i--;}
          else {post(tx,b);}}
        if(i==1){printf("\nCuirasse de 4 cases : ");
          if (boat(c,tx,bs)==0){i--;}
          else {post(tx,b);}}
        if(i==2||i==3){printf("\nSous-marin de 3 cases : ");
          if (boat(s,tx,bs)==0){i--;}
          else {post(tx,b);}}
        if(i==4){printf("\nTorpilleur de 2 cases : ");
          if (boat(t,tx,bs)==0){i--;}
          else {post(tx,b);}}}
      printf("Donner l'ordinateur a l'adversaire apres disparition du tableau");
      sleep(4);
      printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
      sleep(4);
      return;}
    
    int flow(int t[][10],int b){}
    
    void shot(int t[][10],int s[][10],int bs[][6]){}
    
    int vic(int t[][10]){}
    
    int main(){
      int x=0,v,i;
      int t1[10][10], s1[10][10],t2[10][10],s2[10][10],b1[2][6],b2[2][6];
      init(t1);
      init(s1);
      init(t2);
      init(s2);
      place(t1,s1,b1,1);
      place(t2,s2,b2,2);
      return 0;}

    Voici un morceau de mon programme de bataille navale en C.
    La partie place ne marche pas du tout avec printf et scanf, en utilisant les fonctions AFFICHER et SAISIR de insaio.h inclus ci-dessus cela marchait parfaitement mais depuis plus rien ne marche pouvez-vous m'aidez s'il vous plaît

    -
    Edité par ..£ 26 décembre 2023 à 13:11:40

    • Partager sur Facebook
    • Partager sur Twitter
      26 décembre 2023 à 11:28:46

      Utilises le bouton code </> du forum pour poster ton code ! (tu peux modifier ton post, lien modifier en haut à droite du post).

          int d1,d2;
      
          scanf("%f",&d1);
      
          scanf("%f",&d1);

      Pour scanf, le spécificateur de format pour un int c'est "%d" !

      -
      Edité par rouIoude 26 décembre 2023 à 11:34:39

      • Partager sur Facebook
      • Partager sur Twitter
      ...
        26 décembre 2023 à 11:58:59

        Bonjour,

        Le message qui suit est une réponse automatique activée par un membre de l'équipe de modération. Les réponses automatiques leur permettent d'éviter d'avoir à répéter de nombreuses fois la même chose, ce qui leur fait gagner du temps et leur permet de s'occuper des sujets qui méritent plus d'attention.
        Nous sommes néanmoins ouverts et si vous avez une question ou une remarque, n'hésitez pas à contacter la personne en question par Message Privé.

        Pour plus d'informations, nous vous invitons à lire les règles générales du forum

        Merci de colorer votre code à l'aide du bouton Code </>

        Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton  </> de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: php;">Votre code ici</pre>.

        Merci de modifier votre message d'origine en fonction.

        Liens conseillés

        • Partager sur Facebook
        • Partager sur Twitter
          26 décembre 2023 à 13:20:01

          rouIoude a écrit:

          Utilises le bouton code </> du forum pour poster ton code ! (tu peux modifier ton post, lien modifier en haut à droite du post).

              int d1,d2;
          
              scanf("%f",&d1);
          
              scanf("%f",&d1);

          Pour scanf, le spécificateur de format pour un int c'est "%d" !

          -
          Edité par rouIoude il y a environ 1 heure

          Merci ;)

          Malheureusement cela ne règle point mon problème.



          • Partager sur Facebook
          • Partager sur Twitter
            26 décembre 2023 à 16:04:41

            ..£ a écrit:

            Malheureusement cela ne règle point mon problème.

            Je n'ai pas débogué ton code (trop long mais tu peux le faire avec un débogueur).

            Je vois que tu as modifié ton code pour changer le type des variables et garder "%f", ça fait un beau mélange d'entiers et de flottants. 

            Mais si tu ne sais pas utiliser scanf, ça serait une des premières chose à faire avant de te lancer dans des code aussi conséquent. J'en vois aussi avec le spécificateur "%c", il est fort probable qu'il soit zappé par un '\n' restant dans le buffer clavier.

            Q : Est-ce normale que ta fonction boat est un paramètre non utilisé ?

            -
            Edité par rouIoude 26 décembre 2023 à 16:27:28

            • Partager sur Facebook
            • Partager sur Twitter
            ...
              26 décembre 2023 à 16:23:59

              rouIoude a écrit:

              ..£ a écrit:

              Malheureusement cela ne règle point mon problème.

              Je n'ai pas débogué ton code (trop long mais tu peux le faire avec un débogueur).

              Je vois que tu as modifié ton code pour changer le type des variables et garder "%f", ça fait un beau mélange d'entiers et de flottants. 

              Mais si tu ne sais pas utiliser scanf, ça serait une des premières chose à faire avant de te lancer dans des code aussi conséquent. J'en vois aussi avec le spécificateur "%c", il est fort probable qu'il soit zappé par un '\n' restant dans le buffer clavier.

              Q : Est-ce normale que ta fonction boat est un paramètre non utilisé ?

              EDIT : Je viens de le tester avec les deux problèmes que je t'ai mentionné corrigé (Mettre des entiers avec "%d" et mettre un espace avant le %c : " %c" pour manger le ''\n' du buffer clavier) et ça semble fonctionner.

              -
              Edité par rouIoude il y a moins de 30s

              Le paramètre non utilisé est en train d'êre tester en parallèle mais je ne met pas le reste du code sur le forum car je préfère garder le reste du code pour moi.

              • Partager sur Facebook
              • Partager sur Twitter
                26 décembre 2023 à 16:27:40

                Je viens de le tester avec les deux problèmes que je t'ai mentionné corrigé (Mettre des entiers avec "%d" et mettre un espace avant le %c : " %c" pour manger le ''\n' du buffer clavier) et ça semble fonctionner :

                Porte-avion de 5 cases :
                Avant du navire :
                Ligne (A-J) & Colonne (1-10) : A1
                
                Arriere du navire :
                Ligne (A-J) & Colonne (1-10) : A5
                | A  A  A  A  A                 |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                |                               |           |                              |
                • Partager sur Facebook
                • Partager sur Twitter
                ...
                  26 décembre 2023 à 16:34:00

                  Merci l'espace avant le %c marche. Je garde le %f car il me permet de savoir si la personne saisit bien un entier car sinon cela pourrait créer des exploits.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 décembre 2023 à 16:41:51

                    ..£ a écrit:

                    Je garde le %f car il me permet de savoir si la personne saisit bien un entier car sinon cela pourrait créer des exploits.

                    Il y a de bien meilleurs méthode pour les saisie sécurisées, mais bon, c'est pas le sujet.



                    • Partager sur Facebook
                    • Partager sur Twitter
                    ...

                    utilisation du printf scanf

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    • Editeur
                    • Markdown