printf
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:printf
oh, and ... btw, if you have troubles with your PRINT function, just try to make it run in a Linux/Unix/window user process before you try it for real ...
Re:printf
Here's a nice tested printf...:
static int printf( char *msg, ... )
{
char curchar = *msg;
char* ch;
char* str;
va_list args;
va_start( args, msg );
// keep reading the message until it's the end of the message
while ( curchar != '\0' )
{
// if it is just a character, then print
if ( curchar >= ' ' && curchar != '%' )
{
putch( curchar );
}
// it's a '%'
else if ( curchar == '%' )
{
// check ahead if it's another %
// alot of help came from my compiler book;)
++msg;
curchar = *msg;
if ( curchar == '%' )
putch( '%' );
// not another % -- print the character, string, or number
else
{
switch ( curchar )
{
case 'c':
*ch = ( unsigned char ) va_arg( args, int );
putch( *ch );
break;
case 's':
str = va_arg( args, char * );
printf( str );
break;
case 'd':
// d = va_arg( args, int );
// code tk: itoa
break;
default:
putch( '%' ); // just print % when it doesn't know
// what to do
break;
}
}
}
else if ( curchar == 0x08 || curchar == 0x09 || curchar == '\r' || curchar == '\n' )
{
putch( curchar );
}
++msg;
curchar = *msg;
}
va_end( args );
}
static int printf( char *msg, ... )
{
char curchar = *msg;
char* ch;
char* str;
va_list args;
va_start( args, msg );
// keep reading the message until it's the end of the message
while ( curchar != '\0' )
{
// if it is just a character, then print
if ( curchar >= ' ' && curchar != '%' )
{
putch( curchar );
}
// it's a '%'
else if ( curchar == '%' )
{
// check ahead if it's another %
// alot of help came from my compiler book;)
++msg;
curchar = *msg;
if ( curchar == '%' )
putch( '%' );
// not another % -- print the character, string, or number
else
{
switch ( curchar )
{
case 'c':
*ch = ( unsigned char ) va_arg( args, int );
putch( *ch );
break;
case 's':
str = va_arg( args, char * );
printf( str );
break;
case 'd':
// d = va_arg( args, int );
// code tk: itoa
break;
default:
putch( '%' ); // just print % when it doesn't know
// what to do
break;
}
}
}
else if ( curchar == 0x08 || curchar == 0x09 || curchar == '\r' || curchar == '\n' )
{
putch( curchar );
}
++msg;
curchar = *msg;
}
va_end( args );
}
Re:printf
I think you can clean that printf up a bit... here's the one i came up with so far...
void printf(const char* format, ...)
{
va_list list;
va_start(list, format);
int i = 0; //message index
while(format != 0x00)
{
if(format == '%')
{
switch(format[++i])
{
case '%': putchar('%'); break;
case 'c': putchar(va_arg(list, char)); break;
case 's': printf(va_arg(list, char*)); break;
case 'd': break;//integer, ick for now
default: printf("%%%c", format);
};
}
else
{
putchar(format);
}
i++;
}
}
it doesnt handle %d yet, and it will crash if you try to do something like printf("String:%s", "crash here->%s");
but other than that it works well for general purpose printing... by the standard, to output a single '%' you must enter "%%" (just like '\' and "\\")
also if you enter something weird like %z that it doesnt understand, it outputs what you typed (i.e. "%z" exactly as you gave it) not sure if that's standard, but i threw it in there
Tom you seem to be storing the arguments before you pass them to say, putch(), but there's no need, you can use putch() and as an argument, use the va_arg() macro
also, this part of your code:
else if ( curchar == 0x08 || curchar == 0x09 || curchar == '\r' || curchar == '\n' )
{
putch( curchar );
}
does absolutely nothing , in fact it wont ever get to that comparison, because this part of your code takes care of it:
if ( curchar >= ' ' && curchar != '%' )
{
putch( curchar );
}
void printf(const char* format, ...)
{
va_list list;
va_start(list, format);
int i = 0; //message index
while(format != 0x00)
{
if(format == '%')
{
switch(format[++i])
{
case '%': putchar('%'); break;
case 'c': putchar(va_arg(list, char)); break;
case 's': printf(va_arg(list, char*)); break;
case 'd': break;//integer, ick for now
default: printf("%%%c", format);
};
}
else
{
putchar(format);
}
i++;
}
}
it doesnt handle %d yet, and it will crash if you try to do something like printf("String:%s", "crash here->%s");
but other than that it works well for general purpose printing... by the standard, to output a single '%' you must enter "%%" (just like '\' and "\\")
also if you enter something weird like %z that it doesnt understand, it outputs what you typed (i.e. "%z" exactly as you gave it) not sure if that's standard, but i threw it in there
Tom you seem to be storing the arguments before you pass them to say, putch(), but there's no need, you can use putch() and as an argument, use the va_arg() macro
also, this part of your code:
else if ( curchar == 0x08 || curchar == 0x09 || curchar == '\r' || curchar == '\n' )
{
putch( curchar );
}
does absolutely nothing , in fact it wont ever get to that comparison, because this part of your code takes care of it:
if ( curchar >= ' ' && curchar != '%' )
{
putch( curchar );
}
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:printf
i would avoid recursive call of "printf" if i were you ... you're unlikely to love a stack overflow in a display function you'll use for debugging purpose.
Moreover, it's dangerous to do "printf(arg_list(char*))" to handle %s, because if the sub-string contains some %i, %d, %x, %s ... printf will try to translate them, but will get random values from arg_list as the recursive call has no arguments past the format string.
Moreover, it's dangerous to do "printf(arg_list(char*))" to handle %s, because if the sub-string contains some %i, %d, %x, %s ... printf will try to translate them, but will get random values from arg_list as the recursive call has no arguments past the format string.