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[i][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[i][j] == '*' && j % 2 == 0)
printf("|");
else if (digits[i][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
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
> 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__|
> *
[snip]
No, wait a minute, I've got to stop you right there.
I was about to rant about why you would possibly want to use 9 values
to indicate 7 segments, but then I saw...
> 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'm not going to get into anything else, but I will give you a clue on
that.
Yes, you really only need 7 bits to specify the state of on/off state
of the 7 segments. You can use the 8th bit to indicate whether or not
to turn on the decimal point dot that most of them also have.
There is a convention for labeling them that has been around since
7-segment displays and drivers for them were first produced, just
about 40 years ago now since they first appeared in (very expensive in
the early days) digital watches and primitive calculators.
The segments are identified by lower case letters, 'a' through 'f', as
I would try to illustrate, very poorly, with ASCII art, but I don't
have to.
Instead see http://en.wikipedia.org/wiki/Seven_segment_display
--
Jack Klein http://JK-Technology.Com
FAQs for
news:comp.lang.c http://c-faq.com/
news:comp.lang.c++ http://www.parashift.com/c++-faq-lite/
news:alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
<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[i] & und) putchar('_');
else putchar(' ');
putchar(' ');
} else {
if (segs[c] & mask[i] & lbar) putchar('|');
else putchar(' ');
if (segs[c] & mask[i] & und) putchar('_');
else putchar(' ');
if (segs[c] & mask[i] & 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
<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[i][j] != 0; j++)
if ('0' <= argv[i][j] && argv[i][j] <= '9')
for (c = 0; c < countof(font[r]); c++)
{
m = digit[argv[i][j] - '0'];
if (argv[i][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
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
The microsoft c++ compiler doesn't recognise this piece unless it's
changed to this:
const char *seg_row[3][10]
Genius!
--
lxt
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[i];
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[i][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[i][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.
_
| |
_
| |
_
|
_
| |
_
$
else return;
> p = segs[i];
> 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] = '-';
It must be the worst piece in this thread though I spend a whole
afternoon on this piece. Currently, it can't display multiple 7-seg
digits on one line. Why I can't come up with code like Peter Nilsson's
and luserXtrog's above. (how old are you two guys :))
Sigh.
I turn 31 this year.
I'm still in awe of Peter's code. It illustrates explicitly what
I had to do by intuition. That first enum is brilliant.
I think you should be able to extend this to display multiple
units per line. Try expanding the seg array out to the total
width, and adding an offset to i which increases by the width
of unit after each digit.
Sometimes a smoke/porn/tomb-raider break helps see it from a
different angle.
--
lxt
You may want to re-examine this statement. See below
>> else if (c >= 'a' && c <= 'z') i = c - 'a' + 10;
You may want to re-examine this statement.
The C standard does not guarantee that alphabetic characters are allocated
in a continuous sequence. There are platforms where the alphabetic
characters are allocated "out of sequence", or with varying increments
(i.e., where 'J' - 'I' > 1 ).
While your above two statements will compile (likely without any
diagnostic), and will execute (again, likely without any diagnostic), on
some platforms (maybe yours), they will produce unintended and unexpected
results. (Likely that i will be set such that segs[i] will be
out-of-bounds.
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
Or all three. Here's my take 2, with garbage refusal:
#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+ 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,
};
int print(char *s) {
int r;
for (r=0; r<3; r++) {
int i;
for (i=0; s[i]; i++) {
switch(r) {
case 0:
putchar(' ');
putchar( (seg[ao(s[i])] & A)? '_' : ' ');
putchar(' ');
break;
case 1:
putchar( (seg[ao(s[i])] & F)? '|' : ' ');
putchar( (seg[ao(s[i])] & G)? '_' : ' ');
putchar( (seg[ao(s[i])] & B)? '|' : ' ');
break;
case 2:
putchar( (seg[ao(s[i])] & E)? '|' : ' ');
putchar( (seg[ao(s[i])] & D)? '_' : ' ');
putchar( (seg[ao(s[i])] & C)? '|' : ' ');
break;
}
}
putchar('\n');
}
}
int main(int ac, char **av) {
for (++av,--ac;ac;ac--,av++) {
if (strspn(*av, "012345789abcdefABCDEF") != strlen(*av))
fprintf(stderr, "Hex only!\n");
else
print(*av);
}
return 0;
}
--
lxt
> int seg[] =3D {
> /*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,
> };
Or even
/*a*/ A+B+C+D+E+ G,
/*b*/ C+D+E+F+G,
/*c*/ A+ D+E+F,
/*d*/ B+C+D+E+ G,
/*e*/ A+B+ D+E+F+G,
/*f*/ A+ E+F+G,
Or possibly
/*c*/ D+E+ G,
Richard
<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 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
714(1)12:54 AM:~ 0> cat 7seg3.c
#include <stdio.h>
#include <string.h>
int ao(int c) {
/*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>
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>
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
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
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
You're a dick.