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

conversion int vers string

47 réponses
Avatar
sebosac
salut,

je cherche a convertir un int en string:


<stdlib.h>

char string[255];


itoa(1664,&string,10);



mais le compilateur me dit qu'il ne peut linker car le symbole _itoa n'existe pas.


il y aurais t'il une autre solution ?

merci

10 réponses

1 2 3 4 5
Avatar
DINH Viêt Hoà

je cherche a convertir un int en string:

il y aurais t'il une autre solution ?


snprintf()

--
DINH V. Hoa,

"Je suis une merde" -- jyb

Avatar
Emmanuel Delahaye
sebosac wrote on 30/10/04 :
je cherche a convertir un int en string:

<stdlib.h>

char string[255];


itoa(1664,&string,10);


Pas standard. (Quand au '&string', je préfère ne pas en parler...)

mais le compilateur me dit qu'il ne peut linker car le symbole _itoa n'existe
pas.


C'est ce qui arrive quand on utilise des fonctions non standard dont on
a pas le source...

il y aurais t'il une autre solution ?


sprintf()
[C99] snprintf()

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Avatar
Charlie Gordon
"Emmanuel Delahaye" wrote in message
news:
sebosac wrote on 30/10/04 :
je cherche a convertir un int en string:

<stdlib.h>

char string[255];


itoa(1664,&string,10);


Pas standard. (Quand au '&string', je préfère ne pas en parler...)

mais le compilateur me dit qu'il ne peut linker car le symbole _itoa
n'existe


pas.


C'est ce qui arrive quand on utilise des fonctions non standard dont on
a pas le source...


Le source est largement disponible (GNU, BSD...) !

C'est bien débile de la part du comité de normalisation de ne pas avoir
standardisé itoa et ultoa alors que strtol et tous ses dérivés sont passés !
Ce manque de cohérence a pour conséquence qu'on est capable de convertir en
entier des chaines de caractères les représentant dans toutes les bases de 2 à
36, mais que dans l'autre sens on est limité à 8, 10 et 16 avec une syntaxe
(snprintf) qui n'a rien a voir et qui n'est pas sans pièges. Sans compter
l'inefficacité et la lourdeur de la méthode.
On évoquait récemment l'utilité des valeurs binaires litérales, eh bien en C on
est même pas capable de les produire !
Dans C99 on a même rajouté toute une collection de strtoimax, wcstoimax... Les
mouches n'ont qu'à bien se tenir au WG14 !

Chqrlie.


Avatar
DINH Viêt Hoà

C'est bien débile de la part du comité de normalisation de ne pas avoir
standardisé itoa et ultoa alors que strtol et tous ses dérivés sont passés !
Ce manque de cohérence a pour conséquence qu'on est capable de convertir en
entier des chaines de caractères les représentant dans toutes les bases de 2 à
36, mais que dans l'autre sens on est limité à 8, 10 et 16 avec une syntaxe
(snprintf) qui n'a rien a voir et qui n'est pas sans pièges. Sans compter
l'inefficacité et la lourdeur de la méthode.


en quoi snprintf() est lourd et inefficace ?
il ne nécessite pas d'allocation mémoire, contrairement à itoa() et ses
congénères. Ce que je trouve plus efficace.
Et je ne vois pas en quoi itoa() peut-être plus efficace vu que les
opérations utilisées seront les mêmes que snprintf() à part l'allocation
mémoire initiale de itoa().
Il vaut mieux également essayer de ne pas avoir beaucoup de fonctions
qui ont une utilité identique ou bien qui recouvre l'usage de l'autre
sur un ensemble plus réduit.

--
DINH V. Hoa,

"Et alors, les parents d'Odile ? Ils sont trop cool, et tout ce qu'ils
veulent, c'est qu'elle sorte en boîte tous le soirs [...]
et ils militent contre les maths à l'école ?" -- Virginie Despentes

Avatar
Charlie Gordon
"DINH Viêt Hoà" wrote in message
news:

C'est bien débile de la part du comité de normalisation de ne pas avoir
standardisé itoa et ultoa alors que strtol et tous ses dérivés sont passés !
Ce manque de cohérence a pour conséquence qu'on est capable de convertir en
entier des chaines de caractères les représentant dans toutes les bases de 2
à


36, mais que dans l'autre sens on est limité à 8, 10 et 16 avec une syntaxe
(snprintf) qui n'a rien a voir et qui n'est pas sans pièges. Sans compter
l'inefficacité et la lourdeur de la méthode.


