Thread: RE: [Dev-C++] integer to string
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: Daniel G. <sp...@ho...> - 2003-04-01 07:07:42
|
What about itoa and atoi functions? >From: "Ioannis Vranos" <iv...@em...> >To: "Dev-C++ Mailing List" <dev...@li...> >Subject: RE: [Dev-C++] integer to string >Date: Tue, 1 Apr 2003 06:13:20 +0300 > > > -----Original Message----- > > From: dev...@li... > > [mailto:dev...@li...] On Behalf > > Of Khalid El-Kary > > Sent: Tuesday, April 01, 2003 5:43 AM > > To: Dev...@li... > > Subject: [Dev-C++] integer to string > > > > > > Hi fellows, > > > > I'm wondering if there's a possible way to turn an integer to > > its string > > representation in C > > > > //I want to get a string "5" out of f > > int f=5; > > > > thanx in advance. > > > > Regards, > > Khalid Al-Kary > > > >#include <stdio.h> > >/* ... */ > >int f=7; > >char s[5]; > >sprintf(s, "%d", f); > > > >Ioannis Vranos > >* Programming pages: http://www.noicys.freeurl.com >* Alternative URL: http://run.to/noicys > > > > >------------------------------------------------------- >This SF.net email is sponsored by: ValueWeb: >Dedicated Hosting for just $79/mo with 500 GB of bandwidth! >No other company gives more support or power for your dedicated server >http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ >_______________________________________________ >Dev-cpp-users mailing list >Dev...@li... >TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm >https://lists.sourceforge.net/lists/listinfo/dev-cpp-users _________________________________________________________________ Hotmail messages direct to your mobile phone http://www.msn.co.uk/msnmobile/mobilehotmail |
|
From: Reid T. <Rei...@at...> - 2003-04-01 12:43:41
|
char buf[99];
int five =3D 5;
sprintf(buf, "%d", five);
printf(" this is five [%s]\n", buf);
--
thanks,
reid
-----Original Message-----
From: Per Westermark [mailto:pw...@ia...]=20
Sent: Tuesday, April 01, 2003 5:12 AM
To: Ricardo L=F3pez Ruiz
Cc: Khalid El-Kary; Dev-C++
Subject: Re: [Dev-C++] integer to string
Note that while itoa is nonstandard, some implementations take two =
parameters, and some take 3.
The third parameter is then number base, i.e. 2 for binary, 8 for octal, =
etc.
/Per W
On Tue, 1 Apr 2003, Ricardo L=F3pez Ruiz wrote:
> perhaps this example can help you a little more.
> Ricardo.
>
>
> **********ITOA/ATOI **********
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int main()
> {
> char cad[20];
>
> /* the transformation: integer --> string */
> itoa(2003,cad,10); // 2003 is the number to store in cad[]
> printf(cad); // in decimal base =3D 10.
>
> /* and the inverse transformation: string --> integer */
> printf("\n %d",atoi(cad)); // cad[ ] is transformed to =
integer
>
> printf("\n\n");
> system("PAUSE");
> return 0;
> }
>
> *************************************
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: ValueWeb:
> Dedicated Hosting for just $79/mo with 500 GB of bandwidth! No other=20
> company gives more support or power for your dedicated server=20
> http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
> _______________________________________________
> Dev-cpp-users mailing list Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
-------------------------------------------------------
This SF.net email is sponsored by: ValueWeb:=20
Dedicated Hosting for just $79/mo with 500 GB of bandwidth!=20
No other company gives more support or power for your dedicated server =
http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
_______________________________________________
Dev-cpp-users mailing list
Dev...@li...
TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
|
|
From: Luigi S. <gi...@li...> - 2003-04-01 21:59:51
|
Hello,
I've revised the previous implementation of "itoa", adding the
enhancements that Per Westmark suggested. The code lacks error
checking, so isn't robust at all.
--
>> gisan >>
t_itoa.c
--------
#include <stdio.h>
#include "itoa.h"
int
main()
{
int k = 123; /* integer value to be converted */
char *s = itoa(k); /* string holding the converted value */
printf("INPUT:\tk = %d\n", k);
printf("OUTPUT:\ts = %s\n\n", s);
k = -4567; /* a little harder: using a negative number */
s = itoa(k);
printf("INPUT:\tk = %d\n", k);
printf("OUTPUT:\ts = %s\n\n", s);
return 0;
}
--------
itoa.h
------
#ifndef itoa_h
#define itoa_h
#pragma defs_in itoa.c /* needed by makefile generator (ignore it) */
/* turn an integer into a string (i.e. an array) */
char *
itoa(int n);
#endif /* not itoa_h */
------
itoa.c
------
#include "itoa.h"
#define MAXSZ 21 /* assuming integer is made of 19 digits + sign */
char *
itoa(int n)
{
static char buf[MAXSZ];
char *p = buf + MAXSZ; /* sweep across buffer */
char neg = 0; /* 1 means that the integer is negative */
if (n < 0) /* negative integer */
{
n = -n; /* work on its absolute value */
neg = 1; /* turn on the flag */
}
*p = '\0'; /* terminate string */
while (n && p > buf) /* main loop */
{
*--p = '0' + n % 10; /* char for a digit as offset from '0' */
n /= 10; /* drop last character */
}
if (neg && p > buf ) /* prepend a negative sign */
*--p = '-';
return p;
}
------
|
|
From: Per W. <pw...@ia...> - 2003-04-02 01:39:54
|
Assign of string termination will be one position off, i.e. outside your
buffer.
A buffer[MAXSZ] may only access from 0 to MAXSZ-1 and the pointer is
initialized to p[MAXSZ], i.e. first index outside the buffer.
/Per W
On Tue, 1 Apr 2003, Luigi Santillo wrote:
> Hello,
>
> I've revised the previous implementation of "itoa", adding the
> enhancements that Per Westmark suggested. The code lacks error
> checking, so isn't robust at all.
>
> --
> >> gisan >>
>
>
>
> t_itoa.c
> --------
> #include <stdio.h>
> #include "itoa.h"
>
> int
> main()
> {
> int k = 123; /* integer value to be converted */
> char *s = itoa(k); /* string holding the converted value */
>
> printf("INPUT:\tk = %d\n", k);
> printf("OUTPUT:\ts = %s\n\n", s);
>
> k = -4567; /* a little harder: using a negative number */
> s = itoa(k);
> printf("INPUT:\tk = %d\n", k);
> printf("OUTPUT:\ts = %s\n\n", s);
>
> return 0;
> }
> --------
>
>
> itoa.h
> ------
> #ifndef itoa_h
> #define itoa_h
> #pragma defs_in itoa.c /* needed by makefile generator (ignore it) */
>
> /* turn an integer into a string (i.e. an array) */
> char *
> itoa(int n);
>
> #endif /* not itoa_h */
> ------
>
>
> itoa.c
> ------
> #include "itoa.h"
> #define MAXSZ 21 /* assuming integer is made of 19 digits + sign */
>
> char *
> itoa(int n)
> {
> static char buf[MAXSZ];
> char *p = buf + MAXSZ; /* sweep across buffer */
> char neg = 0; /* 1 means that the integer is negative */
>
> if (n < 0) /* negative integer */
> {
> n = -n; /* work on its absolute value */
> neg = 1; /* turn on the flag */
> }
>
> *p = '\0'; /* terminate string */
>
> while (n && p > buf) /* main loop */
> {
> *--p = '0' + n % 10; /* char for a digit as offset from '0' */
> n /= 10; /* drop last character */
> }
>
> if (neg && p > buf ) /* prepend a negative sign */
> *--p = '-';
>
> return p;
> }
> ------
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: ValueWeb:
> Dedicated Hosting for just $79/mo with 500 GB of bandwidth!
> No other company gives more support or power for your dedicated server
> http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Luigi S. <gi...@li...> - 2003-04-02 10:12:40
|
On Wed, Apr 02, 2003 at 04:38:41AM +0200, Per Westermark wrote:
> Assign of string termination will be one position off, i.e. outside your
> buffer.
> [..]
Thanks again for pointing out the bug, I'll fix it as shown by the
few code lines below.
One thing I was wondering is: since "buf" is static, may I assume
it is filled with '\0' by the compiler? (So there will be ne need
for me to place the terminating '\0')
itoa.c
------
/* .. */
/* old code: #define MAXSZ 21 */
#define MAXSZ 20 /* assuming integer is made of 19 digits + sign */
char *
itoa(int n)
{
/* old code: static char buf[MAXSZ]; */
static char buf[MAXSZ + 1];
char *p = buf + MAXSZ;
/* ... */
*p = '\0'; /* << really needed ? >> */
}
------
Regards
--
>> gisan >>
|
|
From: Ioannis V. <iv...@em...> - 2003-04-02 10:48:19
|
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...] On Behalf
> Of Luigi Santillo
> Sent: Wednesday, April 02, 2003 9:01 AM
> To: dev...@li...
> Subject: [Dev-C++] itoa - simple implementation [was: integer
> to string]
>
>
> On Wed, Apr 02, 2003 at 04:38:41AM +0200, Per Westermark wrote:
> > Assign of string termination will be one position off, i.e.
> outside your
> > buffer.
> > [..]
>
> Thanks again for pointing out the bug, I'll fix it as shown by the
> few code lines below.
>
> One thing I was wondering is: since "buf" is static, may I assume
> it is filled with '\0' by the compiler? (So there will be ne need
> for me to place the terminating '\0')
>
>
> itoa.c
> ------
> /* .. */
>
> /* old code: #define MAXSZ 21 */
> #define MAXSZ 20 /* assuming integer is made of 19 digits + sign */
>
> char *
> itoa(int n)
> {
> /* old code: static char buf[MAXSZ]; */
> static char buf[MAXSZ + 1];
> char *p = buf + MAXSZ;
> /* ... */
> *p = '\0'; /* << really needed ? >> */
> }
This code is not good. Assume this:
char *p=itoa(9), *q=itoa(10);
I suggest to return a pointer on memory on the free store.
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL: http://run.to/noicys
|
|
From: Ricardo R. <ri...@po...> - 2003-04-02 11:23:38
|
If you are interested in another implementation
of itoa( ) and atoi ( ), here you have the code.
Hope it can be helpful.
Ricardo.
**************ITOA( ) ******************
/* ITOA: Transforms the long n to a string s */
#include <stdio.h>
#include <string.h>
main( )
{
char s[500];
long int n,sign;
int i,j,c;
printf("give me a number to convert:\n");
scanf("%ld",&n);
if((sign=n)<0) /* changing the sign of a negative number */
n=-n;
i=0; /* obtaining the digits of the number */
do{
s[i++]=n%10 + '0';
}while((n/=10)>0);
if(sign<0) /* returning the correct sign */
s[i++]='-';
s[i]='\0'; /* end of the string */
/* reverse (s) */
for(i=0,j=strlen(s)-1 ;i<j ; i++,j--)
{
c=s[i];
s[i]=s[j];
s[j]=c;
}
printf("the result is:\n%s\n",s);
printf("FIN\n");
system("PAUSE");
return 0;
}
************************************
***************** ATOI( ) ***************
/* ATOI: Reading a number as a string s and returning it as a number n */
#include <stdio.h>
main( )
{
char s[100];
long int n; int i;
printf("give a number chain: \n");
gets(s);
printf("your number chain is: %s\n",s);
n=0; /* tranforming s to a number n */
for(i=0;s[i]>='0' && s[i]<='9'; ++i)
n=n*10+(s[i]-'0');
printf("the number is: %ld\n number of digits: %d\n",n,i);
printf("FIN\n");
system("PAUSE");
return 0;
}
************************************
|
|
From: Ioannis V. <iv...@em...> - 2003-04-02 11:46:32
|
My own contribution to this entirely unneded function:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
char *itoa(int i)
{
size_t Length;
char *p;
int temp=i;
for(Length=0; temp/=10; Length++)
;
p=malloc((Length+1)*sizeof(i));
sprintf(p, "%d", i);
return p;
}
Why would anyone need itoa()? With sprinf() one can easily do the
conversion.
sprintf(s,"%d", i);
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL: http://run.to/noicys
|
|
From: Ioannis V. <iv...@em...> - 2003-04-02 13:10:47
|
In my hurry I forgot the basics:
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...] On Behalf
> Of Ioannis Vranos
> Sent: Wednesday, April 02, 2003 2:46 PM
> To: 'Dev-C++'
> Subject: RE: [Dev-C++] itoa - atoi : another implementation
>
>
> My own contribution to this entirely unneded function:
>
> #include <stddef.h>
> #include <stdlib.h>
> #include <stdio.h>
>
>
> char *itoa(int i)
> {
> size_t Length;
> char *p;
> int temp=i;
>
> for(Length=0; temp/=10; Length++)
> ;
>
> p=malloc((Length+1)*sizeof(i));
if(!p)
return NULL;
>
> sprintf(p, "%d", i);
>
> return p;
> }
>
>
>
> Why would anyone need itoa()? With sprinf() one can easily do the
> conversion.
>
>
> sprintf(s,"%d", i);
>
>
> Ioannis Vranos
>
> * Programming pages: http://www.noicys.freeurl.com
> * Alternative URL: http://run.to/noicys
>
|
|
From: Per W. <pw...@ia...> - 2003-04-02 18:14:38
|
You might have been in even more hurry :-)
How many characters do you allocate if the integer was zero, or negative?
And then of course - itoa() with a sprintf() is of very little use, since
it doesn't solve reentrancy problems, doesn't support variable number
base, and doesn't allow linking without the formatted RTL code.
It isn't even a good optimization of number of source code
characters, since each call MUST be either:
free(itoa(i1));
which is an expensive NOP instruction, or:
char *p = itoa(i1);
use_string(p);
free(p);
which isn't much shorter than
char buf[20];
sprintf(buf,"%d",i1);
use_string(buf);
Whith a static buffer in itoa() you get code length improvement
with:
use_string(itoa(i1));
and with a semi-standard implementation of itoa you get code length
improvement AND extra number bases:
char buf[30];
use_string(itoa(i1,buf,3)); // trinary output
/Per W
On Wed, 2 Apr 2003, Ioannis Vranos wrote:
> In my hurry I forgot the basics:
>
>
>
> > -----Original Message-----
> > From: dev...@li...
> > [mailto:dev...@li...] On Behalf
> > Of Ioannis Vranos
> > Sent: Wednesday, April 02, 2003 2:46 PM
> > To: 'Dev-C++'
> > Subject: RE: [Dev-C++] itoa - atoi : another implementation
> >
> >
> > My own contribution to this entirely unneded function:
> >
> > #include <stddef.h>
> > #include <stdlib.h>
> > #include <stdio.h>
> >
> >
> > char *itoa(int i)
> > {
> > size_t Length;
> > char *p;
> > int temp=i;
> >
> > for(Length=0; temp/=10; Length++)
> > ;
> >
> > p=malloc((Length+1)*sizeof(i));
>
> if(!p)
> return NULL;
>
>
> >
> > sprintf(p, "%d", i);
> >
> > return p;
> > }
> >
> >
> >
> > Why would anyone need itoa()? With sprinf() one can easily do the
> > conversion.
> >
> >
> > sprintf(s,"%d", i);
> >
> >
> > Ioannis Vranos
> >
> > * Programming pages: http://www.noicys.freeurl.com
> > * Alternative URL: http://run.to/noicys
>
> >
>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: ValueWeb:
> Dedicated Hosting for just $79/mo with 500 GB of bandwidth!
> No other company gives more support or power for your dedicated server
> http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Ioannis V. <iv...@em...> - 2003-04-02 20:55:03
|
> -----Original Message----- > From: Per Westermark [mailto:pw...@ia...]=20 > Sent: Wednesday, April 02, 2003 10:13 PM > To: Ioannis Vranos > Cc: 'Dev-C++' > Subject: RE: [Dev-C++] itoa - atoi : another implementation=20 >=20 >=20 > You might have been in even more hurry :-) >=20 > How many characters do you allocate if the integer was zero,=20 > or negative? Yes you are right, I forgot the <=3D0 stuff. Well I leave it as an = exercise for home. :) >=20 > And then of course - itoa() with a sprintf() is of very=20 > little use, since > it doesn't solve reentrancy problems, What do you mean. > doesn't support variable number > base, No it doesn't. > and doesn't allow linking without the formatted RTL code. What do you mean. =20 > It isn't even a good optimization of number of source code > characters, since each call MUST be either: > free(itoa(i1)); > which is an expensive NOP instruction, or: It is supposed to be used where free store usage is affordable (almost everywhere these days). No specific constraint requirements were = provided by the OP. > char *p =3D itoa(i1); > use_string(p); > free(p); > which isn't much shorter than > char buf[20]; > sprintf(buf,"%d",i1); > use_string(buf); Yes it isn't. That's why I said itoa() is not needed. =20 > Whith a static buffer in itoa() you get code length improvement > with: > use_string(itoa(i1)); The above is not thread safe (since as I saw you try to embarrass me). = :) You must place a locking mechanism. > and with a semi-standard implementation of itoa you get code length > improvement AND extra number bases: > char buf[30]; > use_string(itoa(i1,buf,3)); // trinary output I do not know any standard or semi-standard impleentation of itoa(). = Even in K&R2 it is not what you are talking about. Ioannis Vranos =20 * Programming pages: http://www.noicys.freeurl.com * Alternative URL: http://run.to/noicys |
|
From: Per W. <pw...@ia...> - 2003-04-02 21:34:46
|
See below. /Per W On Wed, 2 Apr 2003, Ioannis Vranos wrote: > > -----Original Message----- > > From: Per Westermark [mailto:pw...@ia...] > > Sent: Wednesday, April 02, 2003 10:13 PM > > To: Ioannis Vranos > > Cc: 'Dev-C++' > > Subject: RE: [Dev-C++] itoa - atoi : another implementation > > > > > > You might have been in even more hurry :-) > > > > How many characters do you allocate if the integer was zero, > > or negative? > > > > Yes you are right, I forgot the <=0 stuff. Well I leave it as an exercise > for home. :) > > > > > > > And then of course - itoa() with a sprintf() is of very > > little use, since > > it doesn't solve reentrancy problems, > > > What do you mean. > All environments doesn't have a reentrant sprintf() that you might call from an ISR. > > > > doesn't support variable number > > base, > > > No it doesn't. > > > > and doesn't allow linking without the formatted RTL code. > > > What do you mean. The implementation of sprintf() is normally very large. On an environment that links clib static, check size of binary with use of itoa() with static allocation or buffer as input param and compare it with sprintf() and you'll see the difference. In a lot of embedded environments, itoa() is king, because of that. If a microcontroller have 8kB program area, itoa() consumes 100 byte and sprintf() consumes 2kB, the choice is quite easy. > > > > > It isn't even a good optimization of number of source code > > characters, since each call MUST be either: > > free(itoa(i1)); > > which is an expensive NOP instruction, or: > > > It is supposed to be used where free store usage is affordable (almost > everywhere these days). No specific constraint requirements were provided by > the OP. > > > > > char *p = itoa(i1); > > use_string(p); > > free(p); > > which isn't much shorter than > > char buf[20]; > > sprintf(buf,"%d",i1); > > use_string(buf); > > > > Yes it isn't. That's why I said itoa() is not needed. > > > > > > Whith a static buffer in itoa() you get code length improvement > > with: > > use_string(itoa(i1)); > > > The above is not thread safe (since as I saw you try to embarrass me). :) > You must place a locking mechanism. That's why most implementations of itoa takes a buffer as second parameter. > > > > and with a semi-standard implementation of itoa you get code length > > improvement AND extra number bases: > > char buf[30]; > > use_string(itoa(i1,buf,3)); // trinary output > > > I do not know any standard or semi-standard impleentation of itoa(). Even in > K&R2 it is not what you are talking about. A number of impelemntations of itoa: Developer Studio: char *_itoa(int value, char *string, int radix); note: M$ adds the leading _ on a lot of functions, such as _open(), _getcwd(), ... QNX (www.qnx.com): char* itoa(int value, char* buffer, int radix); www.cplusplus.com/ref/cstdlib/itoa.html: char* itoa(int value,char* buffer,int radix); have note: Not defined in ANSI-C. Supported by some compilers. http://developer.novell.com/ndk/doc/libc/index.html?page=/ndk/doc/libc/libc_enu/data/sdk959.html char *itoa(int value,char *buffer,int radix); note: They classifies it as ANSI www.uclibc.org (Small open clib for embedded systems) char *itoa(int i); note: uses static buffer > > > > > Ioannis Vranos > > * Programming pages: http://www.noicys.freeurl.com > * Alternative URL: http://run.to/noicys > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: ValueWeb: > Dedicated Hosting for just $79/mo with 500 GB of bandwidth! > No other company gives more support or power for your dedicated server > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > |
|
From: Ioannis V. <iv...@em...> - 2003-04-02 21:46:55
|
> -----Original Message----- > From: Per Westermark [mailto:pw...@ia...] > Sent: Thursday, April 03, 2003 1:34 AM > To: Ioannis Vranos > Cc: 'Dev-C++' > Subject: RE: [Dev-C++] itoa - atoi : another implementation > > In a lot of embedded environments, itoa() is king, because of that. If > a microcontroller have 8kB program area, itoa() consumes 100 byte and > sprintf() consumes 2kB, the choice is quite easy. My itoa() was not intended for a microcontroler. > > The above is not thread safe (since as I saw you try to > embarrass me). :) > > You must place a locking mechanism. > > That's why most implementations of itoa takes a buffer as second > parameter. But you said: > > It isn't even a good optimization of number of source code > > characters, since each call MUST be either: > > free(itoa(i1)); > > which is an expensive NOP instruction, or: Decide if you consider the free store usage expensive or not. In any case there wan't any requirement for microcontrollers. In any case you try intentionally to embarrass me. :) > www.uclibc.org (Small open clib for embedded systems) > char *itoa(int i); > note: uses static buffer That's nice, mine uses the free store, is thread safe and is intended for systems which can afford 8 kbs space cost. Ioannis Vranos * Programming pages: http://www.noicys.freeurl.com * Alternative URL: http://run.to/noicys |
|
From: Per W. <pw...@ia...> - 2003-04-02 22:42:57
|
See below. /Per W On Thu, 3 Apr 2003, Ioannis Vranos wrote: > > -----Original Message----- > > From: Per Westermark [mailto:pw...@ia...] > > Sent: Thursday, April 03, 2003 1:34 AM > > To: Ioannis Vranos > > Cc: 'Dev-C++' > > Subject: RE: [Dev-C++] itoa - atoi : another implementation > > > > In a lot of embedded environments, itoa() is king, because of that. If > > a microcontroller have 8kB program area, itoa() consumes 100 byte and > > sprintf() consumes 2kB, the choice is quite easy. > > > My itoa() was not intended for a microcontroler. > > > > > > The above is not thread safe (since as I saw you try to > > embarrass me). :) > > > You must place a locking mechanism. > > > > That's why most implementations of itoa takes a buffer as second > > parameter. > > > But you said: I just tried to say that a itoa() with memory allocation is not of much value. It consumes a lot of CPU-time in allocation/release, it requires extra clean-up code, and a failure to clean will result in memory leaks. A itoa(int,char*[,int]) may even be used in a ISR with a deterministic behaviour, i.e. the answer will always be available in a fixed maximum time (with a fixed maximum stack use), and there is no way any running task may have locked a mutex. Code using malloc()/free() are extremely vulnerable for mutex locks. Good implementations of sprintf() is mutex-free, but most of the time the supplier doesn't specify it in the documentation, so you don't know. > > > > It isn't even a good optimization of number of source code > > > characters, since each call MUST be either: > > > free(itoa(i1)); > > > which is an expensive NOP instruction, or: > > > Decide if you consider the free store usage expensive or not. In any case > there wan't any requirement for microcontrollers. In any case you try > intentionally to embarrass me. :) Never any intention of embarrassing anyone. To make you really happy, I just noticed something really embarrasing. The ltoa() implementation for the RTOS I'm using will fail for a radix < 10 because the guy implementing it forgot that a smaller radix requires a bigger buffer. The code assumes wort-case buffer use for radix 10... I always consider dynamic heap usage as expensive. It's (almost) always ok in bread-and-butter programs but in drivers, servers, embedded environments and where the cude must support very long uptime with high memory utilization (constantly being close to the limit of available memory where heap fragmentation gets extra dangerous) great care is needed. A NIC driver that allocates all packets when they arrive might easily get half transfer speed compared to a driver using a packet pool. This is a bit of problem with object-oriented languages, since extra allocations are so easily hidden somewhere in a base class constructor/destructor etc, and if you don't know what speed you should expect from your code, you don't notice the hidden slowdown. > > > > www.uclibc.org (Small open clib for embedded systems) > > char *itoa(int i); > > note: uses static buffer > > > That's nice, mine uses the free store, is thread safe and is intended for > systems which can afford 8 kbs space cost. > It isn't uncommon that sprintf() uses a itoa(int,char*,int) (or ltoa) to implement the %d support. I just checked on a RTOS I'm using and noticed that their ltoa() would fail for a radix < 10 because of too small > > > > Ioannis Vranos > > * Programming pages: http://www.noicys.freeurl.com > * Alternative URL: http://run.to/noicys > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: ValueWeb: > Dedicated Hosting for just $79/mo with 500 GB of bandwidth! > No other company gives more support or power for your dedicated server > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > |
|
From: Ioannis V. <iv...@em...> - 2003-04-02 22:56:31
|
> -----Original Message----- > From: Per Westermark [mailto:pw...@ia...]=20 > Sent: Thursday, April 03, 2003 2:42 AM > To: Ioannis Vranos > Cc: 'Dev-C++' > Subject: RE: [Dev-C++] itoa - atoi : another implementation=20 >=20 >=20 > I just tried to say that a itoa() with memory allocation is not of > much value. It consumes a lot of CPU-time in allocation/release, it > requires extra clean-up code, and a failure to clean will=20 > result in memory > leaks. Yes, if we are not good coders we can't depend on the library to do our work. The library is responsible for its work only, and if it fails it signals failure in case we know how to handle the problem or to abort = under control. So "don't use memory on the free store because the user needs clean up = code and may have memory leaks" is not a problem of the library coder. Regarding time cost, I prefer thread safety to time cost. If time cost = of malloc()/free() is considered huge you can provide a special itoa() or = work with a default parameter in C++ which would be nice. char *itoa(int number, char *buffer=3D0); For usual systems I would use an std::string. > A itoa(int,char*[,int]) may even be used in a ISR with a deterministic > behaviour, i.e. the answer will always be available in a fixed maximum > time (with a fixed maximum stack use), and there is no way any running > task may have locked a mutex. Code using malloc()/free() are extremely > vulnerable for mutex locks. Good implementations of sprintf() is Sorry, I have no idea what mutex locks are (and I don't want to bother = to searh in google, my current priority are PCs). > mutex-free, but most of the time the supplier doesn't specify=20 > it in the > documentation, so you don't know. >=20 > Never any intention of embarrassing anyone. To make you=20 > really happy, I > just noticed something really embarrasing. The ltoa()=20 > implementation for > the RTOS I'm using will fail for a radix < 10 because the guy=20 > implementing > it forgot that a smaller radix requires a bigger buffer. The=20 > code assumes > wort-case buffer use for radix 10... >=20 > I always consider dynamic heap usage as expensive. Because you work for microcontrollers. On the other hand my major = concern is .NET. :) > It's=20 > (almost) always ok > in bread-and-butter programs but in drivers, servers, embedded > environments and where the cude must support very long uptime=20 > with high > memory utilization (constantly being close to the limit of available > memory where heap fragmentation gets extra dangerous) great care is > needed. I understand. Well if you do bare metal programming you cann allocate = the entire free store and use it in a defragmented way (=3Dtime cost). But = if you do not use the free store, all that memory will go useless? The best approach is use memory on the free store and if it gets too fragmented = use the automatic storage/stack. C++ provides the ability to define the "placement operator new" which is very nice since you can program it to use the stack instead of the heap = or a combination of them! =20 > A NIC driver that allocates all packets when they arrive=20 > might easily get > half transfer speed compared to a driver using a packet pool.=20 > This is a > bit of problem with object-oriented languages, since extra=20 > allocations are > so easily hidden somewhere in a base class=20 > constructor/destructor etc, and > if you don't know what speed you should expect from your=20 > code, you don't > notice the hidden slowdown. OK. Ioannis Vranos =20 * Programming pages: http://www.noicys.freeurl.com * Alternative URL: http://run.to/noicys |
|
From: Per W. <pw...@ia...> - 2003-04-02 17:45:17
|
The most common is one of the following declarations:
void itoa(int num, char *buf, int base);
void itoa(int num, char *buf);
Neither have problem with lost memory, and both are reentrant.
The first form is always useful, since it allows adjustable number base,
i.e. binary, trinary, ...
The second form is only needed in embedded programs, since it requires
less RTL support than the big-big-big sprintf() - note that sprintf()
doesn't know whet additional support that is required, so it has code for
left-adjust, right-adjust, int, long, signed, unsigned, string, pointer,
float, double, ...
/Per W
On Wed, 2 Apr 2003, Ioannis Vranos wrote:
> My own contribution to this entirely unneded function:
>
> #include <stddef.h>
> #include <stdlib.h>
> #include <stdio.h>
>
>
> char *itoa(int i)
> {
> size_t Length;
> char *p;
> int temp=i;
>
> for(Length=0; temp/=10; Length++)
> ;
>
> p=malloc((Length+1)*sizeof(i));
>
> sprintf(p, "%d", i);
>
> return p;
> }
>
>
>
> Why would anyone need itoa()? With sprinf() one can easily do the
> conversion.
>
>
> sprintf(s,"%d", i);
>
>
> Ioannis Vranos
>
> * Programming pages: http://www.noicys.freeurl.com
> * Alternative URL: http://run.to/noicys
>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: ValueWeb:
> Dedicated Hosting for just $79/mo with 500 GB of bandwidth!
> No other company gives more support or power for your dedicated server
> http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Ioannis V. <iv...@em...> - 2003-04-02 20:46:25
|
> -----Original Message----- > From: Per Westermark [mailto:pw...@ia...]=20 > Sent: Wednesday, April 02, 2003 9:44 PM > To: Ioannis Vranos > Cc: 'Dev-C++' > Subject: RE: [Dev-C++] itoa - atoi : another implementation=20 >=20 >=20 > The most common is one of the following declarations: > void itoa(int num, char *buf, int base); > void itoa(int num, char *buf); >=20 > Neither have problem with lost memory, and both are reentrant. >=20 > The first form is always useful, since it allows adjustable=20 > number base, > i.e. binary, trinary, ... I had written some time ago an unsigned to string conversion function in = any number system. But after some time I erased it because except of = hexadecimal and octadecimal systems, it is very rare to use trinary etc in a = program. And for hex and oct we can do the job with the printf() family. > The second form is only needed in embedded programs, since it requires > less RTL support than the big-big-big sprintf() - note that sprintf() > doesn't know whet additional support that is required, so it=20 > has code for > left-adjust, right-adjust, int, long, signed, unsigned,=20 > string, pointer, > float, double, ... I haven't played with embedded systems, but for usual ones I consider = the horsepower/memory enough so as to have the entire C90. I think that if a system can't hold C90, it can only be programmed with assembly. Memory = is very cheap these days. For example one could place an intel processor = with 1 mb ram easily in an embedded system (e.g. just a 286 or some of the = intel processors used for palmtops etc, or from other companies). Ioannis Vranos =20 * Programming pages: http://www.noicys.freeurl.com * Alternative URL: http://run.to/noicys |
|
From: Per W. <pw...@ia...> - 2003-04-02 18:12:24
|
It takes less code - and is faster - to count needed buffer space and
insert backwards than to have to flip at the end.
One more thing. Why call j=3Dstrlen(s)-1 in the last loop, when you already
know how many characters you have inserted in the string?
/Per W
On Wed, 2 Apr 2003, Ricardo L=F3pez Ruiz wrote:
> If you are interested in another implementation
> of itoa( ) and atoi ( ), here you have the code.
> Hope it can be helpful.
> Ricardo.
>
>
> **************ITOA( ) ******************
> /* ITOA: Transforms the long n to a string s */
> #include <stdio.h>
> #include <string.h>
> main( )
> {
> char s[500];
> long int n,sign;
> int i,j,c;
>
> printf("give me a number to convert:\n");
> scanf("%ld",&n);
> if((sign=3Dn)<0) /* changing the sign of a negative number */
> n=3D-n;
>
> i=3D0; /* obtaining the digits of the number */
> do{
> s[i++]=3Dn%10 + '0';
> }while((n/=3D10)>0);
>
> if(sign<0) /* returning the correct sign */
> s[i++]=3D'-';
> s[i]=3D'\0'; /* end of the string */
>
> /* reverse (s) */
> for(i=3D0,j=3Dstrlen(s)-1 ;i<j ; i++,j--)
> {
> c=3Ds[i];
> s[i]=3Ds[j];
> s[j]=3Dc;
> }
>
> printf("the result is:\n%s\n",s);
> printf("FIN\n");
> system("PAUSE");
> return 0;
> }
> ************************************
>
> ***************** ATOI( ) ***************
> /* ATOI: Reading a number as a string s and returning it as a number n */
>
> #include <stdio.h>
> main( )
> {
> char s[100];
> long int n; int i;
>
> printf("give a number chain: \n");
> gets(s);
> printf("your number chain is: %s\n",s);
>
> n=3D0; /* tranforming s to a number n */
> for(i=3D0;s[i]>=3D'0' && s[i]<=3D'9'; ++i)
> n=3Dn*10+(s[i]-'0');
>
> printf("the number is: %ld\n number of digits: %d\n",n,i);
> printf("FIN\n");
> system("PAUSE");
> return 0;
> }
> ************************************
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: ValueWeb:
> Dedicated Hosting for just $79/mo with 500 GB of bandwidth!
> No other company gives more support or power for your dedicated server
> http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Ricardo R. <ri...@po...> - 2003-04-03 08:16:54
|
you are right, you dont need to call strlen( ) and by the way, to include the header "string.h". Ricardo. |
|
From: Per W. <pw...@ia...> - 2003-04-02 18:10:37
|
For a itoa() that returns a pointer, you normally want it defined similar
to asctime(), ctime(), gmtime(), localtime(), ...
If you then need multiple calls before doing something else, you may then
always do:
strcpy(buf1,itoa(i1));
strcpy(buf2,itoa(i2));
...
A dynamically allocating itoa() would be very hard to use in an efficient
way without memory leaks.
You normally don't need to call itoa multiple times before using the
results, since the majority use of itoa() is for output, and if you
have printf(), the following code is meaningless:
char *p1 = itoa(i1), *p2 = itoa(i2);
printf("The result was %s and %s\n",p1,p2);
itoa() is often used in embedded systems where you might not have room
for printf(), and then your output function doesn't support variable
arguments, i.e. you have to do something like:
send(COM1,"The result was ");
send(COM1,itoa(i1));
send(COM1," and ");
send(COM1,itoa(i2));
send(COM1,"\n");
However, the normal implementation of itoa() is with a pointer to buffer
as the second parameter, and possible a number base as third parameter.
Then you have the best of two worlds. Reentrant, quick, non-leaking, ...
/Per W
On Wed, 2 Apr 2003, Ioannis Vranos wrote:
> > -----Original Message-----
> > From: dev...@li...
> > [mailto:dev...@li...] On Behalf
> > Of Luigi Santillo
> > Sent: Wednesday, April 02, 2003 9:01 AM
> > To: dev...@li...
> > Subject: [Dev-C++] itoa - simple implementation [was: integer
> > to string]
> >
> >
> > On Wed, Apr 02, 2003 at 04:38:41AM +0200, Per Westermark wrote:
> > > Assign of string termination will be one position off, i.e.
> > outside your
> > > buffer.
> > > [..]
> >
> > Thanks again for pointing out the bug, I'll fix it as shown by the
> > few code lines below.
> >
> > One thing I was wondering is: since "buf" is static, may I assume
> > it is filled with '\0' by the compiler? (So there will be ne need
> > for me to place the terminating '\0')
> >
> >
> > itoa.c
> > ------
> > /* .. */
> >
> > /* old code: #define MAXSZ 21 */
> > #define MAXSZ 20 /* assuming integer is made of 19 digits + sign */
> >
> > char *
> > itoa(int n)
> > {
> > /* old code: static char buf[MAXSZ]; */
> > static char buf[MAXSZ + 1];
> > char *p = buf + MAXSZ;
> > /* ... */
> > *p = '\0'; /* << really needed ? >> */
> > }
>
>
> This code is not good. Assume this:
>
>
> char *p=itoa(9), *q=itoa(10);
>
>
> I suggest to return a pointer on memory on the free store.
>
>
>
>
> Ioannis Vranos
>
> * Programming pages: http://www.noicys.freeurl.com
> * Alternative URL: http://run.to/noicys
>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: ValueWeb:
> Dedicated Hosting for just $79/mo with 500 GB of bandwidth!
> No other company gives more support or power for your dedicated server
> http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Luigi S. <gi...@li...> - 2003-04-03 07:21:14
|
On Wed, Apr 02, 2003 at 01:48:06PM +0300, Ioannis Vranos wrote: > This code is not good. Assume this: > > > char *p=itoa(9), *q=itoa(10); > > > I suggest to return a pointer on memory on the free store. > Hello, You are right, my simple implementation does not cope well with the above situation. I used the free store in my first implementation, then, following some advice, I attempted to use a static array, as that would probably be faster. Thanks for your suggestion -- >> gisan >> |
|
From: Per W. <pw...@ia...> - 2003-04-03 10:07:59
|
But the following code works: char buf1[30],buf2[30],*p1 = itoa(9,buf1), *p2 = itoa(10,buf2); It's quick since it doesn't use dynamic memory. It's reentrant since the thread uses it's own buffers and not a global buffer hidden somewhere within the itoa() implementation. It supports multiple stored answers for each thread. It may never leak memory, since the buffers are auto-allocated. That's why just about all itoa() implementations available with compilers or OS are taking the pointer as an input parameter. /Per W On Wed, 2 Apr 2003, Luigi Santillo wrote: > On Wed, Apr 02, 2003 at 01:48:06PM +0300, Ioannis Vranos wrote: > > This code is not good. Assume this: > > > > > > char *p=itoa(9), *q=itoa(10); > > > > > > I suggest to return a pointer on memory on the free store. > > > > Hello, > > You are right, my simple implementation does not cope well > with the above situation. I used the free store in my first > implementation, then, following some advice, I attempted to > use a static array, as that would probably be faster. > > Thanks for your suggestion > -- > >> gisan >> > > > ------------------------------------------------------- > This SF.net email is sponsored by: ValueWeb: > Dedicated Hosting for just $79/mo with 500 GB of bandwidth! > No other company gives more support or power for your dedicated server > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > |
|
From: Per W. <pw...@ia...> - 2003-04-02 17:35:48
|
Yes, global variables and static variables are always zero-filled on
startup, so in this case, you could skip the terminating zero.
/Per W
On Wed, 2 Apr 2003, Luigi Santillo wrote:
> On Wed, Apr 02, 2003 at 04:38:41AM +0200, Per Westermark wrote:
> > Assign of string termination will be one position off, i.e. outside your
> > buffer.
> > [..]
>
> Thanks again for pointing out the bug, I'll fix it as shown by the
> few code lines below.
>
> One thing I was wondering is: since "buf" is static, may I assume
> it is filled with '\0' by the compiler? (So there will be ne need
> for me to place the terminating '\0')
>
>
> itoa.c
> ------
> /* .. */
>
> /* old code: #define MAXSZ 21 */
> #define MAXSZ 20 /* assuming integer is made of 19 digits + sign */
>
> char *
> itoa(int n)
> {
> /* old code: static char buf[MAXSZ]; */
> static char buf[MAXSZ + 1];
> char *p = buf + MAXSZ;
> /* ... */
> *p = '\0'; /* << really needed ? >> */
> }
> ------
>
> Regards
> --
> >> gisan >>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: ValueWeb:
> Dedicated Hosting for just $79/mo with 500 GB of bandwidth!
> No other company gives more support or power for your dedicated server
> http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Luigi S. <gi...@li...> - 2003-04-03 07:21:18
|
Hello Per, I see that you have mentioned that an implementation of itoa which has the interface: void itoa(int n, char *s); would be "reentrant". This concept is not clear to me, I would appreciate if you could elaborate a little about it, for instance you could point out the weakness (or "reentrancy" problems) related to the interface char *itoa(int n); and how these would be solved adopting the 2 parameters - void returning - function. TIA -- >> gisan >> |
|
From: Per W. <pw...@ia...> - 2003-04-03 10:04:41
|
Since the caller supplies the buffer, itoa() then doesn't need to touch any global variables. That makes it possible for one thread to call itoa(), a task switch to happen and a new new thread to call itoa() without either a static buffer being corrupted by the two concurrent calls, or the second thread being blocked by a critical section. With a unprotected static buffer owned by itoa(), a second call from another thread while itoa() runs, or before the first thread is done with the returned pointer, would clear the static buffer and immediately try to reuse it. If the static buffer is protected by a critical section or mutex, then only one thread at a time may use the buffer INSIDE itoa(), while any other callers will be blocked until the first itoa() call returns. However, the calling program will not be able to use the static buffer before the next call from the other thread destroys the buffer. If the buffer is dynamically allocated, each concurrent call of itoa() will have their own buffer. This makes the call thread-safe. However, the allocation malloc(), calloc(), strdup(), new or whatever, must access a global list of available memory blocks for performing the allocation. To make these functions thread-safe, they will have to protect the actual allocation within a mutex or critical section. While this makes them thread-safe, it doesn't make them fully reentrant, since a second allocation call may not finish until the first allocation is through. This will force the second thread - doesn=B4t matter how high prio it has - to lock up until the first allocation is done. If implementing a ISR - interrupt service routine - it would not be alloced to cal the allocation function, so it woun't be allowed to call an itoa() that uses dynamic memory. That is because while the interrupt routine is active, there isn't possible for the OS to activate any threads. The thread calling itoa() would then permanently lock the ISR from ending, resulting in a dead-lock. When you send in the buffer as a parameter to itoa(), you never get that kind of problem, since each caller themself arrange for needed memory in a suitable way. All running tasks have their own stack so an auto-allocated buffer works find. As long as the buffer isn't large enough, the ISR may also allocate a buffer on the stack - it will denepnding on OS either have it's own OS-reserved stack, or using the free area of the currently running thread's stack. /Per W On Wed, 2 Apr 2003, Luigi Santillo wrote: > Hello Per, > > I see that you have mentioned that an implementation of itoa > which has the interface: > > void itoa(int n, char *s); > > would be "reentrant". This concept is not clear to me, I would > appreciate if you could elaborate a little about it, for instance > you could point out the weakness (or "reentrancy" problems) related > to the interface > > char *itoa(int n); > > and how these would be solved adopting the 2 parameters - void returning = - > function. > > TIA > -- > >> gisan >> > > > ------------------------------------------------------- > This SF.net email is sponsored by: ValueWeb: > Dedicated Hosting for just $79/mo with 500 GB of bandwidth! > No other company gives more support or power for your dedicated server > http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > |