Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

itoa

16 réponses
Avatar
alain
Quelqu'un a t-il ecrit cette fonction absente de stdlib.h pour gcc ?

6 réponses

1 2
Avatar
Charlie Gordon
"flure" wrote in message
news:42013152$0$26208$
Quelqu'un a t-il ecrit cette fonction absente de stdlib.h pour gcc ?



Pas besoin, sprintf convient tout à fait pour cela ...


On peut supposer que l'OP veut convertir en base 10, et sprintf convient
effectivement pour cela, bien qu'il soit nettement préférable d'utiliser
snprintf().

En revanche, si l'OP cherche la fonction qui convertit dans une base quelconque,
comme strtoi(), sprintf ne convient que pour certaines bases constantes, et on
peut utiliser le source fourni dans K&R a titre d'exemple. C'est bien un
scandale que cette fonction ne soit pas normalisee dans C99.

Chqrlie.


Avatar
pat
Le bon reflexe GOOGLE.FR
En 20 secondes, j'ai trouvé ça !

pat

============================
/* Small c library, by Jeremy Dewey ()
http://www.seashellinc.com/jdewey

Synopsis:
itoa(char* str, int number)

Description:
converts the number to its string representation and stores it in str,
returning a pointer to str.

Example:
char str[6];
itoa(str, 568);

Notes:

*/

#include <ctype.h>
#include <stdlib.h>

char *itoa(char *str, int num)
{
int k;
char c, flag, *ostr;

if (num < 0) {
num = -num;
*str++ = '-';
}
k = 10000;
ostr = str;
flag = 0;
while (k) {
c = num / k;
if (c || k == 1 || flag) {
num %= k;
c += '0';
*str++ = c;
flag = 1;
}
k /= 10;
}
*str = '';
return ostr;
}


"alain" a écrit dans le message news:


Quelqu'un a t-il ecrit cette fonction absente de stdlib.h pour gcc ?




Avatar
Charlie Gordon
"pat" wrote in message
news:421d4b6c$0$851$
Le bon reflexe GOOGLE.FR
En 20 secondes, j'ai trouvé ça !

pat

============================ >
/* Small c library, by Jeremy Dewey ()
http://www.seashellinc.com/jdewey

Synopsis:
itoa(char* str, int number)

Description:
converts the number to its string representation and stores it in str,
returning a pointer to str.

Example:
char str[6];
itoa(str, 568);

Notes:

*/

#include <ctype.h>
#include <stdlib.h>

char *itoa(char *str, int num)
{
int k;
char c, flag, *ostr;

if (num < 0) {
num = -num;
*str++ = '-';
}
k = 10000;
ostr = str;
flag = 0;
while (k) {
c = num / k;
if (c || k == 1 || flag) {
num %= k;
c += '0';
*str++ = c;
flag = 1;
}
k /= 10;
}
*str = '';
return ostr;
}


Dommage que ce soit buggy pour num négatif : le pointeur retourné est str+1 au
lieu de str. Et que ce soit limite UB pour num==INT_MIN : il faudrait passer
par une variable locale num1 non signée.

Chqrlie.

Avatar
Serge Paccalin
Le jeudi 24 février 2005 à 21:04:58, Charlie Gordon a écrit dans
fr.comp.lang.c :

"pat" wrote in message
news:421d4b6c$0$851$

Le bon reflexe GOOGLE.FR
En 20 secondes, j'ai trouvé ça !

k = 10000;


Dommage que ce soit buggy pour num négatif : le pointeur retourné est str+1 au
lieu de str. Et que ce soit limite UB pour num==INT_MIN : il faudrait passer
par une variable locale num1 non signée.

Chqrlie.


De plus, ce 10000 me parait suspect, en ces temps d'int 32 bits ou plus.

--
___________ 2005-02-26 01:52:15
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763


Avatar
pat
Bonjour,

Que des remarques exacts et parfaitement justifiées !

Alors puisque ça vous a plu en voici une autre version , un peu plus
sophistiquée, trouvée sur le net bien sur.!

J'avais les sources de l'original de Unix VII , sur des diquettes 5 pouces
mais j'ai bien peur de ne plus les retrouver...

Enfin personnellement j'aurais utilisé le sprintf comme indiqué avant, c'est
juste pour l'intérêt intellectuel, je retrouve bien là , l'ambiance puriste
des programmeurs C avec l'état d'esprit de K&R qui rode près de nous, (des
bons souvenirs d'équipes...), qui voudraient faire des fonctions complètes
sur un minimum de lignes écrites en C, parfois mème au détriment de la
lisibilité.

pat

===================== char *
itoa(int value, char *string, int radix)
{
char tmp[33];
char *tp = tmp;
int i;
unsigned v;
int sign;
char *sp;

if (radix > 36 || radix <= 1)
{
__set_errno(EDOM);
return 0;
}

sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned)value;
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}

if (string == 0)
string = (char *)malloc((tp-tmp)+sign+1);
sp = string;

if (sign)
*sp++ = '-';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}



===================== "Serge Paccalin" a écrit dans le message
news:
Le jeudi 24 février 2005 à 21:04:58, Charlie Gordon a écrit dans
fr.comp.lang.c :

"pat" wrote in message
news:421d4b6c$0$851$

Le bon reflexe GOOGLE.FR
En 20 secondes, j'ai trouvé ça !

k = 10000;


Dommage que ce soit buggy pour num négatif : le pointeur retourné est
str+1 au


lieu de str. Et que ce soit limite UB pour num==INT_MIN : il faudrait
passer


par une variable locale num1 non signée.

Chqrlie.


De plus, ce 10000 me parait suspect, en ces temps d'int 32 bits ou plus.

--
___________ 2005-02-26 01:52:15
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763




Avatar
Targeur fou
pat wrote:
Bonjour,


Bonjour,

[coupé]

juste pour l'intérêt intellectuel, je retrouve bien là ,
l'ambiance puriste

des programmeurs C avec l'état d'esprit de K&R qui rode près de
nous, (des

bons souvenirs d'équipes...), qui voudraient faire des fonctions
complètes

sur un minimum de lignes écrites en C, parfois mème au détriment
de la

lisibilité.


Bof, je ne sais pas si c'est le credo de tous les puristes du C,
notamment ceux qui naviguent dans les parages, ils préfèrent du code
de bonne qualité et la lisibilité en fait partie, rien que pour des
questions de maintenance.

La fonction ci-dessous me paraît déjà beaucoup mieux et plus
explicite (quoique que plus d'accolades ça ne mangeait pas de pain)
que la précédente, à quelques détails près.


======================
char *
itoa(int value, char *string, int radix)
{
char tmp[33];
char *tp = tmp;
int i;
unsigned v;
int sign;
char *sp;

if (radix > 36 || radix <= 1)
{
__set_errno(EDOM);


__set_errno(EDOM) doit être un truc dépendant de
l'implémentation.
Pourquoi pas errno = EDOM; tout court ?

return 0;
}

sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned)value;
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}

if (string == 0)
string = (char *)malloc((tp-tmp)+sign+1);
sp = string;

if (sign)
*sp++ = '-';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;


Si string est NULL après le malloc, sp l'est aussi. Ca peut faire
boum.

return string;
}



Regis

1 2