595 Stimmen

Umwandlung von char in int in C und C++

Wie konvertiere ich eine char zu einer int in C und C++?

787voto

Foo Bah Punkte 24553

Das hängt davon ab, was Sie tun wollen:

um den Wert als Ascii-Code zu lesen, können Sie schreiben

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

zur Umwandlung des Zeichens '0' -> 0 , '1' -> 1 usw., können Sie schreiben

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

Erläuterung :
a - '0' ist gleichbedeutend mit ((int)a) - ((int)'0') was bedeutet, dass die Ascii-Werte der Zeichen voneinander subtrahiert werden. Da 0 kommt direkt vor 1 in der ascii-Tabelle (und so weiter bis 9 ), die Differenz zwischen den beiden ergibt die Zahl, die das Zeichen a vertritt.

197voto

Vlad Isoc Punkte 1950

Nun, im ASCII-Code beginnen die Zahlen (Ziffern) mit 48 . Alles, was Sie tun müssen, ist:

int x = (int)character - 48;

Oder, da das Zeichen '0' den ASCII-Code 48 hat, können Sie einfach schreiben:

int x = character - '0';  // The (int) cast is not necessary.

65voto

Matt Joiner Punkte 105454

In C und C++ werden Typen immer auf mindestens int . Außerdem sind Zeichenliterale vom Typ int in C und char in C++.

Sie können eine char Typ einfach durch Zuweisung an eine int .

char c = 'a'; // narrowing on C
int a = c;

45voto

Lundin Punkte 171916

Char ist nur eine 1-Byte-Ganzzahl. Der Typ char hat nichts Magisches an sich! Genauso wie Sie eine short einer int oder eine int einer long zuweisen können, können Sie eine char einer int zuweisen.

Ja, der Name des primitiven Datentyps ist zufällig "char", was darauf hindeutet, dass er nur Zeichen enthalten sollte. Aber in Wirklichkeit ist "char" nur eine schlechte Namenswahl, die jeden verwirrt, der versucht, die Sprache zu lernen. Ein besserer Name für diesen Datentyp ist int8_t, und Sie können diesen Namen stattdessen verwenden, wenn Ihr Compiler dem neuesten C-Standard folgt.

Obwohl Sie natürlich sollte Verwenden Sie den Typ char, wenn Sie Strings bearbeiten, da der Index der klassischen ASCII-Tabelle in 1 Byte passt. Sie könnte jedoch String-Handling mit regulären Ints als auch, obwohl es keinen praktischen Grund in der realen Welt, warum Sie jemals wollen, dass zu tun. Zum Beispiel funktioniert der folgende Code perfekt:

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

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

Sie müssen sich darüber im Klaren sein, dass Zeichen und Zeichenketten nur Zahlen sind, wie alles andere im Computer auch. Wenn Sie 'a' in den Quellcode schreiben, wird es in die Zahl 97 umgewandelt, die eine Integer-Konstante ist.

Wenn Sie also einen Ausdruck schreiben wie

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

dies ist eigentlich gleichbedeutend mit

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

die dann die Integer-Promotions der Sprache C durchläuft

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

und dann auf ein Zeichen gekürzt, um dem Ergebnistyp zu entsprechen

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

Es gibt eine Menge subtiler Dinge wie diese zwischen den Zeilen, wo char implizit als ein int behandelt wird.

21voto

Fred Nurk Punkte 13458

(Diese Antwort bezieht sich auf die C++-Seite der Dinge, aber das Problem der Vorzeichenerweiterung besteht auch in C.)

Umgang mit allen drei char Typen ( signed , unsigned y char ) ist heikler als es zunächst scheint. Werte im Bereich von 0 bis SCHAR_MAX (das ist 127 für eine 8-Bit char ) sind einfach:

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

Aber, wenn somevalue liegt außerhalb dieses Bereichs und geht nur über unsigned char gibt Ihnen konsistente Ergebnisse für die "gleichen" char Werte in allen drei Typen:

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.

Dies ist wichtig bei der Verwendung von Funktionen aus ctype.h comme isupper ou toupper wegen der Vorzeichenerweiterung:

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

Beachten Sie, dass die Umwandlung durch int implizit ist; dies hat die gleiche UB:

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

Um dies zu beheben, gehen Sie durch unsigned char was leicht durch Einpacken von ctype.h funktioniert durch 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.

Das funktioniert, weil jede Funktion, die einen der drei Char-Typen annimmt, auch die beiden anderen Char-Typen annehmen kann. Dies führt zu zwei Funktionen, die jeden der Typen verarbeiten können:

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) ergibt immer einen nicht-negativen Wert - auch wenn ein negativer Wert übergeben wird char oder negativ signed char - und chr nimmt einen beliebigen Wert an ord produziert und gibt genau dasselbe zurück char .

In der Praxis würde ich wahrscheinlich einfach durch unsigned char anstatt diese zu verwenden, aber sie verpacken den Cast kurz und bündig und bieten einen bequemen Platz, um eine Fehlerprüfung für int -zu- char und wäre kürzer und übersichtlicher, wenn man sie mehrmals in unmittelbarer Nähe verwenden muss.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X