Simulating a seven-segment display

Discussion in 'C Programming' started by Felipe Ribeiro, Jul 1, 2009.

  1. Hi everybody,

    I wrote a small program that simulates the effect of a seven-segment
    display and would like to know if I can do anything to improve it.
    Here's the code:

    ====================================
    #include <stdio.h>

    #define MAX_DIGITS 10
    #define HEIGHT_DIGIT 3

    /* External variables */
    /*
    * 'segments' stores the seven-segment representaion of each number.
    * The representation is done in the following way:
    *
    * 1__2__3
    * | |
    * 4 6
    * |__5__|
    * | |
    * 7 9
    * |__8__|
    *
    * '*' determines that a segment is necessary in a given position
    while
    * ' ' detrmines that no segment should be printed and a blank is
    * printed instead.
    */
    const char segments[10][9] =
    {{' ', '*', ' ', '*', ' ', '*', '*', '*', '*'},
    {' ', ' ', ' ', ' ', ' ', '*', ' ', ' ', '*'},
    {' ', '*', ' ', ' ', '*', '*', '*', '*', ' '},
    {' ', '*', ' ', ' ', '*', '*', ' ', '*', '*'},
    {' ', ' ', ' ', '*', '*', '*', ' ', ' ', '*'},
    {' ', '*', ' ', '*', '*', ' ', ' ', '*', '*'},
    {' ', '*', ' ', '*', '*', ' ', '*', '*', '*'},
    {' ', '*', ' ', ' ', ' ', '*', ' ', ' ', '*'},
    {' ', '*', ' ', '*', '*', '*', '*', '*', '*'},
    {' ', '*', ' ', '*', '*', '*', ' ', '*', '*'}};
    /*
    * 'digits' will store only the seven-segment representation of the
    * digits entered by the user. Each digit is 3 characters high and 3
    * characters wide.
    */
    char digits[HEIGHT_DIGIT][MAX_DIGITS * 4];

    /* Prototypes */
    void process_digit(int digit, int position);
    void print_digits_array(void);

    /*
    * Calls 'process_digit' and 'print_digits_array' repeatedly.
    */
    int main(void)
    {
    char digit_ch;
    int digit, i = 0;

    printf("Enter a number: ");
    do {
    /*
    * The user may enter a non-numerical character but it's gonna
    * be ignored.
    */
    digit_ch = getchar();
    digit = digit_ch - '0';

    if (0 <= digit && digit <= 9) {
    process_digit(digit, i);
    i++;
    }
    } while (i < MAX_DIGITS && digit_ch != '\n');

    print_digits_array();

    return 0;
    }

    /*
    * Treats the digit entered by the user. 'digits' will receive the
    data
    * stored in 'segments' according to the number entered by the user.
    * For instance; if the number one is entered, then all the
    information
    * in row one of the 'segments' array will be passed to the 'digits'
    * array.
    */
    void process_digit(int digit, int position)
    {
    int start, end;
    int i, j = 0;

    start = position * 4;
    end = start + 3;
    for (i = 0; i < HEIGHT_DIGIT; i++)
    for (start = position * 4; start < end; start++) {
    digits[start] = segments[digit][j];
    j++;
    }
    }

    /*
    * Surprisingly, it prints the 'digits' array.
    */
    void print_digits_array(void)
    {
    int i, j;

    for (i = 0; i < HEIGHT_DIGIT; i++) {
    for (j = 0; j < MAX_DIGITS * 4; j++)
    if (digits[j] == '*' && j % 2 == 0)
    printf("|");
    else if (digits[j] == '*')
    printf("_");
    else
    printf(" ");
    printf("\n");
    }
    }
    ====================================

    I don't know if I chose the best way to do it. Problably not, since
    I'm just learning. :)
    My segments array specially causes me some doubts. Each row stores
    information about a digit and it does so using 9 positions instead of
    7. I wasn't able to figure out a way to solve the problem using just 7
    segments.

    I'd appreciate any advice. :)
    Thank in advance.

    Felipe
     
    Felipe Ribeiro, Jul 1, 2009
    #1
    1. Advertising

  2. Felipe Ribeiro <> wrote:
    > I wrote a small program that simulates the effect of a
    > seven-segment display and would like to know if I can
    > do anything to improve it.
    > Here's the code:

    <snip>
    >         char digit_ch;
    > ...
    >                 digit_ch = getchar();


    There is a FAQ discussing why digit_ch should be an int.
    ....And why you should check the return value.

    >                 digit = digit_ch - '0';

    <snip>

    You seemed to have over complicated things a little.

    % type 7seg.c
    #include <stdio.h>

    const char seg_row[3][10][3] =
    {
    { " _ "," "," _ "," _ "," "," _ "," _ "," _ "," _ "," _ " },
    { "| |"," |"," _|"," _|","|_|","|_ ","|_ "," |","|_|","|_|" },
    { "|_|"," |","|_ "," _|"," |"," _|","|_|"," |","|_|"," _|" }
    };

    #define countof(x) ((size_t) (sizeof(x) / sizeof *(x)))

    int main(int argc, char **argv)
    {
    size_t r;
    const char *s;

    if (argc)
    while (argv++, --argc)
    for (r = 0; r < countof(seg_row); r++, puts(""))
    for (s = *argv; *s; s++)
    if ('0' <= *s && *s <= '9')
    printf("%.*s", (int) countof(seg_row[0][0]),
    seg_row[r][*s - '0']);

    return 0;
    }

    % acc 7seg.c -o 7seg.exe

    % 7seg 1234567890 "2009/07/01"
    _ _ _ _ _ _ _ _
    | _| _||_||_ |_ ||_||_|| |
    ||_ _| | _||_| ||_| _||_|
    _ _ _ _ _ _ _
    _|| || ||_|| | || | |
    |_ |_||_| _||_| ||_| |

    %

    --
    Peter
     
    Peter Nilsson, Jul 1, 2009
    #2
    1. Advertising

  3. Felipe Ribeiro

    luserXtrog Guest

    On Jun 30, 10:11 pm, Felipe Ribeiro <> wrote:
    > Hi everybody,
    >
    > I wrote a small program that simulates the effect of a seven-segment
    > display and would like to know if I can do anything to improve it.
    > Here's the code:
    >


    <snipped longish code, though I am one to say so>

    > I don't know if I chose the best way to do it. Problably not, since
    > I'm just learning. :)
    > My segments array specially causes me some doubts. Each row stores
    > information about a digit and it does so using 9 positions instead of
    > 7. I wasn't able to figure out a way to solve the problem using just 7
    > segments.
    >
    > I'd appreciate any advice. :)
    > Thank in advance.


    As another nother way, here's my go:

    #include <ctype.h>
    #include <stdio.h>
    int main(int c, char **v) {
    for (;c>1; c--, v++) {
    /* _
    |_|
    |_| bits 0-7 :: segs a-g */
    int segs[] = { 077, 006, 0133, 0117, 0146, 0155, 0175, 007,
    0177, 0147 };
    int mask[] = { 01, 0142, 034 };
    int lbar = 060;
    int rbar = 006;
    int und = 0111;
    int i;
    for (i=0; i < sizeof(mask)/sizeof(*mask) /*3*/; i++) {
    int j;
    for (j=0; v[1][j]; j++) {
    int c;
    c = v[1][j];
    if (!isdigit(c)) fprintf(stderr, "bogus input\n");
    c -= '0';
    if (i == 0) {
    putchar(' ');
    if (segs[c] & mask & und) putchar('_');
    else putchar(' ');
    putchar(' ');
    } else {
    if (segs[c] & mask & lbar) putchar('|');
    else putchar(' ');
    if (segs[c] & mask & und) putchar('_');
    else putchar(' ');
    if (segs[c] & mask & rbar) putchar('|');
    else putchar(' ');
    }
    }
    putchar('\n');
    }
    }
    return 0;
    }

    After a glance at Peter's output and a skim through the wikipedia
    entry, octal seems perfect for this size ascii rendition.
    For your bigger dimensions, it might still be straightforward
    to pack it into hex numbers.

    I wasn't entirely happy with the result once I got to the middle
    of the loop. And the error behavior is nothing to write home about.

    I plead insomnia.

    fwiw

    --
    lxt
     
    luserXtrog, Jul 1, 2009
    #3
  4. On Jul 1, 5:47 am, luserXtrog <> wrote:

    <snip>
    >
    > As another nother way, here's my go:
    >
    > #include <ctype.h>
    > #include <stdio.h>
    > int main(int c, char **v) {
    >     for (;c>1; c--, v++) {
    >         /* _
    >           |_|
    >           |_| bits 0-7 :: segs a-g */
    >         int segs[] = { 077, 006, 0133, 0117, 0146, 0155, 0175, 007,
    > 0177, 0147 };
    >         int mask[] = { 01, 0142, 034 };
    >         int lbar = 060;
    >         int rbar = 006;
    >         int und = 0111;
    >         int i;
    >         for (i=0; i < sizeof(mask)/sizeof(*mask) /*3*/; i++) {
    >             int j;
    >             for (j=0; v[1][j]; j++) {
    >                 int c;
    >                 c = v[1][j];
    >                 if (!isdigit(c)) fprintf(stderr, "bogus input\n");
    >                 c -= '0';
    >                 if (i == 0) {
    >                     putchar(' ');
    >                     if (segs[c] & mask & und) putchar('_');
    >                     else putchar(' ');
    >                     putchar(' ');
    >                 } else {
    >                     if (segs[c] & mask & lbar) putchar('|');
    >                     else putchar(' ');
    >                     if (segs[c] & mask & und) putchar('_');
    >                     else putchar(' ');
    >                     if (segs[c] & mask & rbar) putchar('|');
    >                     else putchar(' ');
    >                 }
    >             }
    >             putchar('\n');
    >         }
    >     }
    >     return 0;
    >
    > }
    >

    I'm sorry but I can't really understand your program since I haven't
    seen pointers yet.

    <snip>

    As for the way I used to represent the digits, I simply couldn't
    figure out a way to store the 'segments' array into 'digits' properly
    using just 7 segments.
     
    Felipe Ribeiro, Jul 1, 2009
    #4
  5. Felipe Ribeiro <> wrote:
    > luserXtrog <> wrote:
    > > As another nother way, here's my go:

    <snip>
    > I'm sorry but I can't really understand your program
    > since I haven't seen pointers yet.
    >
    > <snip>
    >
    > As for the way I used to represent the digits, I simply
    > couldn't figure out a way to store the 'segments' array
    > into 'digits' properly using just 7 segments.


    % type 7seg_2.c
    #include <stdio.h>

    #define countof(x) ((size_t) (sizeof(x) / sizeof *(x)))

    typedef unsigned char mask_t;

    enum segments
    {
    S1,
    S2, S3,
    S4,
    S5, S6,
    S7, S8,

    M1 = 1 << S1,
    M2 = 1 << S2,
    M3 = 1 << S3,
    M4 = 1 << S4,
    M5 = 1 << S5,
    M6 = 1 << S6,
    M7 = 1 << S7,
    M8 = 1 << S8
    };

    struct display_char
    {
    mask_t mask;
    char out;
    };

    #define BLANK ' '

    #if 0
    const struct display_char font[3][3] =
    {
    { { 0, 0 }, { M1, '_' }, { 0, 0 } },
    { { M2, '|' }, { M4, '_' }, { M3, '|' } },
    { { M5, '|' }, { M7, '_' }, { M6, '|' } }
    };
    #else
    const struct display_char font[5][5] =
    {
    { { 0, 0 }, {M1,'_'}, {M1, '_'}, { 0, 0 }, { 0, 0 } },
    { {M2,'|'}, { 0, 0 }, { 0, 0 }, {M3, '|'}, { 0, 0 } },
    { {M2,'|'}, {M4,'_'}, {M4, '_'}, {M3, '|'}, { 0, 0 } },
    { {M5,'|'}, { 0, 0 }, { 0, 0 }, {M6, '|'}, { 0, 0 } },
    { {M5,'|'}, {M7,'_'}, {M7, '_'}, {M6, '|'}, {M8,'.'} }
    };
    #endif

    const mask_t digit[10] =
    {
    /* 0 */ M1 + M2 + M3 + M5 + M6 + M7,
    /* 1 */ M3 + M6 ,
    /* 2 */ M1 + M3 + M4 + M5 + M7,
    /* 3 */ M1 + M3 + M4 + M6 + M7,
    /* 4 */ M2 + M3 + M4 + M6 ,
    /* 5 */ M1 + M2 + M4 + M6 + M7,
    /* 6 */ M1 + M2 + M4 + M5 + M6 + M7,
    /* 7 */ M1 + M3 + M6 ,
    /* 8 */ M1 + M2 + M3 + M4 + M5 + M6 + M7,
    /* 9 */ M1 + M2 + M3 + M4 + M6 + M7,
    };

    int main(int argc, char *argv[])
    {
    int i;
    size_t j, r, c;
    mask_t m;

    for (i = 1; i < argc; i++)
    for (r = 0; r < countof(font); r++, puts(""))
    for (j = 0; argv[j] != 0; j++)
    if ('0' <= argv[j] && argv[j] <= '9')
    for (c = 0; c < countof(font[r]); c++)
    {
    m = digit[argv[j] - '0'];
    if (argv[j + 1] == '.') m |= M8;

    if (font[r][c].mask & m)
    putchar(font[r][c].out);
    else
    putchar(BLANK);
    }

    return 0;
    }

    % acc 7seg_2.c -o 7seg_2.exe

    % 7seg_2.exe 3.14159265 "2009.07.02"
    __ __ __ __ __ __
    | | | | | | | | | | |
    __| | |__| | |__ |__| __| |__ |__
    | | | | | | | | | |
    __|. | | | __| __| |__ |__| __|
    __ __ __ __ __ __ __ __
    | | | | | | | | | | | | |
    __| | | | | |__| | | | | | __|
    | | | | | | | | | | | |
    |__ |__| |__| __|.|__| |.|__| |__

    %

    --
    Peter
     
    Peter Nilsson, Jul 2, 2009
    #5
  6. Felipe Ribeiro

    luserXtrog Guest

    On Jul 1, 11:26 am, Felipe Ribeiro <> wrote:
    > On Jul 1, 5:47 am, luserXtrog <> wrote:
    >
    > <snip>
    >
    >
    >
    > > As another nother way, here's my go:

    >
    > > #include <ctype.h>
    > > #include <stdio.h>
    > > int main(int c, char **v) {
    > >     for (;c>1; c--, v++) {
    > >         /* _
    > >           |_|
    > >           |_| bits 0-7 :: segs a-g */
    > >         int segs[] = { 077, 006, 0133, 0117, 0146, 0155, 0175, 007,
    > > 0177, 0147 };
    > >         int mask[] = { 01, 0142, 034 };
    > >         int lbar = 060;
    > >         int rbar = 006;
    > >         int und = 0111;
    > >         int i;
    > >         for (i=0; i < sizeof(mask)/sizeof(*mask) /*3*/; i++) {
    > >             int j;
    > >             for (j=0; v[1][j]; j++) {
    > >                 int c;
    > >                 c = v[1][j];
    > >                 if (!isdigit(c)) fprintf(stderr, "bogus input\n");
    > >                 c -= '0';
    > >                 if (i == 0) {
    > >                     putchar(' ');
    > >                     if (segs[c] & mask & und) putchar('_');
    > >                     else putchar(' ');
    > >                     putchar(' ');
    > >                 } else {
    > >                     if (segs[c] & mask & lbar) putchar('|');
    > >                     else putchar(' ');
    > >                     if (segs[c] & mask & und) putchar('_');
    > >                     else putchar(' ');
    > >                     if (segs[c] & mask & rbar) putchar('|');
    > >                     else putchar(' ');
    > >                 }
    > >             }
    > >             putchar('\n');
    > >         }
    > >     }
    > >     return 0;

    >
    > > }

    >
    > I'm sorry but I can't really understand your program since I haven't
    > seen pointers yet.


    I think I'm not using any pointers. Ok, I see it.
    sizeof(*mask) is the same as sizeof(mask[0]) or sizeof(int).
    That's just to get the number of elements in the mask array
    to avoid using constants all over the place (there were enough
    of them in the arrays).

    It loops over the three elements of mask (which select the bits
    from the segs relevant to the three output lines) and within that,
    it loops over the string to be displayed. On the first line
    it prints space, underscore (if the digit has one), space.
    On the other two lines it prints a bar (if the digit has one),
    an underscore (if...), and another bar (if...).

    To understand the segs array, you have to imagine the template:

    _ a . .
    ..| b f |.. ._. g
    ..| c e |_. ...
    d

    where the bits are laid out in ascending order.
    So an octal number nicely encodes the abc def g, but backwards
    g fed cba. So '0' having abcdef but no g, is 077. '8' is 0177
    to add the g. '7' ends up being 07! I obfuscated that to 007
    for obvious reasons.

    > <snip>
    >
    > As for the way I used to represent the digits, I simply couldn't
    > figure out a way to store the 'segments' array into 'digits' properly
    > using just 7 segments


    Perhaps because of the size you've chosen. If you have a try
    at the smaller sized version, it may help that each segment
    only controls one character.

    I now think it might be fun to do it by allocating a multi-line
    buffer and bitblt the shapes into it.

    --
    lxt
     
    luserXtrog, Jul 2, 2009
    #6
  7. Felipe Ribeiro

    0m Guest

    On Jul 1, 12:28 pm, Peter Nilsson <> wrote:
    > const char seg_row[3][10][3] =
    > {
    > { " _ "," "," _ "," _ "," "," _ "," _ "," _ "," _ "," _ " },
    > { "| |"," |"," _|"," _|","|_|","|_ ","|_ "," |","|_|","|_|" },
    > { "|_|"," |","|_ "," _|"," |"," _|","|_|"," |","|_|"," _|" }
    > };
    >


    The microsoft c++ compiler doesn't recognise this piece unless it's
    changed to this:

    const char *seg_row[3][10]
     
    0m, Jul 2, 2009
    #7
  8. Felipe Ribeiro

    luserXtrog Guest

    On Jul 1, 6:21 pm, Peter Nilsson <> wrote:
    > Felipe Ribeiro <> wrote:
    > > luserXtrog <> wrote:
    > > > As another nother way, here's my go:

    > <snip>
    > > I'm sorry but I can't really understand your program
    > > since I haven't seen pointers yet.

    >
    > > <snip>

    >
    > > As for the way I used to represent the digits, I simply
    > > couldn't figure out a way to store the 'segments' array
    > > into 'digits' properly using just 7 segments.

    >
    >   % type 7seg_2.c
    >   #include <stdio.h>
    >

    <cut>

    Genius!

    --
    lxt
     
    luserXtrog, Jul 2, 2009
    #8
  9. Felipe Ribeiro

    0m Guest

    On Jul 2, 12:24 pm, "0m"
    <> wrote:
    > On Jul 1, 12:28 pm, Peter Nilsson <> wrote:
    >
    > >   const char seg_row[3][10][3] =
    > >   {
    > >     { " _ ","   "," _ "," _ ","   "," _ "," _ "," _ "," _ "," _ " },
    > >     { "| |","  |"," _|"," _|","|_|","|_ ","|_ ","  |","|_|","|_|" },
    > >     { "|_|","  |","|_ "," _|","  |"," _|","|_|","  |","|_|"," _|" }
    > >   };

    >
    > The microsoft c++ compiler doesn't recognise this piece unless it's
    > changed to this:
    >
    >     const char *seg_row[3][10]


    sorry, c++ is off-topic here.
     
    0m, Jul 2, 2009
    #9
  10. Felipe Ribeiro

    0m Guest

    On Jul 2, 1:30 pm, "0m"
    <> wrote:
    > On Jul 2, 12:24 pm, "0m"
    >
    > <> wrote:
    > > On Jul 1, 12:28 pm, Peter Nilsson <> wrote:

    >
    > > >   const char seg_row[3][10][3] =
    > > >   {
    > > >     { " _ ","   "," _ "," _ ","   "," _ "," _ "," _ "," _ "," _ " },
    > > >     { "| |","  |"," _|"," _|","|_|","|_ ","|_ ","  |","|_|","|_|" },
    > > >     { "|_|","  |","|_ "," _|","  |"," _|","|_|","  |","|_|"," _|" }
    > > >   };

    >
    > > The microsoft c++ compiler doesn't recognise this piece unless it's
    > > changed to this:

    >
    > >     const char *seg_row[3][10]

    >
    > sorry, c++ is off-topic here.


    $ cat a.c
    /* a.c */

    static const char segs[16][7 + 1] =
    {
    "ABCDEF ", /* 0 */
    " BC ", /* 1 */
    "AB DE G", /* 2 */
    "ABCD G", /* 3 */
    " BC FG", /* 4 */
    "A CD FG", /* 5 */
    "A CDEFG", /* 6 */
    "ABC ", /* 7 */
    "ABCDEFG", /* 8 */
    "ABC FG", /* 9 */
    "ABC EFG", /* 0xA */
    " CDEFG", /* 0xB */
    "A DEF ", /* 0xC */
    " BCDE G", /* 0xD */
    "A DEFG", /* 0xE */
    "A EFG", /* 0xF */
    };

    void lightup(char seg[5][3], const char c)
    {
    char i, *p;

    if (c >= '0' && c <= '9') i = c - '0';
    else if (c >= 'A' && c <= 'Z') i = c - 'A' + 10;
    else if (c >= 'a' && c <= 'z') i = c - 'a' + 10;
    p = segs;
    while (*p){
    switch(*p++){
    case 'A':
    seg[0][1] = '_';
    break;
    case 'B':
    seg[1][2] = '|';
    break;
    case 'C':
    seg[3][2] = '|';
    break;
    case 'D':
    seg[4][1] = '_';
    break;
    case 'E':
    seg[3][0] = '|';
    break;
    case 'F':
    seg[1][0] = '|';
    break;
    case 'G':
    seg[2][1] = '_';
    break;
    }
    }
    }

    void showup(char seg[5][3], int lncnt, int clcnt)
    {
    int i, j;
    for (i = 0; i != lncnt; i++){
    for (j = 0; j != clcnt; j++){
    printf("%c", seg[j]);
    }
    printf("\n");
    }
    }

    void cleanup(char seg[5][3], int lncnt, int clcnt)
    {
    int i, j;
    for (i = 0; i != lncnt; i++){
    for (j = 0; j != clcnt; j++){
    seg[j] = ' ';
    }
    }
    }

    #include <stdio.h>
    int main(void)
    {
    char seg[5][3] =
    {
    " ",
    " ",
    " ",
    " ",
    " "
    };

    lightup(seg, '8');
    showup(seg, 5, 3);
    cleanup(seg, 5, 3);
    printf("\n");
    lightup(seg, 'b');
    showup(seg, 5, 3);

    return 0;
    }
    $
    $ make && ./a.out 123
    make: `a.out' is up to date.
    _
    | |
    _
    | |
    _


    |
    _
    | |
    _
    $
     
    0m, Jul 2, 2009
    #10
  11. Felipe Ribeiro

    luserXtrog Guest

    On Jul 1, 6:21 pm, Peter Nilsson <> wrote:
    > Felipe Ribeiro <> wrote:
    > > luserXtrog <> wrote:
    > > > As another nother way, here's my go:

    > <snip>
    > > I'm sorry but I can't really understand your program
    > > since I haven't seen pointers yet.

    >
    > > <snip>

    >
    > > As for the way I used to represent the digits, I simply
    > > couldn't figure out a way to store the 'segments' array
    > > into 'digits' properly using just 7 segments.

    >
    >   % type 7seg_2.c


    <snip indimidating example which I looted for the font idea>

    >   % 7seg_2.exe 3.14159265 "2009.07.02"
    >    __                  __   __   __   __   __
    >      |    | |  |    | |    |  |    | |    |
    >    __|    | |__|    | |__  |__|  __| |__  |__
    >      |    |    |    |    |    | |    |  |    |
    >    __|.   |    |    |  __|  __| |__  |__|  __|
    >    __   __   __   __   __   __   __   __
    >      | |  | |  | |  | |  |    | |  |    |
    >    __| |  | |  | |__| |  |    | |  |  __|
    >   |    |  | |  |    | |  |    | |  | |
    >   |__  |__| |__|  __|.|__|    |.|__| |__
    >
    >   %


    One more for the road. Bigger and bAdDER.
    I forgot to address decimal points. Oh Well.

    600(1)12:23 PM:~ 0> cat 7seg3.c
    #include <stdio.h>
    #include <string.h>

    #define dim(x) (sizeof(x)/sizeof*(x))

    int ao(int c) {
    switch(c) {
    case '0':return 0;
    case '1':return 1;
    case '2':return 2;
    case '3':return 3;
    case '4':return 4;
    case '5':return 5;
    case '6':return 6;
    case '7':return 7;
    case '8':return 8;
    case '9':return 9;
    case 'A':case 'a':return 10;
    case 'B':case 'b':return 11;
    case 'C':case 'c':return 12;
    case 'D':case 'd':return 13;
    case 'E':case 'e':return 14;
    case 'F':case 'f':return 15;
    default:return -1;
    }
    }

    enum {
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    F = 1 << 5,
    G = 1 << 6,
    H = 1 << 7 };

    int seg[] = {
    /*0*/ A|B|C|D|E|F,
    /*1*/ B|C,
    /*2*/ A|B| D|E| G,
    /*3*/ A|B|C|D| G,
    /*4*/ B|C| F|G,
    /*5*/ A| C|D| F|G,
    /*6*/ A| C|D|E|F|G,
    /*7*/ A|B|C,
    /*8*/ A|B|C|D|E|F|G,
    /*9*/ A|B|C| F|G,
    /*A*/ A|B|C| E|F|G,
    /*b*/ C|D|E|F|G,
    /*C*/ A| D|E|F,
    /*d*/ B|C|D|E| G,
    /*E*/ A| D|E|F|G,
    /*F*/ A| E|F|G,
    };

    struct font {
    int disp, trig;
    };
    /* _
    |_|
    |_|
    */
    struct font font3[3][3] = {
    { { 0,0}, {'_',A}, { 0,0} },
    { {'|',F}, {'_',G}, {'|',B} },
    { {'|',E}, {'_',D}, {'|',C} },
    };
    /*
    ___
    | |
    |___|
    | |
    |___|
    */
    struct font font5[5][5] = {
    { { 0,0}, {'_',A}, {'_',A}, {'_',A}, { 0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, {'|',B} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'|',B} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, {'|',C} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'|',C} }
    };
    /*
    ----
    | |
    | |
    | |
    ----
    | |
    | |
    | |
    ----
    */
    struct font font9[9][7] = {
    { { 0,0}, {'_',A}, {'_',A}, {'_',A}, {'_',A}, { 0,0}, {0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'_',G}, {'|',B}, {0,0} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'_',D}, {'|',C}, {0,0} },
    };

    #define font_and_dims(x) (struct font *)x, dim(x), dim(*x)

    int print(char *s, struct font *font, int dimy, int dimx) {
    int row, col;
    char *sp;
    for (row = 0; row < dimy; row++) {
    for (sp = s; *sp; sp++) {
    for (col = 0; col < dimx; col++) {
    putchar( seg[ao(*sp)] & font[row*dimx+col].trig ?
    font[row*dimx+col].disp : ' ');
    }
    }
    putchar('\n');
    }
    };

    int main(int ac, char **av) {
    for (++av,--ac;ac;ac--,av++) {
    if (strspn(*av, "0123456789abcdefABCDEF") != strlen(*av))
    fprintf(stderr, "Hex only!\n");
    else
    print(*av, font_and_dims(font9));
    }

    return 0;
    }
    601(1)12:39 PM:~ 0> 7seg3 badf00
    ____ ____ ____ ____
    | | | | | | | | |
    | | | | | | | | |
    | | | | | | | | |
    |____ |____| ____| |____ | | | |
    | | | | | | | | | | |
    | | | | | | | | | | |
    | | | | | | | | | | |
    |____| | | |____| | |____| |____|

    --
    lxt
     
    luserXtrog, Jul 18, 2009
    #11
  12. Felipe Ribeiro

    luserXtrog Guest

    Font change option!

    714(1)12:54 AM:~ 0> cat 7seg3.c
    #include <stdio.h>
    #include <string.h>

    int ao(int c) {
    switch(c) {
    case '0':return 0;
    case '1':return 1;
    case '2':return 2;
    case '3':return 3;
    case '4':return 4;
    case '5':return 5;
    case '6':return 6;
    case '7':return 7;
    case '8':return 8;
    case '9':return 9;
    case 'A':case 'a':return 10;
    case 'B':case 'b':return 11;
    case 'C':case 'c':return 12;
    case 'D':case 'd':return 13;
    case 'E':case 'e':return 14;
    case 'F':case 'f':return 15;
    default:return -1;
    }
    }

    enum {
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    F = 1 << 5,
    G = 1 << 6,
    H = 1 << 7 };

    int seg[] = {
    /*0*/ A|B|C|D|E|F,
    /*1*/ B|C,
    /*2*/ A|B| D|E| G,
    /*3*/ A|B|C|D| G,
    /*4*/ B|C| F|G,
    /*5*/ A| C|D| F|G,
    /*6*/ A| C|D|E|F|G,
    /*7*/ A|B|C,
    /*8*/ A|B|C|D|E|F|G,
    /*9*/ A|B|C| F|G,
    /*A*/ A|B|C|D|E| G, //A|B|C| E|F|G,
    /*b*/ C|D|E|F|G,
    /*C*/ D|E| G, //A| D|E|F,
    /*d*/ B|C|D|E| G,
    /*E*/ A|B| D|E|F|G, //A| D|E|F|G,
    /*F*/ A| E|F|G,
    };

    struct font {
    int disp, trig;
    };
    /* _
    |_|
    |_|
    */
    struct font font3[3][3] = {
    { { 0,0}, {'_',A}, { 0,0} },
    { {'|',F}, {'_',G}, {'|',B} },
    { {'|',E}, {'_',D}, {'|',C} },
    };
    /*
    ___
    | |
    |___|
    | |
    |___|
    */
    struct font font5[5][5] = {
    { { 0,0}, {'_',A}, {'_',A}, {'_',A}, { 0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, {'|',B} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'|',B} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, {'|',C} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'|',C} }
    };
    /*
    ____
    | |
    | |
    | |
    |____|
    | |
    | |
    | |
    |____|
    */
    struct font font9[9][7] = {
    { { 0,0}, {'_',A}, {'_',A}, {'_',A}, {'_',A}, { 0,0}, {0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
    { {'|',F}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',B}, {0,0} },
    { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'_',G}, {'|',B}, {0,0} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
    { {'|',E}, { 0,0}, { 0,0}, { 0,0}, { 0,0}, {'|',C}, {0,0} },
    { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'_',D}, {'|',C}, {0,0} },
    };

    #define dim(x) (sizeof(x)/sizeof*(x))
    #define font_and_dims(x) (struct font *)x, dim(x), dim(*x)

    int print(char *s, struct font *font, int dimy, int dimx) {
    int row, col;
    char *sp;
    for (row = 0; row < dimy; row++) {
    for (sp = s; *sp; sp++) {
    for (col = 0; col < dimx; col++) {
    putchar( seg[ao(*sp)] & font[row*dimx+col].trig ?
    font[row*dimx+col].disp : ' ');
    }
    }
    putchar('\n');
    }
    }

    int main(int ac, char **av) {
    enum { F1, F2, F3 } fz = F1;
    for (++av,--ac;ac;ac--,av++) {
    if (av[0][0] == '-') {
    switch (av[0][1]) {
    case '1': fz=F1; continue;
    case '2': fz=F2; continue;
    case '3': fz=F3; continue;
    default: fprintf(stderr, "Unrecognized Option!\n");
    }
    }
    if (strspn(*av, "0123456789abcdefABCDEF") != strlen(*av))
    fprintf(stderr, "Hex only!\n");
    else
    switch(fz) {
    case F1: print(*av, font_and_dims(font3)); break;
    case F2: print(*av, font_and_dims(font5)); break;
    case F3: print(*av, font_and_dims(font9)); break;
    default: fprintf(stderr, "Invalid Font!\n");
    }
    }

    return 0;
    }

    715(1)12:54 AM:~ 0> 7seg3 1 -2 2 -3 3

    |
    |
    ___
    |
    ___|
    |
    |___
    ____
    |
    |
    |
    ____|
    |
    |
    |
    ____|
    716(1)12:55 AM:~ 0>
     
    luserXtrog, Jul 21, 2009
    #12
  13. Felipe Ribeiro

    luserXtrog Guest

    Simulating a sixteen-segment display

    727(1)01:02 AM:~ 0> cat 16seg.c
    #include <stdio.h>
    #include <string.h>

    enum {
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    F = 1 << 5,
    G = 1 << 6,
    H = 1 << 7,
    I = 1 << 8,
    J = 1 << 9,
    K = 1 << 10,
    L = 1 << 11,
    M = 1 << 12,
    N = 1 << 13,
    O = 1 << 14,
    P = 1 << 15
    };

    struct font {
    int msk, out;
    } font[7][8] = {
    { { 0,0}, {A,'-'}, {A,'-'}, { 0,0}, {B,'-'}, {B,'-'},
    { 0,0}, { 0,0} },
    { {C,'|'}, {D,'\\'}, { 0,0}, {E,'|'}, { 0,0}, {F,'/'},
    {G,'|'}, { 0,0} },
    { {C,'|'}, { 0,0}, {D,'\\'}, {E,'|'}, {F,'/'}, { 0,0},
    {G,'|'}, { 0,0} },
    { { 0,0}, {H,'-'}, {H,'-'}, { 0,0}, {I,'-'}, {I,'-'},
    { 0,0}, { 0,0} },
    { {J,'|'}, { 0,0}, {K,'/'}, {L,'|'}, {M,'\\'}, { 0,0},
    {N,'|'}, { 0,0} },
    { {J,'|'}, {K,'/'}, { 0,0}, {L,'|'}, { 0,0}, {M,'\\'},
    {N,'|'}, { 0,0} },
    { { 0,0}, {O,'-'}, {O,'-'}, { 0,0}, {P,'-'}, {P,'-'},
    { 0,0}, { 0,0} }
    };

    /*
    -- -- AA BB
    |\ | /| CD E FG
    | \|/ | C DEF G
    -- -- HH II
    | /|\ | J KLM N
    |/ | \| JK L MN
    -- -- OO PP
    */

    int segs[] = {
    /* A|B| C|D|E|F|G| H|I| J|K|L|M|N| O|P */
    /*0*/ A|B| C| F|G| J|K| N| O|P,
    /*1*/ G| N,
    /*2*/ A|B| G| H|I| J| O|P,
    /*3*/ A|B| F| H|I| N| O|P,
    /*4*/ C| G| H|I| N,
    /*5*/ A|B| C| H| M| O|P,
    /*6*/ A|B| C| H|I| J| N| O|P,
    /*7*/ A|B| G| N,
    /*8*/ A|B| C| G| H|I| J| N| O|P,
    /*9*/ A|B| C| G| H|I| N| O|P,
    /*A*/ C|D| H| J| M,
    /*B*/ A|B| E| G| I| L| N| O|P,
    /*C*/ A|B| C| J| O|P,
    /*D*/ A|B| E| G| L| N| O|P,
    /*E*/ A|B| C| H|I| J| O|P,
    /*F*/ A|B| C| H|I| J,
    /*G*/ A|B| C| I| J| N| O|P,
    /*H*/ C| G| H|I| J| N,
    /*I*/ A|B| E| L| O|P,
    /*J*/ G| J| N| O|P,
    /*K*/ C| F| H| J| M,
    /*L*/ C| J| O|P,
    /*M*/ C|D| F|G| J| N,
    /*N*/ C|D| G| J| M|N,
    /*O*/ A|B| C| G| J| N| O|P,
    /*P*/ A|B| C| G| H|I| J,
    /*Q*/ A|B| C| G| J| M|N| O|P,
    /*R*/ A|B| C| G| H|I| J| M,
    /*S*/ A|B| C| H|I| N| O|P,
    /*T*/ A|B| E| L,
    /*U*/ C| G| J| N| O|P,
    /*V*/ C| F| J|K,
    /*W*/ C| G| J|K| M|N,
    /*X*/ D| F| K| M,
    /*Y*/ D| F| L,
    /*Z*/ A|B| F| K| O|P
    };

    char *vec = "0123456789"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz";

    int enc(int c) {
    return strchr(vec,c)-vec;
    }

    int print(char *s) {
    int row,col;
    char *sp;
    if (strspn(s,vec)!=strlen(s)) return -1;
    for (row = 0; row < sizeof font/sizeof*font; row++) {
    for (sp = s; *sp; sp++) {
    for (col = 0; col < sizeof*font/sizeof**font; col++) {
    putchar( segs[enc(toupper(*sp))] & font[row]
    [col].msk ?
    font[row][col].out : ' ');
    }
    }
    putchar('\n');
    }
    return 0;
    }

    int main(int ac, char **av) {
    for (++av,--ac;ac;ac--,av++) {
    print(*av);
    }
    return 0;
    }

    728(1)01:02 AM:~ 0> 16seg yo mama
    -- --
    \ / | |
    \ / | |

    | | |
    | | |
    -- --

    |\ /| |\ |\ /| |\
    | \ / | | \ | \ / | | \
    -- --
    | | | \ | | | \
    | | | \ | | | \

    729(1)01:02 AM:~ 0>
     
    luserXtrog, Jul 21, 2009
    #13
  14. Felipe Ribeiro

    luserXtrog Guest

    On Jul 21, 2:12 am, superpollo <> wrote:
    > luserXtrog wrote:
    > > Font change option!

    >
    > > 714(1)12:54 AM:~ 0> cat 7seg3.c
    > > ...
    > >     /*A*/ A|B|C|D|E|  G, //A|B|C|  E|F|G,

    >
    > c99?
    >
    > $ c89 yomama.c
    > yomama.c:47: error: parse error before '/' token
    > yomama.c:49: error: parse error before '/' token
    > yomama.c:51: error: parse error before '/' token
    > $
    >
    > bye


    Whoopsy-daisy!
    Sorry about that. I finally got around to trying Richard Bos'
    suggestion for lower case letters and forgot that I left the
    old ones dangling there.

    So yes: c99, or you'll have to remove the malformed comments.

    --
    lousy urnex drool
     
    luserXtrog, Jul 21, 2009
    #14
  15. Re: Simulating a sixteen-segment display

    On Mon, 20 Jul 2009 23:05:48 -0700 (PDT), luserXtrog
    <> wrote:

    Did you have a question or are you posting 100+ line programs for the
    fun of it.

    >
    >727(1)01:02 AM:~ 0> cat 16seg.c
    >#include <stdio.h>
    >#include <string.h>
    >


    You left out the include for ctype.h needed for toupper.

    snip

    > putchar( segs[enc(toupper(*sp))] & font[row]
    >[col].msk ?
    > font[row][col].out : ' ');


    snip


    --
    Remove del for email
     
    Barry Schwarz, Jul 22, 2009
    #15
  16. Felipe Ribeiro

    luserXtrog Guest

    Re: Simulating a sixteen-segment display

    On Jul 21, 7:35 pm, Barry Schwarz <> wrote:
    > On Mon, 20 Jul 2009 23:05:48 -0700 (PDT), luserXtrog
    >
    > <> wrote:
    >
    > Did you have a question or are you posting 100+ line programs for the
    > fun of it.


    Just for fun. And to polish my chops. And to show off.
    And to spur debate. And to invite comment. And probably other
    motives besides.

    >
    > >727(1)01:02 AM:~ 0> cat 16seg.c
    > >#include <stdio.h>
    > >#include <string.h>

    >
    > You left out the include for ctype.h needed for toupper.


    Dagnabit!

    > snip
    >
    > >                putchar( segs[enc(toupper(*sp))] & font[row]
    > >[col].msk ?
    > >                    font[row][col].out : ' ');


    --
    leeks drool
     
    luserXtrog, Jul 22, 2009
    #16
  17. Felipe Ribeiro

    Squeamizh Guest

    Re: Simulating a sixteen-segment display

    On Jul 21, 5:35 pm, Barry Schwarz <> wrote:
    > On Mon, 20 Jul 2009 23:05:48 -0700 (PDT), luserXtrog
    >
    > <> wrote:
    >
    > Did you have a question or are you posting 100+ line programs for the
    > fun of it.


    You're a dick.
     
    Squeamizh, Jul 22, 2009
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fangs
    Replies:
    3
    Views:
    9,839
    darshana
    Oct 26, 2008
  2. Elnikety
    Replies:
    2
    Views:
    1,422
    Elnikety
    May 7, 2007
  3. electronsteve

    7 segment display

    electronsteve, Nov 7, 2008, in forum: VHDL
    Replies:
    0
    Views:
    1,115
    electronsteve
    Nov 7, 2008
  4. 0m
    Replies:
    2
    Views:
    985
    Richard Bos
    Jul 5, 2009
  5. luserXtrog

    Re: Simulating a seven-segment display

    luserXtrog, Jul 3, 2009, in forum: C Programming
    Replies:
    1
    Views:
    359
    luserXtrog
    Jul 4, 2009
Loading...

Share This Page