itoa please...
itoa please...
hello,
I need an itoa funciton that doen't crash PMode. (look using google and still no help)
does anyone have a itoa funcion, with all the code for reverse & strcat & other stuff it needs?
Thank you
I need an itoa funciton that doen't crash PMode. (look using google and still no help)
does anyone have a itoa funcion, with all the code for reverse & strcat & other stuff it needs?
Thank you
Re:itoa please...
I can't give you all of it, but since I wrote two of the routines you'll need in another thread earlier, you might as well use them. though I haven't tested them and cannot guarantee that they won't need debugging.
With these two, and a simple implementation of strlen(), it should be trivial to implement strcat() and strcpy() as preprocessor macros:
Again, this is not tested code; if you borrow it, be proepared to do some debugging. Note that while this is a traditional implementation approach, you may want to code them as true functions for the sake of increased robustness.
As always, comments and corrections are welcome.
Code: Select all
;;; void* memcpy(void* to, const void* from, size_t count)
extrn memcpy
_memcpy:
push ebp
mov ebp, esp
mov esi, [ebp + 8] ; first arg - src pointer
mov edi, [ebp +12] ; 2nd arg - dest pointer
mov ecx, [ebp + 16] ; 3rd arg - string size in bytes
mov eax, edi ; return value - save now, before EDI gets trashed
cdl ; make sure direction flag set correctly
rep movsb ; block-copy from src to dest
pop ebp ; restore caller's stack frame
ret
;; void* memset(void* buf, int ch, size_t cont)
extrn memset
_memset:
push ebp
mov ebp, esp
mov edi, [ebp + 8] ; first arg - buffer pointer
mov edi, [ebp +12] ; 2nd arg - value to write
mov eax, [ebp + 16] ; 3rd arg - string size in bytes
push edi ; return value - save now, before EDI gets trashed
cdl ; make sure direction flag set correctly
rep stosb
pop eax ; recover return value
pop ebp ; restore caller's stack frame
ret
Code: Select all
#define strcat(x,y) memcat((void *)(x + strlen(x) +1), (void *)(y), (strlen(y) +1))
#define strcpy(x,y) memcpy((void *)(x), (void *)(y), (strlen(x) +1))
As always, comments and corrections are welcome.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:itoa please...
just notifying a typo :
cdl is no valid ASM. the instruction is CLD
cdl is no valid ASM. the instruction is CLD
Re:itoa please...
I posted an itoa implementation (for hex, at least) quite recently. It should be easy to modify to decimal or any other base.
Tim Robinson wrote:Code: Select all
/* str must be at least 9 chars long */ void str_to_hex(char *str, unsigned long num) { static char hexdigits[] = "0123456789abcdef"; char str[9], *ptr; ptr = str + 9; *ptr = '\0'; do { ptr--; *ptr = hexdigits[num % 16]; num >>= 4; } while (num > 0); }
Re:itoa please...
Yes.
Actually, I'll post the generic code, because I've used one or two hex-only tricks in my original. This is the starting point for an strtoul() function (which you can look up in your C reference).
Actually, I'll post the generic code, because I've used one or two hex-only tricks in my original. This is the starting point for an strtoul() function (which you can look up in your C reference).
Code: Select all
/* str must be long enough */
void num_to_str(char *str, unsigned long num, unsigned base)
{
/* extend this for bases beyond 16 */
static char digits[] = "0123456789abcdef";
char buf[20], *ptr;
ptr = buf + sizeof(buf) - 1;
*ptr = '\0';
do
{
ptr--;
*ptr = digits[num % base];
num /= base;
} while (num > 0);
strcpy(str, buf);
}
Re:itoa please...
static int printf( char *msg, ... )
{
char curchar = *msg;
char* ch;
char* str;
unsigned long d;
char* numstring;
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 * );
smprintf( str );
break;
case 'd':
d = va_arg( args, int );
convertInttoString( numstring, d, 10 ); // 10 = the type of
// number system
smprintf( numstring );
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 );
}
void smprintf( char* message )
{
char _curchar = *message;
while ( _curchar != '\0' )
{
// don't check if it's greater or = to ' ' because someone might need to print \n and
// to keep it small, just print all characters
putch( _curchar );
++message;
_curchar = *message;
}
}
//*************************************************************************************************************
//
void convertInttoString( char *stringout, unsigned long number, unsigned base )
{
// If base is 16, it's hex, if it's 10, it's just regular numbers
static char digits[] = "0123456789abcdef";
char buffer[ 20 ], *ptr;
ptr = buffer + sizeof( buffer ) - 1;
*ptr = '\0';
do
{
ptr--;
*ptr = digits[ number % base ];
number /= base;
}
while ( number >= 0 );
strcpy( stringout, buffer );
}
and it prints I beams on my computer when I print %d's :'(
{
char curchar = *msg;
char* ch;
char* str;
unsigned long d;
char* numstring;
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 * );
smprintf( str );
break;
case 'd':
d = va_arg( args, int );
convertInttoString( numstring, d, 10 ); // 10 = the type of
// number system
smprintf( numstring );
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 );
}
void smprintf( char* message )
{
char _curchar = *message;
while ( _curchar != '\0' )
{
// don't check if it's greater or = to ' ' because someone might need to print \n and
// to keep it small, just print all characters
putch( _curchar );
++message;
_curchar = *message;
}
}
//*************************************************************************************************************
//
void convertInttoString( char *stringout, unsigned long number, unsigned base )
{
// If base is 16, it's hex, if it's 10, it's just regular numbers
static char digits[] = "0123456789abcdef";
char buffer[ 20 ], *ptr;
ptr = buffer + sizeof( buffer ) - 1;
*ptr = '\0';
do
{
ptr--;
*ptr = digits[ number % base ];
number /= base;
}
while ( number >= 0 );
strcpy( stringout, buffer );
}
and it prints I beams on my computer when I print %d's :'(
Re:itoa please...
I confess, I never tested the code I posted... :-[
That last line should be:
At this point, [tt]ptr[/tt] points just before the last digit we wrote, somewhere after the start of [tt]buffer[/tt]. Between the start of [tt]buffer[/tt] and [tt]ptr[/tt] there are random characters (what you saw). We want to output characters starting at [tt]ptr[/tt] and going to the end of the string.
BTW: if you want to eliminate [tt]buffer[/tt] and the call to [tt]strcpy[/tt], you could merge the string conversion routine with [tt]printf[/tt].
That last line should be:
Code: Select all
strcpy(stringout, ptr);
BTW: if you want to eliminate [tt]buffer[/tt] and the call to [tt]strcpy[/tt], you could merge the string conversion routine with [tt]printf[/tt].
Re:itoa please...
still prints I beams.......................an also, you got to see FritzOS pk0.7 code...................
Re:itoa please...
I took the sensible route and borrowed all these mundane routines from the DJGPP libc.
Anyway, there's no such thing as itoa in the standard C library. The equivalents are strtoul and strtol.
See here for the various str* routines:
http://cvs.sourceforge.net/cgi-bin/view ... bc/stdlib/
Anyway, there's no such thing as itoa in the standard C library. The equivalents are strtoul and strtol.
See here for the various str* routines:
http://cvs.sourceforge.net/cgi-bin/view ... bc/stdlib/
Re:itoa please...
I have a half working one now...
it prints the number and then the bar character:-X
if I print 999 and then print 0 it comes out
999(bar character) 099(bar character)
is there anything wrong that I can't see?:
char* convertInttoString( long num )
{
long x;
long y = 0;
long z = num;
short a = 1;
char* stringout;
if ( !num )
{
stringout[ 0 ] = 1;
stringout[ 1 ] = '0';
return;
}
if ( num < 0 )
{
stringout[ a++ ] = '-';
num = -num;
}
Loop ( x, 10 )
{
if ( z ) y++;
z /= 10;
}
stringout[ 0 ] = y + a - 1;
while ( y-- )
{
stringout[ y + a ] = ( num % 10 ) + '0';
num /= 10;
}
return stringout;
}
it prints the number and then the bar character:-X
if I print 999 and then print 0 it comes out
999(bar character) 099(bar character)
is there anything wrong that I can't see?:
char* convertInttoString( long num )
{
long x;
long y = 0;
long z = num;
short a = 1;
char* stringout;
if ( !num )
{
stringout[ 0 ] = 1;
stringout[ 1 ] = '0';
return;
}
if ( num < 0 )
{
stringout[ a++ ] = '-';
num = -num;
}
Loop ( x, 10 )
{
if ( z ) y++;
z /= 10;
}
stringout[ 0 ] = y + a - 1;
while ( y-- )
{
stringout[ y + a ] = ( num % 10 ) + '0';
num /= 10;
}
return stringout;
}