2013-05-16 2 views
0

Я просто хочу знать, как преобразовать шестнадцатеричное значение, содержащееся в символе (байте) в целое число. Я хочу преобразовать цветовой буфер из .bmp-файла, который, конечно, в шестнадцатеричном формате и преобразовать его в целые числа.Как преобразовать шестнадцатеричное значение, содержащееся в символе (байт), в целое число?

Например:

char rgb_hexa[3] = {0xA8, 0xF4, 0xD3}; 

После преобразования:

int rgb_int[3] = {168, 244, 211}; 

Я всегда пытался использовать strtol, но это, кажется, работает только с гольца *. Я попытался выполнить следующий тест, но он не работает:

char src_hexa_red = 0xA8; 
char src_hexa_green = 0xF4; 
char src_hexa_blue = 0xD3; 

std::cout << "R=" << strtol(&src_hexa_red, (char**)NULL, 16) << ", G=" 
     << strtol(&src_hexa_green, (char**)NULL, 16) << ", B=" 
     << strtol(&src_hexa_blue, (char**)NULL, 16) << std::endl; 

Может кто-нибудь мне помочь? Заранее благодарим за помощь.

+3

Вам не нужно ничего делать. Целочисленные литералы '0xA8' и' 168' одинаковы, это просто другой способ написать то же самое, чтобы облегчить программисту. Компилятор помещает то же ** двоичное ** представление в скомпилированный двоичный файл. –

+1

@JoachimPileborg - вам нужно будет отличить от unsigned - 168 больше, чем то, что поместится в 'char'. – user93353

+0

@ user93353 Всё зависит. Если вы скомпилируете с помощью опции '/ J' с MSVC,' 168' поместится в 'char'. В более общем плане вам придется либо преобразовать в 'unsigned char', _or_' & 'с' 0xFF'. Последний будет работать даже на машинах с 9-битными байтами (но я не знаю нигде, где подписан знак «char»). –

ответ

3
for(int i = 0; i < 3; ++i) 
    rgb_int[i] = (unsigned char)rgb_hexa[i]; 

char представляет собой целое число в тип C & C++ так же, как short, int и long. Это всего лишь наименьший целочисленный тип. В основном, char подписан & максимум, который может поместиться, равен 127. Так что если значение шестнадцатеричного значения было меньше или равно 127, вам не нужно было ничего делать. Однако в этом случае у вас есть шестнадцатеричные значения> 127 - поэтому вам нужно будет их отличить без знака, чтобы получить нужное значение.

Обратите внимание, что оба оператора идентичны компилятору.

char rgb_hexa[3] = {0xA8, 0xF4, 0xD3}; 
char rgb_hexa[3] = {168, 244, 211}; 

Вы могли бы даже использовал восьмеричное, если вы хотите

char rgb_hexa[3] = {0250, 0364, 0323}; 

Это все то же самое.

+0

unsigned char был ответом для меня. Не понял, что знак подписан. Этот вопрос не должен иметь downvotes .. Это настоящая борьба для новичков ... – Fr4nc3sc0NL

6

Один char никогда не содержит шестнадцатеричный. Не decimal, для это вопрос. Строго говоря, a char содержит значение значение; для стандарта C++ требуется использовать двоичное представление для значения. Значение можно интерпретировать как символ , но это не всегда так; существуют контексты , где интегральное значение используется напрямую.

Шестнадцатеричные и десятичные числа - это просто способы представления значения в текстовом формате. Они имеют смысл иметь дело с текстом.

0

Значения в массиве char уже находятся в двоичной форме, поэтому вы можете использовать их для int, если они вам нужны.

int v = (int)rgb_hexa[0]; 

Вы должны знать, что с использованием знакового знака они будут расширять знак. Таким образом, 0xFA становится 0xFFFFFFFA при преобразовании в int.

Если вы хотите сохранить значения, вы должны использовать unsigned char и unsigned int, что делает его 0x000000FA в зависимости от того, как вы хотите использовать значения.

int v0 = (int)a[1]; <-- sign extended 
unsigned int v1 = (unsigned int)a[1]; <-- sign extended 
unsigned int v1 = (unsigned int)((unsigned char *)a)[1]; <-- not sign extended 
+0

Обычный символ может быть подписан или без знака. По историческим причинам он обычно (но не всегда) по умолчанию имеет подпись, но большинство компиляторов имеют возможность сделать его неподписанным (что вы, вероятно, должны использовать --- подписанные символы - ужасный хак). –

0

Вам не нужно делать никакого преобразования, потому что hexa/decimal - это просто способы представления значений.

Например, 0xA8 в шестнадцатеричном формате имеет такое же значение, как 180 в десятичной системе и 250 в восьмеричном. Как и в языках, например, «два», «deux» и «dois» представляют все одинаковое число (2).

В вашем случае, если вы хотите напечатать значения выполните следующие действия:

short y = (short) x & 0x00FF; // x is the char you want to print 
    cout << "Value (decimal): " << y; 
    cout << "Value (hexa): " << hex << y; 
    cout << "Value (oct): " << oct << y; 
0

Почему вы не можете сделать это

int main(int argc, char *argv[]) 
{ 
    char rgb_hexa[3] = {0xA8, 0xF4, 0xD3}; 
    int rgb_int[3] = {0,}; 
    int i = 0; 
    for(i = 0 ; i < 3 ;i++) 
     rgb_int[i] = (unsigned char)rgb_hexa[i]; 

    for(i = 0 ; i < 3 ;i++) 
     printf("%d ",rgb_int[i]); 

    return 0; 
} 

довольно прямо вперед ..

0

Для типа конверсии, имеется static_cast:

unsigned char source = 168; // note that this has for compiler same meaning as: 
// unsigned char source = 0xA8; // because data is stored in binary anyway 

unsigned int dest = static_cast<int>(source); // the conversion 

std::cout << source << std::endl; 

dest и source имеют одинаковое двоичное значение, но они имеют другой тип.

Я использовал неподписанные типы, потому что подписанный символ обычно содержит значения от -127 до 127, см. limits.