web-dev-qa-db-fra.com

Comment convertir un int en string en C?

Comment convertir une int (entier) en chaîne? J'essaie de créer une fonction qui convertit les données d'une struct en une chaîne pour l'enregistrer dans un fichier.

145
user1063999

EDIT: Comme indiqué dans le commentaire, itoa() n'est pas une norme, il est donc préférable d'utiliser l'approche sprintf () proposée dans la réponse concurrente!


Vous pouvez utiliser la fonction itoa() 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 voulez exporter votre structure dans un fichier, il n’est pas nécessaire de convertir au préalable une valeur. Vous pouvez simplement utiliser la spécification de format printf pour indiquer comment sortir vos valeurs et utiliser l’un des opérateurs de printf family pour sortir vos données.

62
Alexander Galkin

Vous pouvez utiliser sprintf pour le faire, ou peut-être snprintf si vous l'avez:

char str[ENOUGH];
sprintf(str, "%d", 42);

Où le nombre de caractères (plus le caractère de fin) dans la str peut être calculé en utilisant:

(int)((ceil(log10(num))+1)*sizeof(char))
137
cnicutar

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 );

Allouez un caractère de plus pour null-terminator.

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", etc.

38
user2622016

Après avoir examiné différentes versions de itoa pour gcc, la version la plus flexible que j'ai trouvée, capable de gérer les conversions en binaire, décimal et hexadécimal, à la fois positives et négatives, est la quatrième version disponible sur http: //www.strudel .org.uk/itoa/ . Bien que sprintf/snprintf ait des avantages, ils ne gèrent pas les nombres négatifs pour autre chose que la conversion décimale. Comme le lien ci-dessus est hors ligne ou n'est plus actif, j'ai inclus leur 4ème version ci-dessous:

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;
}
26
David C. Rankin

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;
}
8
catfood

Si vous utilisez GCC, vous pouvez utiliser l'extension GNU en tant que fonction printf.

char* str;
asprintf (&str, "%i", 12313);
free(str);

Toute conversion en chaîne devrait: 1) allouer la chaîne résultante ou 2) transmettre une destination et une taille char *. Exemple de code ci-dessous:

Les deux fonctionnent pour tous les int y compris INT_MIN. Ils fournissent une sortie cohérente contrairement à snprintf() qui dépend des paramètres régionaux actuels.

Méthode 1: renvoie 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: Il 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;
}

[Edit] comme demande de @Alter Mann

(CHAR_BIT*sizeof(int_type)-1)*10/33+3 est au moins le nombre maximal de char nécessaire pour coder le type entier signé en tant que 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 nombre binaire n- bit 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 souhaite vivre sur Edge et que le dépassement de mémoire tampon ne pose pas de problème, une solution simple C99 ou ultérieure suit, qui gère allint.

#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));
}

Échantillon de sortie

0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
6
chux
/*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;
     }
3
kannadasan

Si vous voulez exporter votre structure dans un fichier, il n’est pas nécessaire de convertir au préalable une valeur. Vous pouvez simplement utiliser la spécification de format printf pour indiquer comment sortir vos valeurs et utiliser l’un des opérateurs de la famille printf pour sortir vos données.

2
user2374601

utilisez la fonction itoa () pour convertir un entier en chaîne

Par exemple:

char msg[30];
int num = 10;
itoa(num,msg,10);
0
Codemaker