У меня есть char [], который содержит значение, такое как "0x1800785", но для функции, которую я хочу предоставить для значения, требуется int, как я могу преобразовать это в int? Я искал вокруг, но не могу найти ответа. Спасибо.
Преобразовать шестнадцатеричную строку (char []) в int?
Ответ 1
Вы пробовали strtol()
?
strtol - преобразовать строку в длинное целое
Пример:
const char *hexstring = "abcdef0";
int number = (int)strtol(hexstring, NULL, 16);
В случае, если строковое представление числа начинается с префикса 0x
, один должен должен использовать 0 в качестве базы:
const char *hexstring = "0xabcdef0";
int number = (int)strtol(hexstring, NULL, 0);
(Можно также указать явную базу, такую как 16, но я бы не рекомендовал вводить избыточность.)
Ответ 2
Что-то вроде этого может быть полезно:
char str[] = "0x1800785";
int num;
sscanf(str, "%x", &num);
printf("0x%x %i\n", num, num);
Прочитайте man sscanf
Ответ 3
Или, если вы хотите иметь свою собственную реализацию, я написал эту быструю функцию в качестве примера:
/**
* 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;
}
Ответ 4
Предполагая, что вы имеете в виду строку, как насчет strtol?
Ответ 5
Попробуйте использовать блок кода, который работает для меня.
char *p = "0x820";
uint16_t intVal;
sscanf(p, "%x", &intVal);
printf("value x: %x - %d", intVal, intVal);
Выход:
value x: 820 - 2080
Ответ 6
Итак, после некоторого времени поиска и обнаружения того, что strtol довольно медленный, я кодировал свою собственную функцию. Он работает только для заглавных букв, но добавление строчных букв не является проблемой.
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;
}
Использование:
char *someHex = "#CCFF00FF";
int hexDevalue = hexToInt(someHex, 1, 8);
1, потому что гекс, который мы хотим преобразовать, начинается со смещения 1, а 8, потому что это длина гекса.
Speedtest (1.000.000 звонков):
strtol ~ 0.4400s
hexToInt ~ 0.1100s
Ответ 7
Один быстрый & грязное решение:
// 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;
}
Вы должны быть уверены, что введенные данные верны, проверка не включена (можно сказать, что это C). Хорошо, что он довольно компактный, он работает с буквами "A" - "F" и "a" - "f".
Подход основан на положении букв алфавита в таблице ASCII, например, давайте посмотрим. в Википедию (https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png). Короче говоря, цифры находятся ниже символов, поэтому числовые символы (от 0 до 9) легко конвертируются путем вычитания кода для нуля. Буквенные символы (от A до F) читаются путем обнуления, отличного от последних трех битов (эффективно заставляя его работать с upper- или строчными буквами), вычитания одного (потому что после маскировки битов алфавит начинается с первой позиции) и добавления десяти (потому что от A до F представляют 10-15 значение в шестнадцатеричном коде). Наконец, нам нужно объединить две цифры, которые образуют нижний и верхний кусочек закодированного числа.
Здесь мы идем с тем же подходом (с небольшими изменениями):
#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;
}
Ответ 8
Я сделал librairy, чтобы сделать шестнадцатеричное/десятичное преобразование без использования stdio.h
. Очень прост в использовании:
unsigned hexdec (const char *hex, const int s_hex);
Перед первым преобразованием инициализируйте массив, используемый для преобразования, с помощью:
void init_hexdec ();
Здесь ссылка на github: https://github.com/kevmuret/libhex/
Ответ 9
Я сделал аналогичную вещь, думаю, что это может помочь он действительно работает для меня
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;}}
здесь я взял только строку из 8 символов. если вы хотите, чтобы u мог добавить аналогичную логику для 'a' to 'f', чтобы дать свои эквивалентные шестнадцатеричные значения, я не сделал этого, потому что я не нуждался в этом.
Ответ 10
Используйте strtol
если у вас есть libc, как strtol
в верхнем ответе. Однако, если вам нравятся нестандартные вещи или вы используете микроконтроллер без libc или около того, вы можете захотеть слегка оптимизированную версию без сложных ветвлений.
#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;
}
Магия сдвига битов сводится к следующему: просто используйте последние 4 бита, но если это не цифра, то также добавьте 9.
Ответ 11
Используйте xtoi (stdlib.h). Строка имеет "0x" в качестве первых двух индексов, поэтому trim val [0] и val [1] выключен, отправив xtoi & val [2].
xtoi( &val[2] );
Ответ 12
Я знаю, что это действительно старый, но я думаю, что решения выглядели слишком сложными. Попробуйте это в 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