Ich habe ein char [], das einen Wert wie "0x1800785" enthält, aber für die Funktion, der ich den Wert geben möchte, ist ein int erforderlich. Wie kann ich dies in ein int konvertieren? Ich habe mich umgesehen, kann aber keine Antwort finden. Vielen Dank.
81
Antworten:
Hast du es versucht
strtol()
?strtol - Konvertiert einen String in eine lange Ganzzahl
Beispiel:
const char *hexstring = "abcdef0"; int number = (int)strtol(hexstring, NULL, 16);
Wenn die Zeichenfolgendarstellung der Zahl mit einem
0x
Präfix beginnt ,muss0 als Basis verwendet werden:const char *hexstring = "0xabcdef0"; int number = (int)strtol(hexstring, NULL, 0);
(Es ist auch möglich, eine explizite Basis wie 16 anzugeben, aber ich würde die Einführung von Redundanz nicht empfehlen.)
quelle
"0x"
wie in der Frage angegeben eingeführt wird, sollten Sie einfach0
anstelle von verwenden16
.strtol
gibt Ihnen Typ,long
der großartig ist, wenn Sie mit einem sehr großen Hex arbeiten. Verwenden Siestrtoll
für Typlong long
für noch größere Felder.Oder wenn Sie eine eigene Implementierung haben möchten, habe ich diese Schnellfunktion als Beispiel geschrieben:
/** * hex2int * take a hex string and convert it to a 32bit number (max 8 hex digits) */ uint32_t hex2int(char *hex) { uint32_t val = 0; while (*hex) { // get current character then increment uint8_t byte = *hex++; // transform hex character to the 4bit equivalent number, using the ascii table indexes if (byte >= '0' && byte <= '9') byte = byte - '0'; else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10; else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10; // shift 4 to make space for new digit, and add the 4 bits of the new digit val = (val << 4) | (byte & 0xF); } return val; }
quelle
So etwas könnte nützlich sein:
char str[] = "0x1800785"; int num; sscanf(str, "%x", &num); printf("0x%x %i\n", num, num);
Lesen Sie man sscanf
quelle
%x
muss die Adresse eines erhaltenunsigned int
. Und selbst wenn Sie das beheben, wenn die durch die Zeichenfolge dargestellte Zahl größer alsUINT_MAX
ist, ist es wieder undefiniertes VerhaltenAngenommen, Sie meinen, es ist eine Zeichenfolge, wie wäre es mit strtol ?
quelle
int
. +1, übrigens.int54_t
und umgehenuint53_t
.Verwenden
strtol
Sie diese Option, wenn libc verfügbar ist, wie in der oberen Antwort angegeben. Wenn Sie jedoch benutzerdefinierte Inhalte mögen oder sich auf einem Mikrocontroller ohne libc oder so befinden, möchten Sie möglicherweise eine leicht optimierte Version ohne komplexe Verzweigung.#include <inttypes.h> /** * xtou64 * Take a hex string and convert it to a 64bit number (max 16 hex digits). * The string must only contain digits and valid hex characters. */ uint64_t xtou64(const char *str) { uint64_t res = 0; char c; while ((c = *str++)) { char v = (c & 0xF) + (c >> 6) | ((c >> 3) & 0x8); res = (res << 4) | (uint64_t) v; } return res; }
Die Magie der Bitverschiebung läuft darauf hinaus: Verwenden Sie einfach die letzten 4 Bits, aber wenn es sich um eine Nicht-Ziffer handelt, addieren Sie auch 9.
quelle
unsigned long long int hextou64(char *str) { unsigned long long int n = 0; char c, v; for (unsigned char i = 0; i < 16; i++) { c = *(str + i); v = (c & 0xF) + (c >> 6) | ((c >> 3) & 0x8); n = (n << 4) | (unsigned long long int)v; } return n; }
(c >> 6) | ((c >> 3) & 0x8)
→ ergibt 9 im Fall eines Buchstabens oder 0 im Fall einer Dezimalzahl. Ja, ziemlich hackig :)Versuchen Sie es unter dem Codeblock, der für mich funktioniert.
char *p = "0x820"; uint16_t intVal; sscanf(p, "%x", &intVal); printf("value x: %x - %d", intVal, intVal);
Ausgabe ist:
value x: 820 - 2080
quelle
Nachdem ich eine Weile gesucht und herausgefunden habe, dass strtol ziemlich langsam ist, habe ich meine eigene Funktion codiert. Es funktioniert nur für Großbuchstaben bei Buchstaben, aber das Hinzufügen von Kleinbuchstaben ist kein Problem.
int hexToInt(PCHAR _hex, int offset = 0, int size = 6) { int _result = 0; DWORD _resultPtr = reinterpret_cast<DWORD>(&_result); for(int i=0;i<size;i+=2) { int _multiplierFirstValue = 0, _addonSecondValue = 0; char _firstChar = _hex[offset + i]; if(_firstChar >= 0x30 && _firstChar <= 0x39) _multiplierFirstValue = _firstChar - 0x30; else if(_firstChar >= 0x41 && _firstChar <= 0x46) _multiplierFirstValue = 10 + (_firstChar - 0x41); char _secndChar = _hex[offset + i + 1]; if(_secndChar >= 0x30 && _secndChar <= 0x39) _addonSecondValue = _secndChar - 0x30; else if(_secndChar >= 0x41 && _secndChar <= 0x46) _addonSecondValue = 10 + (_secndChar - 0x41); *(BYTE *)(_resultPtr + (size / 2) - (i / 2) - 1) = (BYTE)(_multiplierFirstValue * 16 + _addonSecondValue); } return _result; }
Verwendung:
char *someHex = "#CCFF00FF"; int hexDevalue = hexToInt(someHex, 1, 8);
1, weil das Hex, das wir konvertieren möchten, bei Offset 1 beginnt, und 8, weil es die Hex-Länge ist.
Speedtest (1.000.000 Anrufe):
strtol ~ 0.4400s hexToInt ~ 0.1100s
quelle
Eine schnelle und schmutzige Lösung:
// makes a number from two ascii hexa characters int ahex2int(char a, char b){ a = (a <= '9') ? a - '0' : (a & 0x7) + 9; b = (b <= '9') ? b - '0' : (b & 0x7) + 9; return (a << 4) + b; }
Sie müssen sicher sein, dass Ihre Eingabe korrekt ist, keine Validierung enthalten (man könnte sagen, es ist C). Gut, dass es ziemlich kompakt ist, es funktioniert sowohl mit 'A' bis 'F' als auch mit 'a' bis 'f'.
Der Ansatz basiert auf der Position der Alphabetzeichen in der ASCII-Tabelle. Schauen wir uns beispielsweise Wikipedia an ( https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png ). Kurz gesagt, die Zahlen befinden sich unter den Zeichen, sodass die numerischen Zeichen (0 bis 9) leicht konvertiert werden können, indem der Code für Null subtrahiert wird. Die alphabetischen Zeichen (A bis F) werden gelesen, indem andere als die letzten drei Bits auf Null gesetzt werden (was effektiv dazu führt, dass entweder Groß- oder Kleinbuchstaben verwendet werden), eins subtrahiert wird (da das Alphabet nach der Bitmaskierung an Position eins beginnt) und zehn addiert werden ( weil A bis F den 10. bis 15. Wert im Hexadezimalcode darstellen). Schließlich müssen wir die beiden Ziffern kombinieren, die das untere und obere Halbbyte der codierten Zahl bilden.
Hier gehen wir mit dem gleichen Ansatz (mit geringfügigen Abweichungen):
#include <stdio.h> // takes a null-terminated string of hexa characters and tries to // convert it to numbers long ahex2num(unsigned char *in){ unsigned char *pin = in; // lets use pointer to loop through the string long out = 0; // here we accumulate the result while(*pin != 0){ out <<= 4; // we have one more input character, so // we shift the accumulated interim-result one order up out += (*pin < 'A') ? *pin & 0xF : (*pin & 0x7) + 9; // add the new nibble pin++; // go ahead } return out; } // main function will test our conversion fn int main(void) { unsigned char str[] = "1800785"; // no 0x prefix, please long num; num = ahex2num(str); // call the function printf("Input: %s\n",str); // print input string printf("Output: %x\n",num); // print the converted number back as hexa printf("Check: %ld = %ld \n",num,0x1800785); // check the numeric values matches return 0; }
quelle
Dies ist eine Funktion zum direkten Konvertieren von hexadezimalem char-Array in eine Ganzzahl, für die keine zusätzliche Bibliothek erforderlich ist:
int hexadecimal2int(char *hdec) { int finalval = 0; while (*hdec) { int onebyte = *hdec++; if (onebyte >= '0' && onebyte <= '9'){onebyte = onebyte - '0';} else if (onebyte >= 'a' && onebyte <='f') {onebyte = onebyte - 'a' + 10;} else if (onebyte >= 'A' && onebyte <='F') {onebyte = onebyte - 'A' + 10;} finalval = (finalval << 4) | (onebyte & 0xF); } finalval = finalval - 524288; return finalval; }
quelle
Ich habe eine Bibliothek erstellt, um eine Hexadezimal- / Dezimal-Konvertierung ohne Verwendung von durchzuführen
stdio.h
. Sehr einfach zu bedienen:unsigned hexdec (const char *hex, const int s_hex);
Initialisieren Sie vor der ersten Konvertierung das für die Konvertierung verwendete Array mit:
void init_hexdec ();
Hier der Link auf Github: https://github.com/kevmuret/libhex/
quelle
Ich habe eine ähnliche Sache gemacht, denke, es könnte dir helfen, dass es tatsächlich für mich funktioniert
int main(){ int co[8],i;char ch[8];printf("please enter the string:");scanf("%s",ch);for(i=0;i<=7;i++){if((ch[i]>='A')&&(ch[i]<='F')){co[i]=(unsigned int)ch[i]-'A'+10;}else if((ch[i]>='0')&&(ch[i]<='9')){co[i]=(unsigned int)ch[i]-'0'+0;}}
hier habe ich nur eine Zeichenfolge von 8 Zeichen genommen. Wenn du willst, dass du eine ähnliche Logik für 'a' zu 'f' hinzufügen kannst, um ihre äquivalenten Hex-Werte anzugeben, habe ich das nicht getan, weil ich es nicht gebraucht habe.
quelle
Verwenden Sie xtoi (stdlib.h). Die Zeichenfolge hat "0x" als erste zwei Indizes, also trimmen Sie val [0] und val [1] aus, indem Sie xtoi & val [2] senden.
xtoi( &val[2] );
quelle
xtoi
ist keine StandardfunktionIch weiß, dass dies wirklich alt ist, aber ich denke, die Lösungen sahen zu kompliziert aus. Versuchen Sie dies in VB:
Public Function HexToInt(sHEX as String) as long Dim iLen as Integer Dim i as Integer Dim SumValue as Long Dim iVal as long Dim AscVal as long iLen = Len(sHEX) For i = 1 to Len(sHEX) AscVal = Asc(UCase(Mid$(sHEX, i, 1))) If AscVal >= 48 And AscVal <= 57 Then iVal = AscVal - 48 ElseIf AscVal >= 65 And AscVal <= 70 Then iVal = AscVal - 55 End If SumValue = SumValue + iVal * 16 ^ (iLen- i) Next i HexToInt = SumValue End Function
quelle