en quoi snprintf() est lourd et inefficace ?


Parce que passer une chaine de format à une fonction générique pour faire une
conversion simple me semble plus lourd et forcément moins efficace. Par exemple
putc(c,fp) me semble plus efficace que fprintf(fp, "%c", c);

il ne nécessite pas d'allocation mémoire, contrairement à itoa() et ses
congénères. Ce que je trouve plus efficace.


De quelle allocation mémoire parles-tu ? Du tableau automatique que certaines
implémentations utilisent ?
Ce qui est regrettable dans itoa, c'est que la taille du tableau résultat n'est
pas spécifiée dans l'appel, avec les problèmes de débordement de tableaux que
cela peut poser si le programmeur est peu méfiant ou que la taille des types
entiers change au delà de ses attentes.

Et je ne vois pas en quoi itoa() peut-être plus efficace vu que les
opérations utilisées seront les mêmes que snprintf() à part l'allocation
mémoire initiale de itoa().


parce que snprintf finira par appeler la fonction que je me propose d'appeler
directement.

Il vaut mieux également essayer de ne pas avoir beaucoup de fonctions
qui ont une utilité identique ou bien qui recouvre l'usage de l'autre
sur un ensemble plus réduit.


C'est faux, d'abord le langage est truffé de méthodes différentes pour faire
chaque chose, ensuite ce ne sont pas des fonctions avec une utilité identique,
mais d'une fonction simple pour un usage et d'une fonction riche qui utilisée
d'une certaine facon permet d'obtenir un résultat (presque) identique.

Dans un programme qui fait beaucoup de conversions int->str, ou qui a besoin de
les faire très vite, on regrettera de n'avoir que snprintf() pour ce faire. On
peut bien sur faire faire des exploits au compilateur avec des extensions du
préprocesseur pour détecter un tel usage, mais c'est quand même pas une solution
générale.

Enfin itoa permet de choisir la base de conversion, ce que snprintf ne peut
faire que pour l'octal, le decimal ou l'hexadecimal, avec une méthode inefficace
si la base est variable. Par exemple convertir un int en binaire n'est pas
possible avec snprintf.

Chqrlie.


Avatar
Antoine Leca
En cm80l7$7ai$, Charlie Gordon va escriure:
DINH Viêt Hoà wrote in message
news:

C'est bien débile de la part du comité de normalisation de ne pas
avoir standardisé itoa et ultoa alors que strtol et tous ses
dérivés sont passés ! Ce manque de cohérence




Le problème c'est le manque de cohérence de la bibliothèque C (originale)
quand il s'agit de renvoyer un résultat sous forme de chaîne de caractères.

a pour conséquence qu'on est capable de convertir en entier des
chaines de caractères les représentant dans toutes les bases de
2 à 36, mais que dans l'autre sens on est limité à 8, 10 et 16




Sans blague, tu ne crois pas que l'histoire de « toutes les bases » c'est du
sucre qui a été mis là parce que cela ne coutait rien, mais qui ne sert à
personne dans la réalité ?

Ada aussi a un moyen de spécifier des bases anormales, y compris pour les
constantes entières; je me demande comment réagirait un comité de relecture
si on écrivait 7#1245#? ;-)


avec une syntaxe
(snprintf) qui n'a rien a voir et qui n'est pas sans pièges.




Si tu passes tous les paramètres équivalents à ceux de strtol à _ltostr,
plus ceux pour gérer la chaîne et son allocation, tu va finir avec une
syntaxe plutôt lourde, tu ne crois pas ?

Sans compter l'inefficacité et la lourdeur de la méthode.


en quoi snprintf() est lourd et inefficace ?


Parce que passer une chaine de format à une fonction générique pour
faire une conversion simple me semble plus lourd et forcément moins
efficace.


Plus lourd: je ne sais pas; pour le cerveau du programmeur, en tous cas,
c'est pas plus lourd, puisque de toute façon il est obligé de maîtriser les
formats pour printf.

Moins efficace, là c'est carrément pas évident: la plupart des programmes
sont lié avec le code générique de printf, la plupart des bibliothèques qui
ont à arbitrer l'espace ont un mécanisme pour ne pas s'encombrer de la
bibliothèque des flottants, et le code qui reste (en C90 "C" only) c'est à
plus de 90 % celui que de toute manière tu es obligé d'avoir, les autres 10
% gérant le décodage et les formats de chaînes. Reste à savoir si passer 3
arguments par paramètres est plus efficace que de passer la chaîne constante
"%d".

