Simulating a seven-segment display

F

Felipe Ribeiro

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
 
P

Peter Nilsson

Felipe Ribeiro said:
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:
        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"
_ _ _ _ _ _ _ _
| _| _||_||_ |_ ||_||_|| |
||_ _| | _||_| ||_| _||_|
_ _ _ _ _ _ _
_|| || ||_|| | || | |
|_ |_||_| _||_| ||_| |

%
 
L

luserXtrog

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:

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
 
F

Felipe Ribeiro

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.
 
P

Peter Nilsson

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"
__ __ __ __ __ __
| | | | | | | | | | |
__| | |__| | |__ |__| __| |__ |__
| | | | | | | | | |
__|. | | | __| __| |__ |__| __|
__ __ __ __ __ __ __ __
| | | | | | | | | | | | |
__| | | | | |__| | | | | | __|
| | | | | | | | | | | |
|__ |__| |__| __|.|__| |.|__| |__

%
 
L

luserXtrog

<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.
 
L

lovecreatesbeauty

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]
 
L

lovecreatesbeauty

  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.
 
L

lovecreatesbeauty

  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.
_
| |
_
| |
_


|
_
| |
_
$
 
L

luserXtrog

  % type 7seg_2.c

  % 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
____ ____ ____ ____
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
|____ |____| ____| |____ | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
|____| | | |____| | |____| |____|
 
L

luserXtrog

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>
 
L

luserXtrog

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>
 
L

luserXtrog

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.
 
B

Barry Schwarz

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

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
 
L

luserXtrog

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


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 : ' ');
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top