Partage
  • Partager sur Facebook
  • Partager sur Twitter

Affichage d'un entier au format SSD

SSD : les chiffres tels qu'affichés dans une montre digitale

    20 avril 2008 à 18:22:37

    Ce message fait suite à une question suggérée dans le fil du message Petit exercice pour débutants et pour laquelle -ed- a proposé une réponse.


    Il s'agit d'écrire un programme permettant d'afficher un nombre avec ses chiffres écrits au format SSD (seven segment display).


    Je donne ci-dessous une version minimaliste, on pourrait corser en demandant à l'utilisateur de proposer un nombre ayant un nombre arbitraire de chiffres, de proposer une base de conversion et/ou de fournir la taille des chiffres pendant l'exécution du programme. Ce serait beaucoup plus substantiel que ce que je propose ci-dessous, je dirais de l'ordre 500/1000 lignes de code si on fait les choses proprement, j'avoue que j'ai pas le temps de me lancer là-dedans.



    Image utilisateur

    Voici le code, je pense qu'il nécessite quelques améliorations/rectifications. Le but est quand même de rester abordable pour des débutants.
    #include <stdio.h>
    
    #define N 32                    /* nombre max de chiffres */
    #define H 3                     /* hauteur d'un ssd */
    #define L 3                     /* largeur d'un ssd */
    #define ESPACE ' '
    #define BASE 10
    
    
    /* Retourne le nombre de chiffres de l'écriture en base base de x et remplit 
       le tableau des chiffres de x dans leur ordre d'apparition naturelle (le
       chiffre de poids fort au début) */
    int nb_chiffres(int x, int liste_chiffres[N], const int base)
    {
      int q = x;
      int resultat = 1, i = 0;
    
      do
        {
          liste_chiffres[i] = q % base;
          q /= base;
          i++;
        }
      while (q != 0);
      resultat = i;
    
      i = 0;
      /* On écrit dans l'autre sens la suite des chiffres */
      while (i < resultat - (i + 1))
        {
          int temp;
    
          temp = liste_chiffres[i];
          liste_chiffres[i] = liste_chiffres[resultat - (i + 1)];
          liste_chiffres[resultat - (i + 1)] = temp;
          i++;
        }
    
      return resultat;
    }
    
    /* Colle un chiffre au format ssd à la ligne 0 et colonne ind_col du tableau 
       t */
    void coller(int t[H][(L + 1) * N], int ind_col, char ssd[H][L + 1])
    {
      int ligne, colonne;
    
      for (ligne = 0; ligne < H; ligne++)
        {
          for (colonne = 0; colonne < L; colonne++)
            {
              t[ligne][ind_col + colonne] = ssd[ligne][colonne];
            }
          t[ligne][ind_col + colonne] = ESPACE;
        }
    
    }
    
    /* Convertit le nombre x en chiffres au format ssd dans un tableau 2D et
       affiche le tableau */
    void afficher_en_ssd(int x, char chiffres_ssd[BASE][H][L + 1], int base)
    {
      int chiffres[N];
      int i, n = nb_chiffres(x, chiffres, base);
      int t[H][(L + 1) * N];
    
      for (i = 0; i < n; i++)
        {
          int d = chiffres[i];
    
          coller(t, (L + 1) * i, chiffres_ssd[d]);
        }
    
      /* ===================== Affichage du nombre en ssd ============= */
      {
        int ligne, colonne;
    
        for (ligne = 0; ligne < H; ligne++)
          {
            for (colonne = 0; colonne < (L + 1) * n; colonne++)
              {
                printf("%c", t[ligne][colonne]);
              }
            printf("\n");
          }
        printf("\n");
      }
    }
    
    
    
    int main(void)
    {
    
    /* *INDENT-OFF* */
        /* le tableau de chiffres */
    char chiffres_ssd[BASE][H][L+1]=
    {
    /* zéro */
    {
    " _ ",
    "| | ",
    "|_| "
    },
    /* un */
    {
    "   ",
    "  | ",
    "  | "
    },/* deux */
    {
    " _ ",
    " _|",
    "|_ "
    },/* trois */
    {
    " _ ",
    " _| ",
    " _| "
    },/* quatre */
    {
    "   ",
    "|_| ",
    "  | "
    },/* cinq */
    {
    " _ ",
    "|_ ",
    " _| "
    },/* six */
    {
    " _ ",
    "|_ ",
    "|_| "
    },/* sept */
    {
    " _ ",
    "| | ",
    "  | "
    },/* huit */
    {
    " _ ",
    "|_| ",
    "|_| "
    },/* neuf */
    {
    " _ ",
    "|_| ",
    " _| "
    }
    };
    /* *INDENT-ON* */
    
      int x;
    
      printf("Entrer un entier (int) positif et ecrit en base 10 :\n");
      scanf("%d", &x);
    
      afficher_en_ssd(x, chiffres_ssd, BASE);
      return 0;
    }
    


    Voici également une alternative à la proposition d'utiliser un champ de bit pour représenter un "chiffre-ssd" et utilisant des opérateuurs bit à bit. Bon, je reconnais que c'est un peu lourd. En fait, ci-dessous un "chiffre-ssd" est représenté dans un unsigned char (1 byte donc).

    Pareil, le code est sans doute à améliorer/rectifier.

    Image utilisateur

    #include <stdio.h>
    #define BASE 10
    
    void afficher(int x)
    {
      int i = 0;
    
      printf(" ");
      (x & (1 << 0)) ? printf("_") : printf(" ");
      printf(" ");
      printf("\n");
      for (i = 0; i < 2; i++)
        {
          (x & (1 << (3*i + 1))) ? printf("|") : printf(" ");
          (x & (1 << (3*i + 2))) ? printf("_") : printf(" ");
          (x & (1 << (3*i + 3))) ? printf("|") : printf(" ");
          printf("\n");
        }
    }
    
    int main(void)
    {
      char s[7];
      unsigned char ssd[BASE];
    
      int i;
    
      for (i = 0; i < 7; i++)
        s[i] = 1 << i;
    
       /* *INDENT-OFF* */
    /*
    
     -------
    |   0   |
    |1     3|
    |   2   |
     -------
    |       |
    |4     6|
    |   5   |
     -------
    
    */
       /* *INDENT-ON* */
    
      ssd[0] = s[0] | s[1] | s[3] | s[4] | s[5] | s[6];
      ssd[1] = s[3] | s[6];
      ssd[2] = s[0] | s[2] | s[3] | s[4] | s[5];
      ssd[3] = s[0] | s[2] | s[3] | s[5] | s[6];
      ssd[4] = s[1] | s[2] | s[3] | s[6];
      ssd[5] = s[0] | s[1] | s[2] | s[5] | s[6];
      ssd[6] = s[0] | s[1] | s[2] | s[4] | s[5] | s[6];
      ssd[7] = s[0] | s[1] | s[3] | s[6];
      ssd[8] = s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6];
      ssd[9] = s[0] | s[1] | s[2] | s[3] | s[5] | s[6];
    
      for (i = 0; i < BASE; i++)
        {
          afficher(ssd[i]);
          printf("\n");
        }
    
    return 0;
    }
    



    • Partager sur Facebook
    • Partager sur Twitter
      21 avril 2008 à 14:15:47

      Je viens de bricoler ça :

      #include <limits.h>
      #include <stdio.h>
      
      void afficherChiffreSSD (unsigned int n);
      void afficherNombreHexSSD (unsigned int n);
      
      
      int main (void)
      {
         afficherNombreHexSSD (0xdeadbeef);
      
         return 0;
      }
      
      
      void afficherChiffreSSD (unsigned int n)
      {
         if (n > 15)
         {
            puts ("Chiffre invalide");
         }
         else
         {
            struct digit
            {                          /*  -------  */
               unsigned char const a;  /* |   a   | */
               unsigned char const b;  /* |f     b| */
               unsigned char const c;  /* |   g   | */
               unsigned char const d;  /*  -------  */
               unsigned char const e;  /* |       | */
               unsigned char const f;  /* |e     c| */
               unsigned char const g;  /* |   d   | */
            };                         /*  -------  */
            
            static struct digit const lut[] = {/* a  b  c  d  e  f  g */
                                         /* 0 */ {1, 1, 1, 1, 1, 1, 0},
                                         /* 1 */ {0, 1, 1, 0, 0, 0, 0},
                                         /* 2 */ {1, 1, 0, 1, 1, 0, 1},
                                         /* 3 */ {1, 1, 1, 1, 0, 0, 1},
                                         /* 4 */ {0, 1, 1, 0, 0, 1, 1},
                                         /* 5 */ {1, 0, 1, 1, 0, 1, 1},
                                         /* 6 */ {1, 0, 1, 1, 1, 1, 1},
                                         /* 7 */ {1, 1, 1, 0, 0, 0, 0},
                                         /* 8 */ {1, 1, 1, 1, 1, 1, 1},
                                         /* 9 */ {1, 1, 1, 1, 0, 1, 1},
                                         /* A */ {1, 1, 1, 0, 1, 1, 1},
                                         /* B */ {0, 0, 1, 1, 1, 1, 1},
                                         /* C */ {1, 0, 0, 1, 1, 1, 0},
                                         /* D */ {0, 1, 1, 1, 1, 0, 1},
                                         /* E */ {1, 0, 0, 1, 1, 1, 1},
                                         /* F */ {1, 0, 0, 0, 1, 1, 1}
                                              };
                              
            struct digit const segments = lut[n];
            
            if (segments.a == 1)
            {
               printf (" _");
            }
         
            putchar ('\n');
            
            if (segments.f == 1)
            {
               putchar ('|');
            }
            else
            {
               putchar (' ');
            }
         
            if (segments.g == 1)
            {
               putchar ('_');
            }
            else
            {
               putchar (' ');
            }
         
            if (segments.b == 1)
            {
               putchar ('|');
            }
         
            putchar ('\n');
            
            if (segments.e == 1)
            {
               putchar ('|');
            }
            else
            {
               putchar (' ');
            }
         
            if (segments.d == 1)
            {
               putchar ('_');
            }
            else
            {
               putchar (' ');
            }
         
            if (segments.c == 1)
            {
               putchar ('|');
            }
         
            putchar ('\n');
         }
      }
      
      
      void afficherNombreHexSSD (unsigned int n)
      {
         unsigned int i;
         unsigned int temp;
         
         for (i = 0; i < (sizeof n*CHAR_BIT)/4; ++i)
         {
            temp = n >> (sizeof n*CHAR_BIT - 4 - i*4);
            temp &= 0xF;
            afficherChiffreSSD (temp);
         }
      }
      


      J'ai réfléchi un peu à la suite mais j'ai la flemme de me lancer.
      • Partager sur Facebook
      • Partager sur Twitter
        21 avril 2008 à 18:18:41

        Citation : dap

        Je viens de bricoler ça :



        Le traitement de l'affichage des chiffres est assez sobre. Par contre, pour l'affichage d'exemples, c'est dommage qu'on ait pas que des chiffres significatifs (tu affiches les zéros "avant" l'entier) et en outre les chiffres ne sont pas côte à côte. Pour être portable ton exemple devrait utiliser des unsigned long int. En outre l'affichage des chiffres ne serait pas complet si sizeof n*CHAR_BIT (qui est curieusement écrit sans parenthèses bien que ce soit correct, les opérateurs unaires ayant une priorité supérieure aux opérateurs binaires) n'est pas multiple de 4.
        • Partager sur Facebook
        • Partager sur Twitter
          21 avril 2008 à 22:18:25

          D'après http://www.siteduzero.com/forum-83-265 [...] html#r2404444 (le 1er code), affichage en hexa :

          Corrections de types...
          #include <stdio.h>
          
          #define N 32                    /* nombre max de chiffres */
          #define H 3                     /* hauteur d'un ssd */
          #define L 3                     /* largeur d'un ssd */
          #define ESPACE ' '
          
          typedef unsigned long ulong;
          typedef unsigned int uint;
          
          
          
          /* Retourne le nombre de chiffres de l'écriture en base base de x et remplit
             le tableau des chiffres de x dans leur ordre d'apparition naturelle (le
             chiffre de poids fort au début) */
          int nb_chiffres (int x, int liste_chiffres[N], const uint base)
          {
             int q = x;
             int resultat = 1, i = 0;
          
             do
             {
                liste_chiffres[i] = q % base;
                q /= base;
                i++;
             }
             while (q != 0);
             resultat = i;
          
             i = 0;
             /* On écrit dans l'autre sens la suite des chiffres */
             while (i < resultat - (i + 1))
             {
                int temp;
          
                temp = liste_chiffres[i];
                liste_chiffres[i] = liste_chiffres[resultat - (i + 1)];
                liste_chiffres[resultat - (i + 1)] = temp;
                i++;
             }
          
             return resultat;
          }
          
          /* Colle un chiffre au format ssd à la ligne 0 et colonne ind_col du tableau
             t */
          void coller (int t[H][(L + 1) * N], int ind_col, char const ssd[H][L + 1])
          {
             int ligne, colonne;
          
             for (ligne = 0; ligne < H; ligne++)
             {
                for (colonne = 0; colonne < L; colonne++)
                {
                   t[ligne][ind_col + colonne] = ssd[ligne][colonne];
                }
                t[ligne][ind_col + colonne] = ESPACE;
             }
          
          }
          
          /* Convertit le nombre x en chiffres au format ssd dans un tableau 2D et
             affiche le tableau */
          void afficher_en_ssd (int x, int base)
          {
          
          /* *INDENT-OFF* */
              /* le tableau de chiffres */
          static char const chiffres_ssd[][H][L+1]=
          {
          /* zéro */
          {
          " _ ",
          "| | ",
          "|_| "
          },
          /* un */
          {
          "   ",
          "  | ",
          "  | "
          },/* deux */
          {
          " _ ",
          " _|",
          "|_ "
          },/* trois */
          {
          " _ ",
          " _| ",
          " _| "
          },/* quatre */
          {
          "   ",
          "|_| ",
          "  | "
          },/* cinq */
          {
          " _ ",
          "|_ ",
          " _| "
          },/* six */
          {
          " _ ",
          "|_ ",
          "|_| "
          },/* sept */
          {
          " _ ",
          "| | ",
          "  | "
          },/* huit */
          {
          " _ ",
          "|_| ",
          "|_| "
          },/* neuf */
          {
          " _ ",
          "|_| ",
          " _| "
          },
          {
          " _ ",
          "|_| ",
          "| | "
          },
          {
          "   ",
          "|_  ",
          "|_| "
          },
          {
          " _ ",
          "|   ",
          "|_  "
          },
          {
          "   ",
          " _| ",
          "|_| "
          },
          {
          " _ ",
          "|_  ",
          "|_  "
          },
          {
          " _ ",
          "|_  ",
          "|   "
          }
          };
          /* *INDENT-ON* */
          
             int chiffres[N];
             int i, n = nb_chiffres (x, chiffres, base);
             int t[H][(L + 1) * N];
          
             for (i = 0; i < n; i++)
             {
                int d = chiffres[i];
          
                coller (t, (L + 1) * i, chiffres_ssd[d]);
             }
          
             /* ===================== Affichage du nombre en ssd ============= */
             {
                int ligne, colonne;
          
                for (ligne = 0; ligne < H; ligne++)
                {
                   for (colonne = 0; colonne < (L + 1) * n; colonne++)
                   {
                      printf ("%c", t[ligne][colonne]);
                   }
                   printf ("\n");
                }
                printf ("\n");
             }
          }
          
          int main (void)
          {
             ulong x = 0xDEADBEEF;
          #if 1
             printf ("Entrer un entier positif et ecrit en base 10 :\n");
             scanf ("%lu", &x);
          #endif
          
             afficher_en_ssd (x,  16);
             return 0;
          }
          

          Entrer un entier positif et ecrit en base 10 :
          1234567890
               _   _   _   _   _       _
          |_| |_| |_| |_  | |  _|  _|  _|
            |  _|  _| |_| |_| |_  |_| |_
          
          
          Press ENTER to continue.
          
          Entrer un entier positif et ecrit en base 10 :
          3735928559
               _   _           _   _   _
           _| |_  |_|  _| |_  |_  |_  |_
          |_| |_  | | |_| |_| |_  |_  |
          
          
          Press ENTER to continue.
          Entrer un entier positif et ecrit en base 10 :
          4294967295
           _   _   _   _   _   _   _   _
          |_  |_  |_  |_  |_  |_  |_  |_
          |   |   |   |   |   |   |   |
          
          
          Press ENTER to continue.

          • Partager sur Facebook
          • Partager sur Twitter
          Music only !
            22 avril 2008 à 2:03:11

            Citation : -ed-

            D'après http://www.siteduzero.com/forum-83-265 [...] html#r2404444 (le 1er code), affichage en hexa :



            Merci de ce complément qui me donne l'occasion de me rendre compte qu'il n'était pas nécessaire de faire des copies d'écran ainsi que j'avais fait.

            Maintenant, l'étape suivante serait de faire un affichage à taille modulable pendant l'exécution (donc plus de tableaux statiques), les tailles étant fournies par l'utilisateur. L'idéal serait bien sûr de garder le code déjà écrit, en particulier les tableaux 3x3 des gabarits des chiffres.

            L'étape suivante serait d'accepter n'importe quel nombre (de longueur quelconque) et l'étape ultime serait d'avoir un programme optimisé.

            Je préviens tout de suite que je ne m'y lance pas (1), c'est pas très dur, c'est pas super exitant et c'est assez laborieux et donc ça prend du temps.


            (1) ou pas pour l'instant en tout cas.
            • Partager sur Facebook
            • Partager sur Twitter

            Affichage d'un entier au format SSD

            × 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