Konvertieren Sie eine Ziffer in die entsprechende Ganzzahl in C.

103

Gibt es eine Möglichkeit, ein Zeichen in C in eine Ganzzahl umzuwandeln?

Zum Beispiel von '5'bis 5?

Fließen
quelle

Antworten:

147

Wie in anderen Antworten angegeben, ist dies in Ordnung:

char c = '5';
int x = c - '0';

Zur Fehlerprüfung möchten Sie möglicherweise zuerst überprüfen, ob isdigit (c) wahr ist. Beachten Sie, dass Sie dies für Briefe nicht vollständig portabel tun können, zum Beispiel:

char c = 'b';
int x = c - 'a'; // x is now not necessarily 1

Der Standard garantiert, dass die Zeichenwerte für die Ziffern '0' bis '9' zusammenhängend sind, übernimmt jedoch keine Garantie für andere Zeichen wie Buchstaben des Alphabets.

Chris Young
quelle
3
@Paul Tomblin: Ja für Ziffern, keine Buchstaben, da, wie ich in der Antwort sagte, die Standardgarantien '0' bis '9' zusammenhängend sind, aber keine solchen Garantien für andere Zeichen wie 'a' bis 'z' geben.
Chris Young
char c = 'b'; int x = c - 'a'; dann wird x nur in ASCII 1 sein?
Pan
@Pan In jeder Codierung, einschließlich ASCII, hat 'b' 1 mehr als 'a'. Dies gilt immer noch in EBCDIC, macht jedoch ('j' - 'i') == 8.
Chris Young
@ChrisYoung Warum? Ursache in EBCDIC ist 'j' nicht 1 mehr als 'i'?
Pan
2
Was fehlt mir hier, wo atoi nicht verwendet wird?
Daniel
41

Subtrahiere '0' wie folgt:

int i = c - '0';

Der C-Standard garantiert, dass jede Ziffer im Bereich '0'..'9'um eine Ziffer größer ist als die vorherige Ziffer (im Abschnitt 5.2.1/3des C99-Entwurfs ). Gleiches gilt für C ++.

Johannes Schaub - litb
quelle
1
Diese Antwort wäre besser, wenn Sie erwähnen würden, dass ein Zeichen / bereits / effektiv eine Ganzzahl ist, ein von der Implementierung definiertes Vorzeichen (dh möglicherweise signiert oder nicht signiert) und CHAR_BITS lang ist.
Arafangion
Ich war mir nicht sicher, ob ihm das wirklich hilft. aber Chris machte einen guten Punkt mit a..z nicht unbedingt zusammenhängend. Ich hätte das stattdessen erwähnen sollen. jetzt hat er das Rennen gewonnen :)
Johannes Schaub - litb
1
Ihre ist besser, weil Sie Ihre Antwort qualifiziert haben - Chris hätte sich sehr gut seine Sachen ausdenken können. :)
Arafangion
Danke für die Wertschätzung. Ich gebe zu, ich war mir über den Zustand von C. nicht sicher, also schaute ich auf und weil ich schon dabei war,
fügte
Und deshalb, Sir, haben Sie ein paar Punkte mehr als ich. :)
Arafangion
29

Wenn Sie durch einen verrückten Zufall eine Zeichenfolge in eine Ganzzahl konvertieren möchten , können Sie dies auch tun!

char *num = "1024";
int val = atoi(num); // atoi = ASCII TO Int

valist jetzt 1024. Anscheinend atoi()ist es in Ordnung, und was ich zuvor darüber gesagt habe, gilt nur für mich (unter OS X (vielleicht (Lisp-Witz hier einfügen))). Ich habe gehört, dass es sich um ein Makro handelt, das ungefähr dem nächsten Beispiel zugeordnet ist und strtol()stattdessen eine allgemeinere Funktion verwendet, um die Konvertierung durchzuführen:

char *num = "1024";
int val = (int)strtol(num, (char **)NULL, 10); // strtol = STRing TO Long

strtol() funktioniert so:

long strtol(const char *str, char **endptr, int base);

Es wird *strin a konvertiert longund so behandelt, als wäre es eine Basiszahl base. Wenn **endptres nicht null ist, enthält es das erste gefundene nichtstellige Zeichen strtol()(aber wen interessiert das?).

Chris Lutz
quelle
Es gibt keine Thread-Probleme mit atoi (es hat keine statischen Daten) und es ist nicht veraltet. Tatsächlich ist es funktional äquivalent zu: #define atoi (x) (int) (strtol ((x), NULL, 10)
Evan Teran
5
Das Problem mit atoi ist, dass 0 als Wert "Hier kann keine Zahl gefunden werden" verwendet wird, sodass atoi ("0") und atoi ("eins") beide 0 zurückgeben. Wenn das für das, was Sie tun, nicht funktioniert ' Wenn Sie es für verwenden, suchen Sie nach strtol () oder sscanf ().
David Thornley
Der andere Vorteil von strtol ist natürlich, dass Sie möglicherweise andere Dinge aus derselben Zeichenfolge lesen müssen, die nach der Nummer stehen.
dfeuer
@EvanTeran Wenn Sie Visual Studio ausführen, wird leider eine Abschreibungswarnung angezeigt (und die Kompilierung wird nicht ohne Deaktivierung durchgeführt). VS empfiehlt jetzt itoa_s().
Simon
7

Subtrahieren Sie char '0' oder int 48 wie folgt:

char c = '5';
int i = c - '0';

Erläuterung: Intern funktioniert es mit dem ASCII- Wert. In der ASCII-Tabelle ist der Dezimalwert von Zeichen 5 53 und 0 48 . Also 53 - 48 = 5

ODER

char c = '5';
int i = c - 48; // Because decimal value of char '0' is 48

