web-dev-qa-db-fra.com

Conversion de caractère en caractère en C

En ce moment, j'essaye de convertir un int en programmation en C. Après des recherches, j'ai trouvé que je devrais pouvoir le faire comme ceci:

int value = 10;
char result = (char) value;

Ce que j'aimerais, c'est que cela retourne 'A' (et que 0-9 renvoie '0' - '9'), mais cela retourne un nouveau caractère de ligne, je pense . Toute ma fonction ressemble à ceci:

char int2char (int radix, int value) {
  if (value < 0 || value >= radix) {
    return '?';
  }

  char result = (char) value;

  return result;
}
4
Kyle Hobbs

pour convertir int en caractère, vous n'avez rien à faire

char x;
int y;


/* do something */

x = y;

comme un chiffre imprimable (généralement ASCII), comme dans votre exemple:

const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int inttochar(int val, int base)
{
    return digits[val % base];
}

si vous souhaitez convertir la chaîne (char *), vous devez utiliser l'une des fonctions stansdard telles que sprintf, itoa, ltoa, utoa, ultoa .... ou en écrire une vous-même:

char *reverse(char *str);
const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

char *convert(int number, char *buff, int base)
{
    char *result = (buff == NULL || base > strlen(digits) || base < 2) ? NULL : buff;
    char sign = 0;


    if (number < 0)
    {
         sign = '-';

    }
    if (result != NULL)
    {
        do
        {
            *buff++ = digits[abs(number % (base ))];
            number /= base;
        } while (number);
        if(sign) *buff++ = sign;
        if (!*result) *buff++ = '0';
        *buff = 0;
        reverse(result);
    }
    return result;
}
6
P__J__

Une façon de faire portable serait de définir un

const char* foo = "0123456789ABC...";

... représente le reste des caractères à prendre en compte.

Alors et foo[value] sera évalué à une char particulière. Par exemple, foo[0] sera '0' et foo[10] sera 'A'.

Si vous supposez un encoding particulier (tel que l'ASCII commun mais nullement omniprésent), votre code n'est pas strictement portable.

4
Bathsheba

Conversion de Int en Char 

Je suppose que l’OP veut plus qu’une conversion à un chiffre car radix a été fourni.


Pour convertir une int en un string, (pas seulement 1 char), il existe l'approche sprintf(buf, "%d", value).

Pour ce faire, quelle que soit la base, la gestion des chaînes de caractères devient un problème tout en tenant compte du cas de coin de INT_MIN


La solution C99 suivante renvoie un char* dont la durée de vie est valide à la fin du bloc. Pour ce faire, il fournit un littéral composé via la macro.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

// Maximum buffer size needed
#define ITOA_BASE_N (sizeof(unsigned)*CHAR_BIT + 2)

char *itoa_base(char *s, int x, int base) {
  s += ITOA_BASE_N - 1;
  *s = '\0';
  if (base >= 2 && base <= 36) {
    int x0 = x;
    do {
      *(--s) = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[abs(x % base)];
      x /= base;
    } while (x);
    if (x0 < 0) {
      *(--s) = '-';
    }
  }
  return s;
}

#define TO_BASE(x,b) itoa_base((char [ITOA_BASE_N]){0} , (x), (b))

Utilisation de l'échantillon et tests

void test(int x) {
  printf("base10:% 11d base2:%35s  base36:%7s ", x, TO_BASE(x, 2), TO_BASE(x, 36));
  printf("%ld\n", strtol(TO_BASE(x, 36), NULL, 36));
}

int main(void) {
  test(0);
  test(-1);
  test(42);
  test(INT_MAX);
  test(-INT_MAX);
  test(INT_MIN);
}

Sortie

base10:          0 base2:                                  0  base36:      0 0
base10:         -1 base2:                                 -1  base36:     -1 -1
base10:         42 base2:                             101010  base36:     16 42
base10: 2147483647 base2:    1111111111111111111111111111111  base36: ZIK0ZJ 2147483647
base10:-2147483647 base2:   -1111111111111111111111111111111  base36:-ZIK0ZJ -2147483647
base10:-2147483648 base2:  -10000000000000000000000000000000  base36:-ZIK0ZK -2147483648

Ref Comment utiliser les littéraux composés pour fprintf() plusieurs nombres formatés avec des bases arbitraires?

1
chux

Les caractères utilisent un codage (généralement ASCII) pour mapper des nombres à un caractère particulier. Les codes pour les caractères '0' à '9' sont consécutifs. Par conséquent, pour les valeurs inférieures à 10, ajoutez la valeur à la constante de caractère '0'. Pour les valeurs 10 ou plus, vous ajoutez la valeur moins 10 à la constante de caractère 'A':

char result;
if (value >= 10) {
    result = 'A' + value - 10;
} else {
    result = '0' + value;
}
1
dbush

Les caractères en C sont donc basés sur ASCII (ou UTF-8, qui est rétrocompatible avec les codes ascii). Cela signifie que sous le capot, "A" est en fait le nombre "65" (sauf en binaire plutôt qu'en décimal). Tout ce qu'un "caractère" est en C est un entier avec assez d'octets pour représenter chaque caractère ASCII. Si vous voulez convertir une int en une char, vous devez demander à l'ordinateur d'interpréter les octets d'un int comme des valeurs ASCII - et cela fait longtemps que je n'ai pas fait C, mais je crois que le le compilateur se plaindra puisque char contient moins d'octets que int. Cela signifie que nous avons besoin d'une fonction, comme vous l'avez écrit. Ainsi, 

if(value < 10) return '0'+value;
return 'A'+value-10;

sera ce que vous voulez revenir de votre fonction. Gardez vos limites avec "radix" comme vous l'avez fait, à mon avis, c'est une bonne pratique en C. 

0
Jonathan Howard

Consultez la table ascii

Les valeurs stockées dans un caractère sont interprétées comme les caractères correspondant à cette table. La valeur de 10 est une nouvelle ligne

0
savram