2013-10-01 13 views
1

Я пытался выяснить, как это сделать во встроенном C++ некоторое время, у меня есть гексаговый цвет для веб-сайта в RGB888, например, «# ba00ff», который Я хочу, чтобы преобразовать в шестнадцатеричном значение C++ RGB555, например 0x177CC/C++ Hex char * to byte array

в настоящее время я уже подстриженный на # из строки, и я застрял при преобразовании его в тип можно использовать для создания RGB555

моего кода в настоящее время выглядит так:

p_led_struct->color = "#ba00ff"; 
char hexString[7] = {}; 
memmove(hexString, p_led_struct->color+1, strlen(p_led_struct->color)); 
byte colorBytes[3]; 
sscanf(hexString,"%x%x%x",&colorBytes); 

Значение hexString становится «ba00ff» правильно, хотя массив colorBytes имеет неверные данные.

любая помощь в том, как я должен делать это преобразование было бы удивительным :)

Спасибо!

+0

Если вы пропустите первый символ , вам не нужно вычитать 1 из длины строки? –

+1

Я считаю, что конец строки '/ n' делает «ba00ff» 7 символов, я не уверен, что массив символов без конца строкового символа в sscanf вызовет ошибку. ** Изменить ** извините, я имел в виду «Null-terminated» '\ 0' not'/n' –

+0

'/ n' является символом новой строки, а не терминатором. В вашей строке нет новой строки. –

ответ

2

Проблемы с sscanf(hexString,"%x%x%x",&colorBytes); являются:

  1. sscanf ожидает от вас, чтобы дать 3 int сек в качестве параметра, но только один массив дается и не int.
  2. Отдельный %x читает более двух символов.

Try:

int r, g, b; 
if(sscanf(hexString,"%2x%2x%2x", &r, &g, &b) != 3) { 
    // error 
} 

Edit:

Очень полезная информация о Scanf-семьи: http://en.cppreference.com/w/c/io/fscanf

+0

Awesome, это сработало отлично, спасибо за объяснение, как правильно использовать sscanf! –

1

Используйте hh модификатор для сканирования непосредственно в 1 байт.

p_led_struct->color = "#ba00ff"; 
byte colorBytes[3]; 
int result; 
result = sscanf(p_led_struct->color, "#%2hhx%2hhx%2hhx", &colorBytes[0], 
    &colorBytes[1], &colorBytes[2]); 
if (result != 3) { 
    ; // handle problem 
} 

После успешного сканирования трехразрядных 8-битных байтов RGB пересчитайте результат 3x5 бит.

int r,g,b; 
r = colorBytes[0] >> 3; 
g = colorBytes[1] >> 3; 
b = colorBytes[2] >> 3; 
printf("%04X", (r << 10) | (g << 5) | (b << 0)); 
+0

опечатка в вашей последней строке, теперь вы получите красную серовую шкалу :) – usr2564301

+0

@Jongware Спасибо и исправлены. Теперь единственное, что красное - мое лицо.:) – chux

+0

Спасибо Chux, я пытаюсь понять решение должно 'result = sscanf (p_led_struct-> color," #% 2hhx% 2hhx% 2hhx ", & colorBytes [0], & colorBytes [0], & colorBytes [0]); ' be' & colorBytes [0], & colorBytes [1], & colorBytes [2] 'или все ссылки на первый адрес? –

2

Преобразование p_led_struct->color в целое

p_led_struct->color = "#ba00ff"; 
unsigned int colorValue = strtoul(p_led_struct->color+1, NULL, 16); 

и преобразовать это значение RGB в RGB555. Целый RGB имеет поле 0000.0000.rrrr.rrrr.gggg.gggg.bbbb.bbbb и RGB555 имеет поле 0rrr.rrgg.gggb.bbbb, так что нам нужны только немного сдвигая:

unsigned short rgb555 = ((colorValue & 0x00f80000) >> 9) + // red 
    ((colorValue & 0x0000f800) >> 7) + // green 
    ((colorValue & 0x000000f8) >> 3); // blue