Das heißt, wenn Sie 48 von einem Ziffernzeichen abziehen , wird die Ganzzahl automatisch konvertiert.

Arif
quelle
6
char numeralChar = '4';
int numeral = (int) (numeralChar - '0');
Kevin Conner
quelle
numeralChar - '0'ist bereits vom Typ int, sodass Sie die Besetzung nicht benötigen. Auch wenn dies nicht der Fall ist, wird die Besetzung nicht benötigt.
Alok Singhal
Huh, ja das würde zwingen, nicht wahr? Vielleicht hat Java meine Wahrnehmungen gefärbt. Oder vielleicht irre ich mich völlig und es würde sogar in Java zwingen. :)
Kevin Conner
5

Um die Ziffer in eine entsprechende Ganzzahl umzuwandeln. Gehen Sie wie folgt vor:

char c = '8';                    
int i = c - '0';

Die Logik hinter der obigen Berechnung besteht darin, mit ASCII-Werten zu spielen. Der ASCII-Wert von Zeichen 8 ist 56, der ASCII-Wert von Zeichen 0 ist 48. Der ASCII-Wert von Ganzzahl 8 ist 8.

Wenn wir zwei Zeichen subtrahieren, erfolgt eine Subtraktion zwischen ASCII-Zeichen.

int i = 56 - 48;   
i = 8;
Ashish
quelle
Warum bin ich der einzige, der dies befürwortet? Die Erklärung ist so einfach und informativ: +1:
Brandon Benefield
0

Wenn es sich bei ASCII nur um ein einzelnes Zeichen 0-9 handelt, sollte das Subtrahieren des Werts des ASCII-Nullzeichens vom ASCII-Wert einwandfrei funktionieren.

Wenn Sie größere Zahlen konvertieren möchten, reicht Folgendes aus:

char *string = "24";

int value;

int assigned = sscanf(string, "%d", &value);

** Vergessen Sie nicht, den Status zu überprüfen (der 1 sein sollte, wenn es im obigen Fall funktioniert hat).

Paul.

Paul W. Homer
quelle
0
char chVal = '5';
char chIndex;

if ((chVal >= '0') && (chVal <= '9')) {

    chIndex = chVal - '0';
}
else 
if ((chVal >= 'a') && (chVal <= 'z')) {

    chIndex = chVal - 'a';
}
else 
if ((chVal >= 'A') && (chVal <= 'Z')) {

    chIndex = chVal - 'A';
}
else {
    chIndex = -1; // Error value !!!
}
Alphaneo
quelle
0

Wenn ich so etwas tun muss, backe ich ein Array mit den gewünschten Werten vor.

const static int lookup[256] = { -1, ..., 0,1,2,3,4,5,6,7,8,9, .... };

Dann ist die Konvertierung einfach

int digit_to_int( unsigned char c ) { return lookup[ static_cast<int>(c) ]; }

Dies ist im Grunde der Ansatz, den viele Implementierungen der ctype-Bibliothek verfolgen. Sie können dies trivial anpassen, um auch mit Hex-Ziffern zu arbeiten.

Michael Anderson
quelle
Dies scheint für die Konvertierung einer einzelnen Dezimal- (oder Oktal-) Ziffer äußerst ineffizient zu sein. Wenn sich der relevante Teil Ihrer Nachschlagetabelle nicht zufällig im L1-Cache befindet, werden Sie eine Reihe von Zyklen ausführen, um ihn abzurufen und nur einen Wert zu erhalten. Ehrlich gesagt bezweifle ich, dass dies sogar eine gute Idee ist, wenn Sie eine ganze Reihe von Ziffern konvertieren, aber das müssten Sie messen. Für Hex ist es natürlich viel wettbewerbsfähiger.
Feuer
0

Überprüfen Sie dies,

char s='A';

int i = (s<='9')?(s-'0'):(s<='F')?((s-'A')+10):((s-'a')+10);

für nur 0,1,2, ...., E, F.

Shiva
quelle
0

Verwenden Sie einfach die atol()Funktion:

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

int main() 
{
    const char *c = "5";
    int d = atol(c);
    printf("%d\n", d);

}
Dylan Hallen
quelle
0

Wenn Ihre Ziffer beispielsweise '5'in ASCII ist, wird sie als Binärzahl 0011 0101(53) dargestellt. Jede Ziffer hat die höchsten vier Bits 0011und die niedrigsten 4 Bits repräsentieren die Ziffer in bcd. Also machst du es einfach

char cdig = '5';
int dig = cdig & 0xf; // dig contains the number 5

um die niedrigsten 4 Bits oder, was auch immer, die Ziffer zu erhalten. In asm wird andanstelle von sub(wie in den anderen Antworten) die Operation verwendet .

Garmekain
quelle
'5'ist 53 ( 00110101)
eyllanesc
@eyllanesc Zuerst war es eine 4. Danke. Bearbeitet es.
Garmekain
0

Hier sind Hilfsfunktionen, mit denen Sie Ziffern in char in int und umgekehrt konvertieren können:

int toInt(char c) {
    return c - '0';
}

char toChar(int i) {
    return i + '0';
}
Maxim Makhun
quelle
-2

Verwenden Sie die Funktion: atoi für Array zu Integer, atof für Array zu Float-Typ; oder

char c = '5';
int b = c - 48;
printf("%d", b);
K.tin
quelle
Mehrere Antworten deckten dies bereits ab. Dies fügt nichts hinzu, was sie noch nicht behandelt haben.
ShadowRanger
-3

Sie würden es in ein int umwandeln (oder float oder double oder was auch immer Sie sonst damit machen wollen) und es in einer anderen Variablen speichern.

SeanJA
quelle