2013-08-20 3 views
0

Я хотел бы знать, почему я получаю результат 0 при преобразовании шестнадцатеричной строки (0x1) в uint8.Как преобразовать шестнадцатеричную строку в Uint8

Я пытался использовать boost::lexical_cast, но получаю исключение bad_lexical_cast. Поэтому я решил использовать stringstream, но я получаю неправильное значение.

... 
uint8_t temp; 
std::string address_extension = "0x1"; 
std::cout << "Before: " << address_extension << std::endl; 
StringToNumeric(address_extension, temp); 
std::cout << "After: " << temp << std::endl; 
... 

template <typename T> 
void StringToNumeric(const std::string& source, T& target) 
{ 
    //Check if source is hex 
    if(IsHexNotation(source)) 
    { 
     std::stringstream ss; 
     //Put value in the stream 
     ss << std::hex << source; 
     //Stream the hex value into a target type 
     ss >> target; 
    } 

} 

Вы можете быть уверены в том, что IsHexNotation() работает правильно и не меняет источник, как она объявлена:

bool IsHexNotation(const std::string& source) 

Что такое правильный способ преобразования шестнадцатеричной строки в uint8 (при условии, что hex string Вписывается в тип данных)?

+0

Hex - это * представление * числового значения, равно как десятичные или римские цифры. Вы * форматируете * это или * сканируете * это, вы не * прикладываете * его. –

+0

@HotLicks Это имеет смысл - я никогда не думал об этом таким образом (и поэтому почему лексический актер не работал - он не знал, что с ним делать!). – larrylampco

ответ

5

Используя код, как это работает для меня:

std::stringstream ss; 
int target(0); 
ss << std::hex << source; 
if (ss >> target) { 
    std::cout << "value=" << target << '\n'; 
} 
else { 
    std::cout << "failed to read value\n"; 
} 

Однако, я помню, что там была дискуссия о том, где позиция считывания строкового потока должна быть после записи. Поскольку он в основном следует за моделью файловых потоков, вам нужно искать желаемую позицию, даже если она находится в том же положении. Некоторые реализации использовали общую позицию, а другие использовали отдельные позиции чтения и записи. Вы можете использовать

ss.seekg(0, std::ios_base::beg); 

, чтобы убедиться, что позиция чтения находится в начале потока. С другой стороны, и, по моему мнению, предпочтительнее, чтобы инициализировать std::istringstream и читать от этого непосредственно:

std::istringstream in(source); 
if (in >> std::hex >> target) { ... } 

Обратите внимание, что вы всегда хотите, чтобы проверить, если добыча была успешной: таким образом, вы получите подсказку, что что-то на самом деле пошел неверно, а значение 0 может быть только некоторым начальным значением переменной.

+0

После попытки вашей реализации кажется, что моя проблема связана с использованием 'uint8_t'. Когда я использую только 'int', как и у вас, он работает нормально. Любые идеи о том, почему это может вызвать изменения? – larrylampco

+0

@larrylampco: Вы не упомянули свой выбор типа для «target», и я предположил, что это будет правильное целое число: хотя типы символов обычно ведут себя как маленькие целые числа, они не всегда так делают. Отформатированные функции чтения для символов начинаются с пропущенных пробелов (при условии, что 'std :: ios_base :: skipws' установлен по умолчанию), а затем прочитайте один символ. То есть, ваш 'uint8_t' считывает значение' '0'' (а не значение '0' или' '\ 0'') вместо того, чтобы пытаться прочитать шестнадцатеричное значение. –

Смежные вопросы