Par exemple putc(c,fp) me semble plus efficace que fprintf(fp, "%c", c);


Oui. Et je me demande ce qu'il en est pour puts("ma chaine:", fp),
puts(chaine, fp), putc('n', fp); par rapport au fprintf équivalent.
Mais cela n'a pas grand chose à voir avec le sujet.


Ce qui est regrettable dans itoa, c'est que la taille du tableau
résultat n'est pas spécifiée dans l'appel, avec les problèmes de
débordement de tableaux que cela peut poser si le programmeur est peu
méfiant ou que la taille des types entiers change au delà de ses
attentes.


Ça, c'est l'argument massue pour ne PAS normaliser itoa(). gets()a réussi à
rester parce qu'il y avait à côté un moyen simple d'éviter les débordements.
En ce qui concerne le itoa() classique (issu de MS-DOS je pense), cet
équivalent simple n'existe pas, ou plutôt on en revient à sprintf() et un
calcul de la longueur de la chaîne en fonction des propriétés des types
entiers; et quand tu en es là, utiliser sprintf ou autre chose devient
anecdotique, sans parler de la lourdeur.

Avec C95, la complexité ajoutée à sprintf aurait pu justifié l'introduction
de itoa(), mais on a préféré snprintf(), et ÀMHA c'est plutôt une bonne idée
(même si cela aurait été mieux que toutes les fonctions qui remplissent une
chaîne aient des comportements homogènes).


Et je ne vois pas en quoi itoa() peut-être plus efficace vu que les
opérations utilisées seront les mêmes que snprintf() à part
l'allocation mémoire initiale de itoa().


parce que snprintf finira par appeler la fonction que je me propose
d'appeler directement.


Chez moi, cette fonction est snprintf elle-même (en fait, vfprintf avec un
FILE spécial).

Je sais bien que tu peux écrire une version plus simple pour faire ce que
fait le itoa() classique (et avec un source bien conçu, la même fonction va
aussi gérer ltoa, ultoa, xtoa, otoa, itow etc.) Mais je n'ai jamais eu
besoin personellement.


Il vaut mieux également essayer de ne pas avoir beaucoup de fonctions
qui ont une utilité identique ou bien qui recouvre l'usage de l'autre
sur un ensemble plus réduit.


C'est faux, d'abord le langage est truffé de méthodes différentes
pour faire chaque chose,


Exact.

ensuite ce ne sont pas des fonctions avec
une utilité identique, mais d'une fonction simple pour un usage et
d'une fonction riche qui utilisée d'une certaine facon permet
d'obtenir un résultat (presque) identique.

Dans un programme qui fait beaucoup de conversions int->str, ou qui a
besoin de les faire très vite, on regrettera de n'avoir que
snprintf() pour ce faire.


Déjà, sprintf() devrait aller plus vite: si tu dois contrôler ce qui se
passe en cas de débordement, tu es hors jeu pour le sprint, tu ne peux
concourrir que pour le fond.

Ensuite, cela dépend complètement de la qualité de ton implémentation: tu
risques d'avoir des implémentations de sprintf qui sont en fait snprintf( ,
SIZE_MAX, ... ), et d'un autre côté tu vas trouver des implémentations de
itoa() qui appelent sprintf() ;-) (de la même manière qu'aujourd'hui, c'est
en général vain d'essayer de gagner du temps en utilisant atoi())
Si tu es vraiment juste sur les perfs de cette partie, tu ne vas pas couper
de réécrire cela toi-même.

Enfin, par expérience les programmes qui génèrent des chaînes de caractères
ne le font pas pour faire joli, ils finissent par ranger ces chaînes quelque
part, dans un fichier ou dans un socket, donc ils finissent par être limités
par le débit des entrées-sorties (OK, cela fait un bail que je n'ai pas
programmé sur un processeur plus lent que son contrôleur d'E/S, même si je
sais que cela existe encore, surtout en C).


Pour finir, la vraie raison, c'est que itoa() n'existait pas sur les bécanes
Unix (plus précisement, sur V7).


Antoine



Avatar
Gabriel Dos Reis
"Antoine Leca" writes:

| >>> a pour conséquence qu'on est capable de convertir en entier des
| >>> chaines de caractères les représentant dans toutes les bases de
| >>> 2 à 36, mais que dans l'autre sens on est limité à 8, 10 et 16
|
| Sans blague, tu ne crois pas que l'histoire de « toutes les bases » c'est du
| sucre qui a été mis là parce que cela ne coutait rien, mais qui ne sert à
| personne dans la réalité ?

On voit que tu ne parses pas du PostScript ;-)

