У меня есть чар byte[0] = '1' (H'0x31)
а также byte[1] = 'C'(H'0x43)
Я использую еще один буфер для большего количества баффов char hex_buff[0]
Я хочу иметь шестнадцатеричное содержание в этом hex_buff[0] = 0x1C
(т.е. комбинация байта [0] и байта [1])
Я использовал код ниже, но я понял, что мой код действителен только для шестнадцатеричных значений 0-9
char s_nibble1 = (byte[0]<< 4)& 0xf0;
char s_nibble2 = byte[1]& 0x0f;
hex_buff[0] = s_nibble1 | s_nibble2;
// здесь я хочу иметь 0x1C
вместо 0x13
Возможный способ сделать это, без зависимостей с другими функциями управления символами:
char hex2byte(char *hs)
{
char b = 0;
char nibbles[2];
int i;
for (i = 0; i < 2; i++) {
if ((hs[i] >= '0') && (hs[i] <= '9'))
nibbles[i] = hs[i]-'0';
else if ((hs[i] >= 'A') && (hs[i] <= 'F'))
nibbles[i] = (hs[i]-'A')+10;
else if ((hs[i] >= 'a') && (hs[i] <= 'f'))
nibbles[i] = (hs[i]-'a')+10;
else
return 0;
}
b = (nibbles[0] << 4) | nibbles[1];
return b;
}
Например: hex2byte("a1")
возвращает байт 0xa1
,
В вашем случае вы должны вызвать функцию как: hex_buff[0] = hex2byte(byte)
,
Что мешает вам использовать strtol()
?
char bytes[] = "1C";
char buff[1];
buff[0] = strtol(bytes, NULL, 16); /* Sets buff[0] to 0x1c aka 28. */
Чтобы добавить это согласно chuxкомментарий: strtol()
работает только на 0
-определенные массивы символов. Который не обязательно должен иметь место для вопроса OP.
Вы пытаетесь получить кусочек, маскируя биты символьного кода, а не вычитая действительное значение. Это не сработает, потому что диапазон отключен: между [0..9]
а также [A-F]
в кодировке, поэтому маскирование не удастся.
Вы можете исправить это, добавив небольшую вспомогательную функцию и дважды используя ее в своем коде:
int hexDigit(char c) {
c = toupper(c); // Allow mixed-case letters
switch(c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': return c-'0';
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F': return c-'A'+10;
default: // Report an error
}
return -1;
}
Теперь вы можете закодировать конверсию следующим образом:
int val = (hexDigit(byte[0]) << 4) | hexDigit(byte[1]);
Похоже, вы пытаетесь преобразовать ASCII-гекс во внутреннее представление.
Есть много способов сделать это, но тот, который я использую чаще всего для каждого клева:
int nibval(unsigned short x)
{
if (('0' <= x) && ('9' >= x))
{
return x - '0';
}
if (('a' <= x) && ('f' >= x))
{
return x - ('a' - 10);
}
if (('A' <= x) && ('F' >= x))
{
return x - ('A' - 10);
}
// Invalid input
return -1;
}
При этом используется параметр типа unsigned int, поэтому он будет работать как с однобайтовыми символами, так и с символами wchar_t.