web-dev-qa-db-fra.com

Convertit char en int en C et C ++

Comment convertir une char en int en C et C++?

322
mainajaved

Tout dépends de ce que tu veux faire:

pour lire la valeur sous forme de code ASCII, vous pouvez écrire

char a = 'a';
int ia = (int)a; 
/* note that the int cast is not necessary -- int ia = a would suffice */

convertir le caractère '0' -> 0, '1' -> 1, etc., vous pouvez écrire

char a = '4';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */

Explication:
a - '0' est équivalent à ((int)a) - ((int)'0'), ce qui signifie que les valeurs ascii des caractères sont soustraites les unes des autres. Puisque 0 vient juste avant 1 dans la table ascii (et ainsi de suite jusqu'à 9), la différence entre les deux donne le nombre que le caractère a représente.

450
Foo Bah

Eh bien, dans le code ASCII, les chiffres commencent à partir de 48. Tout ce que vous devez faire c'est:

int x = (int)character - 48;
76
Vlad Isoc

C et C++ promeuvent toujours les types au moins à int. De plus, les littéraux de caractères sont de type int en C et char en C++.

Vous pouvez convertir un type char en affectant simplement à un int.

char c = 'a'; // narrowing on C
int a = c;
58
Matt Joiner

char est juste un entier de 1 octet. Il n'y a rien de magique avec le type d'omble! Tout comme vous pouvez affecter un short à un int ou un int à un long, vous pouvez affecter un caractère à un int.

Oui, le nom du type de données primitif se trouve être "char", ce qui signifie qu'il ne devrait contenir que des caractères. Mais en réalité, "char" n'est qu'un mauvais nom pour confondre tous ceux qui essaient d'apprendre la langue. Int8_t est un meilleur nom, et vous pouvez utiliser ce nom à la place, si votre compilateur respecte la dernière norme C.

Bien sûr, vous devriez utiliser le type de caractère lorsque vous manipulez des chaînes, car l'index de la table classique ASCII tient dans un octet. . Cependant, vous pourriez gérer les chaînes avec des ints classiques, bien qu'il n'y ait aucune raison pratique dans le monde réel pour laquelle vous voudriez le faire. Par exemple, le code suivant fonctionnera parfaitement:

  int str[] = {'h', 'e', 'l', 'l', 'o', '\0' };

  for(i=0; i<6; i++)
  {
    printf("%c", str[i]);
  }

Vous devez comprendre que les caractères et les chaînes ne sont que des chiffres, comme tout le reste de l'ordinateur. Lorsque vous écrivez "a" dans le code source, celui-ci est pré-traité dans le nombre 97, qui est une constante entière.

Donc, si vous écrivez une expression comme

char ch = '5';
ch = ch - '0';

c'est en fait équivalent à

char ch = (int)53;
ch = ch - (int)48;

qui passe ensuite par les promotions entières du langage C

ch = (int)ch - (int)48;

puis tronqué en caractère pour correspondre au type de résultat

ch = (char)( (int)ch - (int)48 );

Il y a beaucoup de choses subtiles comme celle-ci qui se passe entre les lignes, où char est implicitement traité comme un int.

29
Lundin

(Cette réponse concerne le côté C++ des choses, mais le problème de l'extension du signe existe aussi en C.)

Le traitement des trois types char (signed, unsigned et char) est plus délicat qu’il n’apparaît au début. Les valeurs comprises entre 0 et SCHAR_MAX (qui est 127 pour un char 8 bits) sont simples:

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
int n = c;

Toutefois, lorsque somevalue se situe en dehors de cette plage, seul le passage à unsigned char vous donne des résultats cohérents pour les "mêmes" valeurs char dans les trois types:

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
// Might not be true: int(c) == int(sc) and int(c) == int(uc).
int nc = (unsigned char)c;
int nsc = (unsigned char)sc;
int nuc = (unsigned char)uc;
// Always true: nc == nsc and nc == nuc.

Ceci est important lorsque vous utilisez des fonctions de ctype.h , telles que isupper ou toupper, en raison de l'extension de signe:

char c = negative_char;  // Assuming CHAR_MIN < 0.
int n = c;
bool b = isupper(n);  // Undefined behavior.

Notez que la conversion via int est implicite; cela a le même UB:

char c = negative_char;
bool b = isupper(c);

Pour résoudre ce problème, parcourez unsigned char, ce qui est facilement réalisable en encapsulant ctype.h des fonctions via safe_ctype :

template<int (&F)(int)>
int safe_ctype(unsigned char c) { return F(c); }

//...
char c = CHAR_MIN;
bool b = safe_ctype<isupper>(c);  // No UB.

std::string s = "value that may contain negative chars; e.g. user input";
std::transform(s.begin(), s.end(), s.begin(), &safe_ctype<toupper>);
// Must wrap toupper to eliminate UB in this case, you can't cast
// to unsigned char because the function is called inside transform.

Cela fonctionne car toute fonction prenant l'un des trois types de caractères peut également prendre les deux autres types de caractères. Cela conduit à deux fonctions qui peuvent gérer n'importe quel type:

int ord(char c) { return (unsigned char)c; }
char chr(int n) {
  assert(0 <= n);  // Or other error-/sanity-checking.
  assert(n <= UCHAR_MAX);
  return (unsigned char)n;
}

// Ord and chr are named to match similar functions in other languages
// and libraries.

ord(c) vous donne toujours une valeur non négative - même si un char négatif ou négatif signed char - et chr prend une valeur que ord produit et restitue le même char.

Dans la pratique, j’aurais probablement simplement jeté unsigned char au lieu de les utiliser, mais ils encapsulent de manière succincte la distribution, constituent un endroit pratique pour ajouter une vérification d’erreur pour int à -char et serait plus court et plus clair lorsque vous devez les utiliser plusieurs fois à proximité.

16
Fred Nurk

Utilisez static_cast<int>:

int num = static_cast<int>(letter); // if letter='a', num=97

Edit: Vous devriez probablement essayer d'éviter d'utiliser (int)

int num = (int) lettre;

check out Pourquoi utiliser static_cast <int> (x) au lieu de (int) x? pour plus d’informations.

11
herohuyongtao

Cela dépend en quelque sorte de ce que vous entendez par "convertir".

Si vous avez une série de caractères représentant un entier, tel que "123456", il existe deux façons de procéder de la sorte en C: Utilisez une conversion spéciale telle que atoi () ou strtol () , ou l'utilisation générale sscanf () . C++ (qui est vraiment un langage différent se faisant passer pour une mise à niveau) ajoute un troisième, stringstreams.

Si vous voulez dire que vous voulez que le modèle de bits exact dans l'une de vos variables int soit traité comme un char, c'est plus facile. En C, les différents types d’entiers sont davantage un état d’esprit que des "types" distincts. Commencez simplement à l’utiliser là où chars sont demandés, et tout devrait bien se passer. Vous aurez peut-être besoin d'une conversion explicite pour que le compilateur arrête de pleurnicher à l'occasion, mais tout ce qui devrait être fait est de supprimer les bits supplémentaires après 256.

6
T.E.D.

J'ai absolument null compétences en C, mais pour une analyse syntaxique simple:

char* something = "123456";

int number = parseInt(something);

... cela a fonctionné pour moi:

int parseInt(char* chars)
{
    int sum = 0;
    int len = strlen(chars);
    for (int x = 0; x < len; x++)
    {
        int n = chars[len - (x + 1)] - '0';
        sum = sum + powInt(n, x);
    }
    return sum;
}

int powInt(int x, int y)
{
    for (int i = 0; i < y; i++)
    {
        x *= 10;
    }
    return x;
}
5
Henke

Vous voulez probablement que cette conversion soit utilisée pour utiliser des fonctions de la bibliothèque standard C.

Dans ce cas, faites (syntaxe C++)

typedef unsigned char UChar;

char myCppFunc( char c )
{
    return char( someCFunc( UChar( c ) ) );
}

L'expression UChar( c ) est convertie en unsigned char afin d'éliminer les valeurs négatives qui, à l'exception de EOF, ne sont pas prises en charge par les fonctions C.

Ensuite, le résultat de cette expression est utilisé comme argument réel pour un argument formel int. Où vous obtenez la promotion automatique à int. Vous pouvez aussi écrire explicitement cette dernière étape, comme int( UChar( c ) ), mais personnellement, je trouve cela trop verbeux.

Vive & hth.,

3
Cheers and hth. - Alf

Pour char ou short to int, il vous suffit d'attribuer la valeur.

char ch = 16;
int in = ch;

Identique à int64.

long long lo = ch;

Toutes les valeurs seront 16.

0
Riwels

J'avais des problèmes pour convertir un tableau de caractères comme "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e" en un entier qui pourrait être représenté par "7C" comme une valeur hexadécimale. Donc, après avoir trouvé de l’aide, j’ai créé cela, et j’ai pensé que ce serait cool de le partager.

Cela sépare la chaîne de caractères en ses entiers corrects, et peut être utile à plus de personnes que moi;)

unsigned int* char2int(char *a, int len)
{
    int i,u;
    unsigned int *val = malloc(len*sizeof(unsigned long));

    for(i=0,u=0;i<len;i++){
        if(i%2==0){
            if(a[i] <= 57)
                val[u] = (a[i]-50)<<4;
            else
                val[u] = (a[i]-55)<<4;
        }
        else{
            if(a[i] <= 57)
                val[u] += (a[i]-50);
            else
                val[u] += (a[i]-55);
            u++;
        }
    }
    return val;
}

J'espère que ça aide!

0
Mathorlaz