printf( "%-15s %d\n", tbl->name, tbl->value );
}
}
int main(){
char buf[80];
struct elem *ptr;
printtable(table);
for(;;){
printf( "-> " );
if( gets( buf ) == NULL) break; /* EOF */
if( ! strcmp( buf, "q" ))
exit(0); /* quit: */
ptr = find( buf, table, SIZE-1 );
if( ptr )
printf( "%d\n", ptr->value );
else {
printf( "--- ---\n" );
printtable(table);
}
}
return 0;
}
7.26. , ,
, - . ,
, UNIX -
: , less (more)
.
#define LEN 9 /* 256 */
char input[] = "(xxx+yyy)/123.75=?";
char output[LEN];
void main( void ){
int len=LEN, i; void bi_conv(); char c;
bi_conv(input, output, &len);
if(len > LEN){
printf(" LEN %d\n", len);
len = LEN; /* */
}
for(i=0; i < len && (c = output[i]); ++i)
putchar(c);
putchar('\n');
}
/* , include-
* ! */
#include <stdio.h>
#include <ctype.h>
#define PUT(c) { count++; \
if(put < *len){ *p++ = (c); ++put;}}
#define GET() (*s ? *s++ : EOF)
void bi_conv(
. , 1992-95 - 290 - UNIX
/*IN*/ char *s,
/*OUT*/ char *p,
/*INOUT*/ int *len ){
int count, put, c;
for(count=put=0; (c=GET()) != EOF; ){
/* : C\bC */
/* : _\bC */
if(isalpha(c)){ PUT('_'); PUT('\b'); }
else if(isdigit(c)){ PUT( c ); PUT('\b'); }
PUT(c);
}
PUT('\0'); /* */
*len = count;
#undef PUT
#undef GET
}
. ,
input output ; , ,
#define PUT(c) if(c)putchar(c)
#define GET() getchar()
, .
7.27. , . -
C\b
#include <stdio.h>
#define NOPUT (-1) /* ASCII */
/* - */
typedef enum { NORMAL=1, ITALICS, BOLD, RED=BOLD } font;
int ontty; font textfont; /* */
#define setfont(f) textfont=(f)
#define getfont() (textfont)
#define SetTtyFont(f) if(ontty) tfont(f)
/* */
void tfont(font f){ /* ANSI */
static font ttyfont = NORMAL;
if(ttyfont == f) return;
printf("\033[0m"); /* set NORMAL font */
switch(ttyfont = f){
case NORMAL: /* */ break;
case BOLD: printf("\033[1m"); break;
case ITALICS: /* use reverse video */
printf("\033[7m"); break;
}
}
void put(int c){ /* */
if(c == NOPUT) return; /* '\b' */
SetTtyFont(getfont()); putchar(c);
setfont(NORMAL); /* C\b - */
}
void
main(){ register int c, cprev = NOPUT;
/* - ? */
ontty = isatty(fileno(stdout));
setfont(NORMAL);
while((c = getchar()) != EOF){
. , 1992-95 - 291 - UNIX
if(c == '\b'){ /* */
if((c = getchar()) == EOF) break;
if(c == cprev) setfont(BOLD);
else if(cprev == '_') setfont(ITALICS);
else /* A\bB */ setfont(RED);
} else put(cprev);
cprev = c;
}
put(cprev); /* */
SetTtyFont(NORMAL);
}
7.28. -.
. , -
( - ). : -
, . :
'\r' - ;
, , ,
( , '\t').
7.29. , - . -
, "", 'c' - -
. EPSON-FX ( EP-2424)
(ESC '\033'):
(bold) ESC G ESC H
(emphasized) ESC E ESC F
(italics) ESC 4 ESC 5
(underline) ESC - 1 ESC - 0
ESC x 1 ESC x 0
(near letter quality) nlq draft
(superscript) ESC S 0 ESC T
(subscript) ESC S 1 ESC T
(17 /) '\017' '\022'
(condensed)
ESC W 1 ESC W 0
(expanded)
ESC p 1 ESC p 0
(proportional spacing)
.
:
pitch ( )
pica (10 /) ESC P
elite (12 /) ESC M
micron (15 /) ESC g
font ()
(draft (Roman)) ESC k '\0'
(text (Sans Serif)) ESC k '\1'
(courier) ESC k '\2'
0 '0' '\0'; 1 '1' '\1'. :
printf( "This is \033Gboldface\033H word\n");
. , 1992-95 - 292 - UNIX
7.30. , -
. '\f' (form feed) .
7.31. . -
: ( ),
(), . -
- , (
) . : -
main(), ,
. : ,
( ).
/* : pr.c */
#include <stdio.h>
#include <string.h>
#define YES 1
#define NO 0
#define FORMFEED '\f'
#define LINEFEED '\n'
extern char *malloc(unsigned);
extern char *strchr(char *, char);
void untab(register char *s);
void resetsheet( void );
void addsheet( char *s, FILE *fpout );
void flushsheet( FILE *fpout );
void printline( int y, char *s, char *attr,
FILE *fpout );
void doattr( register char *abuf,
register char *vbuf );
void printcopy( FILE *fpin, FILE *fpout );
void main(void);
char *strdup (const char *s){
char *p = malloc(strlen(s)+1); strcpy(p,s); return p;
/* return strcpy((char *) malloc(strlen(s)+1), s); */
}
/* ... untab() ... */
int Sline; /* */
int Shalf; /* */
int npage; /* */
int startpage = 1;
/* 1 */
int fline; /* */
int topline = 0; /* */
int halfwidth; /* */
int twocolumns = YES; /* ? */
int lshift, rshift = 1; /* */
typedef unsigned short ushort;
int COLS = 128; /* () */
int LINES = 66; /* () */
ushort *mem; /* */
#define AT(x,y) mem[ (x) + (y) * COLS ]
/* */
void resetsheet ( void ){
register x;
if( mem == NULL ){ /* */
. , 1992-95 - 293 - UNIX
if ((mem = (ushort *)
malloc (COLS * LINES * sizeof(ushort)))
== NULL ){
fprintf(stderr, "Out of memory.\n"); exit(1);
}
}
/* */
for( x= COLS * LINES - 1 ; x >= 0 ; x-- )
mem[x] = ' ' & 0xFF;
halfwidth = (twocolumns ? COLS/2 : COLS )
- (lshift + rshift );
Sline = topline; Shalf = 0;
}
#define NEXT_HALF \
if( twocolumns == YES && Shalf == 0 ){ \
/* */ \
Shalf = 1; /* */ \
Sline = topline; \
} else \
flushsheet(fpout) /* */
/* */
void addsheet ( char *s, FILE *fpout )
{
register x, y;
register i;
char *rest = NULL;
int wrap = NO;
/* YES */
/* ? */
x = (Shalf == 0 ? 0 : COLS/2) + lshift;
y = Sline;
i = 0; /* s */
while (*s) {
if( *s == '\f' ){
/* form feed */
rest = strdup( s+1 ); /* */
NEXT_HALF;
if( *rest ) addsheet(rest, fpout);
free( rest );
return;
}
if( i >= halfwidth ){
/* */
wrap = YES;
rest = strdup(s);
break;
}
/* */
if( s[1] == '\b' ){
while( s[1] == '\b' ){
AT(x, y) = (s[0] << 8) | (s[2] & 0xFF);
/* overstrike */
s += 2;
}
s++; x++; i++;
} else {
AT (x, y) = *s++ & 0xFF;
. , 1992-95 - 294 - UNIX
x++; i++;
}
}
/* /_ */
Sline++;
if (Sline == LINES) { /* */
NEXT_HALF; }
if( wrap && rest ) { /* */
addsheet(rest, fpout); free(rest);
}
}
int again; /* ? */
/* */
void flushsheet ( FILE *fpout ){
register x, y, xlast;
char *s, *p;
static char outbuf[BUFSIZ], attr[BUFSIZ];
/* attr - */
ushort c;
if( npage >= startpage )
for (y = 0; y < LINES; y++) {
/* */
for (xlast = (-1), x = COLS - 1; x >= 0; x--)
if (AT (x, y) != ' ') { xlast = x; break; }
again = NO; s = outbuf; p = attr;
for (x = 0; x <= xlast; x++){
c = AT(x, y);
*s++ = c & 0xFF;
/* ? */
c >>= 8; c &= 0xFF;
*p++ = c ? c : ' ';
if( c ) again = YES;
}
*s = '\0'; *p = '\0';
printline(y, outbuf, attr, fpout);
}
npage++; /* next page */
resetsheet(); /* */
}
/* */
void printline ( int y, char *s, char *attr,
FILE *fpout ){
register x;
if( again ){
doattr(attr, s); fprintf(fpout, "%s\r", attr );
}
fprintf(fpout, "%s", s);
/* */
fputc( y == LINES-1 ? FORMFEED : LINEFEED, fpout );
}
/* - */
void doattr ( register char *abuf,
register char *vbuf ){
for(; *abuf; abuf++, vbuf++ )
if( !strchr(" _-!|\177", *abuf))
*abuf = *vbuf;
}
. , 1992-95 - 295 - UNIX
/* */
void printcopy ( FILE *fpin, FILE *fpout )
{
char inbuf[BUFSIZ];
npage = 1; /* 1 */
fline = 0; /* - 0 */
resetsheet(); /* */
while( fgets(inbuf, sizeof inbuf - 1, fpin )
!= NULL ){
register l = strlen( inbuf );
if( l && inbuf[l-1] == '\n' )
inbuf[--l] = '\0' ;
fline++;
untab ( inbuf );
addsheet( inbuf, fpout );
}
if( !(Sline == topline && Shalf == 0))
/* ... */
flushsheet(fpout);
fprintf(stderr, "%d , %d .\n",
fline, npage-1);
}
/* : pr < > /dev/lp */
void main (){ printcopy(stdin, stdout); }
- UNIX /dev/lp , MS DOS - prn.
7.32. ,
. : -
malloc() strcpy().
, . ,
80
50. :
char text[50][80];
50*80 = 4000 . ,
10 .
50 * (10 + 1) = 550
4000 - 50 * (10 + 1) = 3450
(+1 '\0' ).
char *text[50]; int i=0;
:
char buffer[81], *malloc(), *gets();
while( gets(buffer) != NULL ){
text[i] = (char *) malloc(strlen(buffer)+1);
/* +1 \0, strlen- */
strcpy(text[i++], buffer);
}
,
. ( sizeof(char *)==4)
. , 1992-95 - 296 - UNIX
50 * 4 + 50 * (10 + 1 + 4) = 950
+ malloc
(+4 - malloc), .
,
, malloc()- (
free()). malloc
, NULL:
if((text[i] = malloc(....)) == NULL)
{ fprintf(stderr, " \n"); break; }
:
for(--i; i >= 0; i-- ){
printf("%s\n", text[i]);
free( text[i] );
}
free(ptr) ""|- malloc() calloc()
ptr , malloc() -
. free(). (
) , malloc()-!
,
, ,
, , , .
, -
.
- .
7.33. , .
! " "
" " , " ".
____________________
|- ,
, .
malloc - -
? .
. , 1992-95 - 297 - UNIX
/* .
* , -
* ,
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#define BUFS 4096 /* */
void main(int argc, char **argv )
{
FILE *fp;
struct stat st;
long len;
char buffer[ BUFS+1 ];
FILE *fpnew; /* */
int lgt;
if( argc != 2 ){
printf("Error: must be filename\n");
exit(1);
}
if( (fp= fopen( argv[1], "r" )) == NULL ){
printf( "Can not open %s\n", argv[1] );
exit(2);
}
stat( argv[1], &st ); /* fstat(fileno(fp), &st); */
len = st.st_size; /* */
if( (fpnew = fopen( "inv.out", "w" ))== NULL ){
printf("Can not create file\n");
exit(3);
}
while( fgets( buffer, sizeof buffer, fp ) != NULL ){
lgt = strlen( buffer );
fseek(fpnew, len - lgt , 0);
/* , lseek fseek -
* long, int.
*
* lseek(fd, (long) off, whence);
*/
len -= lgt;
fprintf( fpnew, "%s", buffer );
/* fputs(buffer, fpnew); */
}
fclose( fp ); fclose( fpnew );
}
7.34. , , "" , -
. "" .
, :
. , 1992-95 - 298 - UNIX
----------- -----------
|###### A | |###### A | 1
|#### A | |#### A |
|##### A | |##### A |
| | | |
|###### B | | |
----------- -----------
|#### B | |###### B | 2
| | |#### B |
... | |
, -
. (
!). - .
/* ,
* */
#include <stdio.h>
#include <ctype.h>
extern void *malloc(unsigned);
extern int atoi(char *);
FILE *fpin = stdin, *fpout = stdout;
/* */
char *strdup (const char *s) {
char *ptr = (char *) malloc (strlen (s) + 1);
if( ptr ) strcpy (ptr, s); return ptr;
}
int page_length = 66; /* */
int current_line; /* ( ) */
int numbered = 0; /* ? */
#define MAXLINES 256 /* . */
int stored = 0; /* */
char *lines[MAXLINES]; /* */
/* */
void remember (char *s) {
if (stored >= MAXLINES) {
fprintf (stderr, " .\n"); return;
} else if((lines[stored++] = strdup (s)) == NULL ){
fprintf (stderr, " (Out of memory).\n"); exit(13);
}
}
/* */
void newpage () {
current_line = 0; putc('\f', fpout);
}
. , 1992-95 - 299 - UNIX
/* */
void newline (void) {
if (current_line == page_length - 1)
newpage (); /* */
else {
current_line++;
if( numbered ) fprintf(fpout, "%02d\n", current_line);
else putc ('\n', fpout);
}
}
/* */
void nextpage () {
while (current_line != 0)
newline ();
}
/* */
void throwout () {
register i;
for (i = 0; i < stored; i++) {
if( numbered )
fprintf(fpout, "%02d %s", current_line, lines[i]);
else fputs (lines[i], fpout);
newline (); free (lines[i]);
}
stored = 0;
}
/* , */
void flush () {
int rest_of_page = page_length - current_line;
/* */
if ((stored > page_length && rest_of_page < page_length / 4) ||
rest_of_page < stored)
nextpage ();
throwout ();
if (current_line) /* */
newline (); /* */
}
/* */
void process () {
char buffer[512]; int l;
while (fgets (buffer, sizeof buffer, fpin) != NULL) {
if ((l = strlen (buffer)) && buffer[l - 1] == '\n')
buffer[ --l] = '\0';
if (l) remember (buffer);
/* - */
else if (stored) flush ();
}
if (stored) flush ();
nextpage();
}
. , 1992-95 - 300 - UNIX
void main (int argc, char *argv[]) {
argc--; argv++;
while (*argv) {
if (**argv == '-') {
char *key = *argv + 1, *arg;
switch (*key) {
case 'l':
if (! key[1]) {
if( argv[1] ){
arg = argv[1]; argv++; argc--;
} else arg = "";
} else arg = key+1;
if( isdigit(*arg) ){
page_length = atoi(arg);
fprintf (stderr, " : %d \n", page_length);
} else fprintf(stderr, "-l \n");
break;
case 'n':
numbered++; break;
default:
fprintf (stderr, " %s\n", key);
break;
}
}
argv++; argc--;
}
process ();
exit(0);
}
7.35. ,
. ,
abcdef ... oklmn 987654321
..... .....
123456789 nmlko ... fedcba
:
. :
().
7.36. , -
. - . : -
.
. , 1992-95 - 301 - UNIX
/* */
#include <stdio.h>
char buf[240]; /* */
int lines; /* */
typedef struct node{
struct _data{ /* */
char *key; /* - */
int line; /* */
} data;
/* */
struct node *l, /* */
*r; /* */
} Node;
Node *root = NULL; /* ( ) */
/* */
Node *newNode(s)
char *s; /* */
{
Node *tmp;
extern char *malloc(); /* */
tmp = (Node *) malloc(sizeof(Node));
if( tmp == NULL ){
fprintf( stderr, " .\n");
exit(1);
}
tmp -> l = tmp -> r = NULL; /* */
tmp -> data.line = lines; /* */
tmp -> data.key = malloc( strlen(s) + 1 );
/* +1 - '\0' */
strcpy(tmp -> data.key, s); /* */
return tmp;
}
int i; /* ,
* auto-,
* */
. , 1992-95 - 302 - UNIX
/* */
void printtree(root, tree, level, c)
Node *root; /* */
Node *tree; /* */
int level; /* */
char c; /* */
{
if( root == NULL ){ printf(" .\n"); return; }
if( tree == NULL ) return;
/* - */
printtree (root, tree -> l, level + 1, '/'); /* 'L' */
/* */
for( i=0; i < level; i++ )
printf(" ");
printf("%c%3d--\"%s\"\n",
c, tree-> data.line, tree -> data.key);
/* - */
printtree(root, tree -> r, level + 1, '\\'); /* 'R' */
}
void prTree(tree) Node *tree;
{
printtree(tree, tree, 0, '*');
}
/* key tree */
void addnode(tree, key)
Node **tree; /* : ,
* */
char *key; /* */
{
#define TREE (*tree)
if( TREE == NULL ){ /* */
TREE = newNode( key );
return;
}
/* */
if ( strcmp (key, TREE -> data.key) < 0 )
{
/* */
if ( TREE -> l == NULL ){
/* */
TREE -> l = newNode(key);
return;
}
else addnode( & TREE ->l , key);
}
. , 1992-95 - 303 - UNIX
else{
/* */
if ( TREE -> r == NULL ){
/* */
TREE -> r = newNode(key);
return;
}
else addnode ( & TREE ->r, key) ;
}
}
/* . */
typedef struct node *NodePtr;
static NodePtr delNode; /* */
void delete(key, tree)
char *key; /* */
NodePtr *tree; /* */
{
extern void doDelete();
if(*tree == NULL){
printf( "%s \n", key ); return;
}
/* */
else if(strcmp(key, (*tree)->data.key) < 0)
delete( key, &(*tree)->l );
else if(strcmp(key, (*tree)->data.key) > 0)
delete( key, &(*tree)->r );
else{ /* */
delNode = *tree; /* */
if(delNode->r == NULL) *tree = delNode->l;
else if(delNode->l == NULL) *tree = delNode->r;
else doDelete( & delNode->l );
free(delNode);
}
}
static void doDelete(rt) NodePtr *rt;
{
if( (*rt)->r != NULL ) /* */
doDelete( &(*rt)->r );
else{
/* */
delNode->data = (*rt)->data;
delNode = *rt; /* free() */
*rt = (*rt)->l;
}
}
. , 1992-95 - 304 - UNIX
void main(){
extern char *gets(); char *s;
while (gets(buf) != NULL){ /* */
lines++;
addnode( & root, buf );
}
prTree(root);
/* */
freopen("/dev/tty", "r", stdin);
do{
printf( " ? " );
if((s = gets(buf)) == NULL) break;
delete(buf, &root);
prTree( root );
} while( s && root );
printf("Bye-bye.\n");
exit(0);
}
7.37. , 10 ,
. .
#include <stdio.h>
#include <ctype.h>
#define INT 'i'
#define STR 's'
struct data {
char tag; /* , . . */
union {
int i;
char *s;
} value;
} a[10];
int counter = 0; /* */
void main(){
char word[128]; int i; char *malloc(unsigned);
/* : */
for(counter=0; counter < 10; counter++){
if( gets(word) == NULL ) break;
if( isdigit((unsigned char) *word)){
a[counter].value.i = atoi(word);
a[counter].tag = INT;
} else {
a[counter].value.s = malloc(strlen(word)+1);
strcpy(a[counter].value.s, word);
a[counter].tag = STR;
}
}
/* : */
for(i=0; i < counter; i++)
switch(a[i].tag){
case INT: printf(" %d\n", a[i].value.i);
break;
case STR: printf(" %s\n", a[i].value.s);
free(a[i].value.s);
break;
}
. , 1992-95 - 305 - UNIX
}
7.38. ,
, - .
, . ,
-
? .
- -
. !
7.38.1.
/* .
* .
*/
#include <stdio.h> /* printf(), NULL */
#include <string.h> /* strdup() */
#include <stdlib.h> /* malloc() */
#define A_INT 1
#define A_STR 2
#define A_NULL 0
typedef struct arg {
int type;
union jack {
char *s;
int d;
} data;
struct arg *next;
} Arg;
void doit(Arg args[], int n){
int i;
for(i=0; i < n; i++)
switch(args[i].type){
case A_INT:
printf("%d", args[i].data.d);
break;
case A_STR:
printf("%s", args[i].data.s);
break;
default:
fprintf(stderr, "Unknown type!\n");
break;
}
}
. , 1992-95 - 306 - UNIX
/* union
* .
*/
Arg sample[] = {
{ A_INT, (char *) 123 },
{ A_STR, (char *) " hello, " },
{ A_INT, (char *) 456 },
{ A_STR, (char *) " world\n" }
};
int main(int ac, char *av[]){
doit(sample, sizeof sample / sizeof sample[0]);
return 0;
}
7.38.2.
/* .
* :
* :
* . :
* ,
* .
* ,
* .
* C++
* .
*/
#include <stdio.h> /* printf(), NULL */
#include <string.h> /* strdup() */
#include <stdlib.h> /* malloc() */
#define A_INT 1
#define A_STR 2
#define A_NULL 0
typedef struct arg {
int type;
union jack {
char *s;
int d;
} data;
struct arg *next;
} Arg;
. , 1992-95 - 307 - UNIX
void doit(Arg *arglist){
for( ; arglist; arglist=arglist->next)
switch(arglist->type){
case A_INT:
printf("%d", arglist->data.d);
break;
case A_STR:
printf("%s", arglist->data.s);
break;
default:
fprintf(stderr, "Unknown type!\n");
break;
}
}
Arg *new_int(int n, Arg *next){
Arg *ptr = (Arg *) malloc(sizeof(Arg));
ptr->type = A_INT;
ptr->data.d = n;
ptr->next = next;
return ptr;
}
Arg *new_str(char *s, Arg *next){
Arg *ptr = (Arg *) malloc(sizeof(Arg));
ptr->type = A_STR;
ptr->data.s = strdup(s);
ptr->next = next;
return ptr;
}
int main(int ac, char *av[]){
doit(
new_int(123,
new_str(" hello, ",
new_int(456,
new_str(" world\n",
NULL))))
);
return 0;
}
7.38.3.
/*
* .
*/
#include <stdio.h> /* printf(), NULL */
#include <stdarg.h> /* va_... */
#define A_INT 1
#define A_STR 2
#define A_NULL 0
. , 1992-95 - 308 - UNIX
void doit(...){ /* */
va_list args;
/* - , ...
* - !
*/
va_start(args, );
for(;;){
switch(va_arg(args, int)){
case A_INT:
printf("%d", va_arg(args, int));
break;
case A_STR:
printf("%s", va_arg(args, char *));
break;
case A_NULL:
goto breakloop;
default:
fprintf(stderr, "Unknown type!\n");
break;
}
}
breakloop:
va_end(args);
}
int main(int ac, char *av[]){