-- Gaby
Avatar
Antoine Leca
En , Gabriel Dos Reis va escriure:
"Antoine Leca" writes:

Sans blague, tu ne crois pas que l'histoire de « toutes les bases »
c'est du sucre qui a été mis là parce que cela ne coutait rien, mais
qui ne sert à personne dans la réalité ?


On voit que tu ne parses pas du PostScript ;-)


Au début, j'ai cru que tu avais écrit cela pour ma phrase sur les programmes
qui manipule des chaînes sans faire de sorties, et je m'apprêtait à répondre
que si, je parse des fois du Postscript (OK, du Type1/Type2, ce sont des
sous-ensembles), et je m'empresse de coder les chaînes par des jetons...

Mais là, je ne comprends pas: il y a des affreux qui écrivent du Postscript
(déjà, une drôle d'idée en soi) et qui utilisent des bases bizarres ?

Ou bien tu veux parler du «chiffrage» des type1 ?


Antoine


Avatar
Charlie Gordon
"Gabriel Dos Reis" wrote in message
news:
"Antoine Leca" writes:

| >>> a pour conséquence qu'on est capable de convertir en entier des
| >>> chaines de caractères les représentant dans toutes les bases de
| >>> 2 à 36, mais que dans l'autre sens on est limité à 8, 10 et 16
|
| Sans blague, tu ne crois pas que l'histoire de « toutes les bases » c'est du
| sucre qui a été mis là parce que cela ne coutait rien, mais qui ne sert à
| personne dans la réalité ?

On voit que tu ne parses pas du PostScript ;-)


A ce propos, je me souviens avoir optimisé en 1991 à Cambridge le driver
Postscript de Lotus 1-2-3. C'était l'horreur : l'impression Postscript était
extrêmement lente et leurs ingénieurs attribuaient cela à la lenteur de la
connexion imprimante, ou de l'imprimante PS Apple elle-même. Nous avons
bêtement profilé le code du tableur et du driver, ce qu'ils n'avaient pas osé
faire à cause de l'énormité de cette application, et le résultat fût consternant
: plus de 90% du temps passé était concentré dans une seule routine qui
convertissait en chaines de caractères en base 10 des nombres entiers pour la
plupart constants. Ne pouvant utiliser sprintf dans un driver d'impression, ils
avaient réécrit une routine de conversion décimale particulièrement lente, qui
faisait des divisions bit à bit en 32 bits. En implémentant efficacement cette
conversion et en évitant de la faire pour des nombres constants, l'ensemble de
la génération Postscript devint négligeable devant le temps de transfert et
d'impression, avec tout de même un gain d'un facteur 20.

Convertir les nombres en chaines est une opération courante, c'est dommage que
les outils pour le faire soient si tordus.

Chqrlie.

Avatar
Antoine Leca
En cmctic$7ft$, Charlie Gordon va escriure:
A ce propos, je me souviens avoir optimisé en 1991 à Cambridge le
driver Postscript de Lotus 1-2-3.


Jolie anecdote.

plus de 90% du temps passé était concentré dans une seule routine qui
convertissait en chaines de caractères en base 10 des nombres entiers


Tu ramènes de l'eau à mon moulin, là: par rapport à itoa qui est censé gérer
toutes les bases, sprintf est «prévenu» de la base à utiliser, donc peut
optimiser à part la base 10 (ou 16).
;-)

Après, c'est un problème de qualité d'implémentation: c'est évident que si
tu as un problème de perf' et que la routine de conversion numérique vers
texte intégrée dans xprintf() fait la division « à la main » (et si en plus
elle doit gérer les objets sur 64 ou 128 bits avec le même chemin... sans
commentaire)

pour la plupart constants.


Tu as des chiffres sur l'impact de traiter à part les constantes (courantes)
? Je suppose que ce doit être important, mais les faits sont meilleurs que
les suppositions...



Convertir les nombres en chaines est une opération courante, c'est
dommage que les outils pour le faire soient si tordus.


Sí señor. En fait, c'est vrai de tout ce qui crée des chaînes (cf.
discussions sur strncpy).


Antoine

1 2 3 4 5