Преобразовать шестнадцатеричную строку с ведущим 0x в короткое со знаком в С++?

Я нашел код для преобразования шестнадцатеричной строки в signed int с использованием strtol, но я не могу найти что-то для короткого int (2 байта). Вот мой кусок кода:

while (!sCurrentFile.eof() )
{
    getline (sCurrentFile,currentString);
    sOutputFile<<strtol(currentString.c_str(),NULL,16)<<endl;
}

Моя идея состоит в том, чтобы прочитать файл со значениями шириной 2 байта (например, 0xFFEE), преобразовать его в подписанный int и записать результат в выходной файл. Скорость выполнения не имеет значения.

Я мог бы найти несколько способов избежать этой проблемы, но я хотел бы использовать «однострочное» решение, поэтому, возможно, вы можете помочь в этом :)

Редактировать: файлы выглядят так:

0x0400
0x03fe
0x03fe
...

Редактировать: я уже пытался использовать шестнадцатеричный оператор, но перед этим мне все еще нужно преобразовать строку в целое число.

// This won't work as currentString is not an integer
myInt << std::hex << currentString.c_str(); 

person gramm    schedule 28.09.2009    source источник
comment
Как выглядит ваш входной файл? Без этой информации довольно сложно давать какие-либо рекомендации.   -  person hrnt    schedule 28.09.2009
comment
см., что strtol возвращает long , а не signed int,   -  person Satbir    schedule 28.09.2009
comment
sscanf возвращает целое число, но возвращаемое значение функций семейства scanf — это количество успешно преобразованных полей. Хотя я ценю огласку, вы неправильно расшифровали это. :)   -  person ChrisV    schedule 28.09.2009
comment
редактировать: мой плохой, я хотел уменьшить код и не смотрел на то, что я делал - это был конец моего рабочего дня :)   -  person gramm    schedule 29.09.2009
comment
Похоже, Локи — единственный человек, который на самом деле ответил на вопрос.   -  person jww    schedule 07.05.2017


Ответы (6)


Рассматривали ли вы sscanf с квалификатором преобразования "%hx"?

person ChrisV    schedule 28.09.2009
comment
Или, если у вас нет особой необходимости использовать потоки ввода-вывода C++, перейдите прямо к fscanf... Зависит от того, какой частью этого кода вы управляете. - person ChrisV; 28.09.2009
comment
Я обычно с этим справляюсь с помощью fscanf и sscanf. У меня есть программа, которая считывает шестнадцатеричные строки CRC, подобные этой: sscanf(cstr_fileCRC, %lX, &ul_fileCRC); - person John D.; 28.09.2009
comment
Вопрос помечен как C++. Кроме того, sscanf обычно не одобряют из-за проблем, связанных с безопасностью, которые он несет с собой. - person jww; 07.05.2017

Это должно быть просто:

std::ifstream   file("DataFile");
int             value;

while(file >> std::hex >> value)  // Reads a hex string and converts it to an int.
{
    std::cout << "Value: " << std::hex << value << "\n";
}

Пока мы говорим о файлах:
вы должны НЕ делать следующее:

while (!sCurrentFile.eof() )
{
    getline (sCurrentFile,currentString);
    ... STUFF ...
}

Это связано с тем, что когда вы читаете последнюю строку, она НЕ устанавливает EOF. Поэтому, когда вы зацикливаетесь, а затем читаете строку после последней строки, getline() завершится ошибкой, и вы будете делать STUFF с тем, что было в currentString с момента последней настройки. Таким образом, вы будете обрабатывать последнюю строку дважды.

Правильный способ перебора файла:

while (getline(sCurrentFile,currentString))
{
    // If the get fails then you have read past EOF and loop is not entered.
    ... STUFF ...
}
person Martin York    schedule 28.09.2009

Вероятно, вы можете использовать оператор >> класса stringtream с шестнадцатеричным манипулятор.

person Naveen    schedule 28.09.2009
comment
Именно то, что мне нужно, это всего одна строка! - person gramm; 28.09.2009
comment
Вы, вероятно, должны привести пример. Ведущий 0x, по-видимому, приводит к сбою синтаксического анализа. - person jww; 07.05.2017

Если вы уверены, что данным из currentString.c_str() можно доверять, вы также можете легко сделать

myInt << std::hex << atoi(currentString.c_str());
person Chaosteil    schedule 28.09.2009
comment
Зачем использовать функции C, если поток C++ уже выполняет всю работу. - person Martin York; 28.09.2009
comment
Вопрос помечен как C++, а не C. - person jww; 07.05.2017

Если вы знаете, что данные всегда будут в этом формате, не могли бы вы просто сделать что-то вроде:

myInt << std::hex << currentString.c_str() +2; // skip the leading "0x"
person Community    schedule 28.09.2009
comment
Здесь std::hex ничего не делает, поскольку обрабатывает строку. Вы просто перепечатываете прочитанную строку (минус первые два символа). - person Martin York; 28.09.2009

person    schedule
comment
Вы явно совсем охренели :-) - person Martin York; 28.09.2009