Comment convertir un int
(entier) en chaîne? J'essaie de créer une fonction qui convertit les données d'un struct
en une chaîne pour l'enregistrer dans un fichier.
int
. Ouais je sais. C'est un raccourci très courant, mais ça me dérange toujours.
Comment convertir un int
(entier) en chaîne? J'essaie de créer une fonction qui convertit les données d'un struct
en une chaîne pour l'enregistrer dans un fichier.
int
. Ouais je sais. C'est un raccourci très courant, mais ça me dérange toujours.
Réponses:
EDIT: Comme indiqué dans le commentaire, ce itoa()
n'est pas une norme, il vaut donc mieux utiliser l'approche sprintf () suggérée dans la réponse concurrente!
Vous pouvez utiliser la itoa()
fonction pour convertir votre valeur entière en chaîne.
Voici un exemple:
int num = 321;
char snum[5];
// convert 123 to string [buf]
itoa(num, snum, 10);
// print our string
printf("%s\n", snum);
Si vous souhaitez sortir votre structure dans un fichier, il n'est pas nécessaire de convertir une valeur au préalable. Vous pouvez simplement utiliser la spécification du format printf pour indiquer comment sortir vos valeurs et utiliser l'un des opérateurs de la famille printf pour sortir vos données.
itoa
n'est pas standard - voir par exemple stackoverflow.com/questions/190229/…
itoa()
souffre du même potentiel de débordement de tampon que gets()
.
Vous pouvez utiliser sprintf
pour le faire, ou peut snprintf
- être si vous l'avez:
char str[ENOUGH];
sprintf(str, "%d", 42);
Où le nombre de caractères (plus le caractère de fin) dans le str
peut être calculé en utilisant:
(int)((ceil(log10(num))+1)*sizeof(char))
ENOUGH
suffit, nous pouvons le faire parmalloc(sizeof(char)*(int)log10(num))
(int)log10(42)
c'est le cas 1
.
#define ENOUGH ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
int length = snprintf(NULL, 0,"%d",42);
pour obtenir la longueur, puis allouez les length+1
caractères pour la chaîne.
La réponse courte est:
snprintf( str, size, "%d", x );
Le plus long est: vous devez d'abord trouver une taille suffisante. snprintf
vous indique la longueur si vous l'appelez avec NULL, 0
comme premiers paramètres:
snprintf( NULL, 0, "%d", x );
Attribuez un caractère de plus pour null-terminator.
#include <stdio.h>
#include <stdlib.h>
int x = -42;
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
Si fonctionne pour chaque chaîne de format, vous pouvez donc convertir float ou double en chaîne en utilisant "%g"
, vous pouvez convertir int en hex en utilisant "%x"
, et ainsi de suite.
Après avoir examiné différentes versions d'itoa pour gcc, la version la plus flexible que j'ai trouvée qui est capable de gérer les conversions en binaire, décimal et hexadécimal, à la fois positive et négative est la quatrième version trouvée sur http://www.strudel.org .uk / itoa / . Bien que sprintf
/ snprintf
aient des avantages, ils ne traiteront pas les nombres négatifs pour autre chose que la conversion décimale. Étant donné que le lien ci-dessus est hors ligne ou n'est plus actif, j'ai inclus leur 4ème version ci-dessous:
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
sprintf()
et "c'est beaucoup plus rapide que sprintf" peut être vrai sur votre compilateur mais pas toujours tenir. Un compilateur peut l'examiner sprintf(str, "%d", 42);
et l'optimiser pour une itoa()
fonction similaire optimisée - certainement plus rapide que cet utilisateur. code.
sprintf(str, "%d", 42);
en ajoutant deux caractères const, mais c'est de la théorie. Dans la pratique, les gens ne sprintent pas et l'itoa ci-dessus est presque aussi optimisé que possible. Au moins, vous pourriez être sûr à 100% que vous n'obtiendrez pas des ordres de grandeur de déclassement d'un sprintf générique. Ce serait bien de voir le contre-exemple que vous avez en tête, avec la version et les paramètres du compilateur.
C'est vieux mais voici une autre façon.
#include <stdio.h>
#define atoa(x) #x
int main(int argc, char *argv[])
{
char *string = atoa(1234567890);
printf("%s\n", string);
return 0;
}
Si vous utilisez GCC, vous pouvez utiliser la fonction d'extension GNU asprintf.
char* str;
asprintf (&str, "%i", 12313);
free(str);
La conversion de n'importe quoi en chaîne doit soit 1) allouer la chaîne résultante, soit 2) transmettre une char *
destination et une taille. Exemple de code ci-dessous:
Les deux fonctionnent pour tous, int
y compris INT_MIN
. Ils fournissent une sortie cohérente contrairement à snprintf()
ce qui dépend des paramètres régionaux actuels.
Méthode 1: retour NULL
sur mémoire insuffisante.
#define INT_DECIMAL_STRING_SIZE(int_type) ((CHAR_BIT*sizeof(int_type)-1)*10/33+3)
char *int_to_string_alloc(int x) {
int i = x;
char buf[INT_DECIMAL_STRING_SIZE(int)];
char *p = &buf[sizeof buf - 1];
*p = '\0';
if (i >= 0) {
i = -i;
}
do {
p--;
*p = (char) ('0' - i % 10);
i /= 10;
} while (i);
if (x < 0) {
p--;
*p = '-';
}
size_t len = (size_t) (&buf[sizeof buf] - p);
char *s = malloc(len);
if (s) {
memcpy(s, p, len);
}
return s;
}
Méthode 2: elle retourne NULL
si le tampon était trop petit.
static char *int_to_string_helper(char *dest, size_t n, int x) {
if (n == 0) {
return NULL;
}
if (x <= -10) {
dest = int_to_string_helper(dest, n - 1, x / 10);
if (dest == NULL) return NULL;
}
*dest = (char) ('0' - x % 10);
return dest + 1;
}
char *int_to_string(char *dest, size_t n, int x) {
char *p = dest;
if (n == 0) {
return NULL;
}
n--;
if (x < 0) {
if (n == 0) return NULL;
n--;
*p++ = '-';
} else {
x = -x;
}
p = int_to_string_helper(p, n, x);
if (p == NULL) return NULL;
*p = 0;
return dest;
}
[Modifier] tel que demandé par @Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3
est au moins le nombre maximum de char
nécessaire pour coder le type d'entier signé sous la forme d'une chaîne composée d'un signe négatif facultatif, de chiffres et d'un caractère nul.
Le nombre de bits non signés dans un entier signé n'est pas supérieur à CHAR_BIT*sizeof(int_type)-1
. Une représentation en base 10 d'un n
nombre binaire de bits prend jusqu'à n*log10(2) + 1
chiffres. 10/33
est un peu plus que log10(2)
. +1 pour le signe char
et +1 pour le caractère nul. D'autres fractions pourraient être utilisées comme 28/93.
Méthode 3: Si l'on veut vivre sur le bord et que le débordement de tampon n'est pas un problème, une simple solution C99 ou ultérieure suit qui gère tout int
.
#include <limits.h>
#include <stdio.h>
static char *itoa_simple_helper(char *dest, int i) {
if (i <= -10) {
dest = itoa_simple_helper(dest, i/10);
}
*dest++ = '0' - i%10;
return dest;
}
char *itoa_simple(char *dest, int i) {
char *s = dest;
if (i < 0) {
*s++ = '-';
} else {
i = -i;
}
*itoa_simple_helper(s, i) = '\0';
return dest;
}
int main() {
char s[100];
puts(itoa_simple(s, 0));
puts(itoa_simple(s, 1));
puts(itoa_simple(s, -1));
puts(itoa_simple(s, 12345));
puts(itoa_simple(s, INT_MAX-1));
puts(itoa_simple(s, INT_MAX));
puts(itoa_simple(s, INT_MIN+1));
puts(itoa_simple(s, INT_MIN));
}
Exemple de sortie
0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
/*Function return size of string and convert signed *
*integer to ascii value and store them in array of *
*character with NULL at the end of the array */
int itoa(int value,char *ptr)
{
int count=0,temp;
if(ptr==NULL)
return 0;
if(value==0)
{
*ptr='0';
return 1;
}
if(value<0)
{
value*=(-1);
*ptr++='-';
count++;
}
for(temp=value;temp>0;temp/=10,ptr++);
*ptr='\0';
for(temp=value;temp>0;temp/=10)
{
*--ptr=temp%10+'0';
count++;
}
return count;
}
Si vous souhaitez sortir votre structure dans un fichier, il n'est pas nécessaire de convertir une valeur au préalable. Vous pouvez simplement utiliser la spécification du format printf pour indiquer comment sortir vos valeurs et utiliser l'un des opérateurs de la famille printf pour sortir vos données.
Utilisez la fonction itoa()
pour convertir un entier en chaîne
Par exemple:
char msg[30];
int num = 10;
itoa(num,msg,10);
printf
ou l'un de ses cousins devrait faire l'affaire