Я пытаюсь отформатировать двоичный массив: char* memblock
в шестнадцатеричную строку.
Когда я использую следующее:
fprintf(out, "0x%02x,", memblock[0]);
Я получаю следующий вывод:
0x7f,
Когда я пытаюсь использовать boost::format
на офстриме вот так:
std::ofstream outFile (path, std::ios::out); //also tried with binary
outFile << (boost::format("0x%02x")%memblock[0]);
Я получаю странный вывод, как это (видно в Vi): 0x0^?
,
Что дает?
Учитывая, что персонаж за 0x7f
является CTRL-?, похоже, это выводит memblock[0]
как символ, а не как шестнадцатеричное значение, несмотря на вашу строку формата.
Это на самом деле имеет смысл, основываясь на том, что я прочитал в документации. Boost::format
является типобезопасной библиотекой, в которой спецификаторы формата определяют, как будет выводиться переменная, но ограничено фактическим типом указанной переменной, который имеет приоритет.
документация говорится (мой жирный):
Устаревшие строки формата printf:
%spec
гдеspec
этоprintf
спецификация формата.
spec
передает параметры форматирования, такие как ширина, выравнивание, числовая база, используемая для форматирования чисел, а также другие конкретные флаги. Но классический флаг спецификации типаprintf
имеет слабое значение в формате.Это просто устанавливает соответствующие флаги на внутренний поток и / или параметры форматирования, но не требует, чтобы соответствующий аргумент был определенного типа. например : спецификация
2$x
значение «print аргумент № 2, который является целым числом в гекса» для printf, просто означает «аргумент печати 2 с флагами базового поля потока, установленными в шестнадцатеричный формат» для формата.
И, по-видимому, установка флага поля в hex не имеет большого смысла, когда вы печатаете char
так что игнорируется. Дополнительно из этой документации (хотя перефразируя немного):
type-char
не облагать соответствующий аргумент должен иметь ограниченный набор типов, но просто устанавливает флаги которые связаны с этой спецификацией типа.type-char
изp
или жеx
означает шестнадцатеричный вывод, но просто устанавливает шестнадцатеричный флаг в потоке.
Это также более конкретно подтверждается текстом эта ссылка:
Мои коллеги и я обнаружили, однако, что когда
%d
дескриптор используется для печатиchar
Переменная результат как будто%c
дескриптор был использован —printf
а такжеboost::format
не дают тот же результат.
В документации Boost, связанной с вышеупомянутым, также объясняется, что заполнение нулями 0
модификатор работает на все типы, а не только целые, поэтому вы получаете второе 0
в 0x0^?
( ^?
это не замужем персонаж).
Во многом это похоже на проблему попытки вывести const char *
в C ++, так что вы видите указатель. Следующий код:
#include <iostream>
int main() {
const char *xyzzy = "plugh";
std::cout << xyzzy << '\n';
std::cout << (void*)xyzzy << '\n';
return 0;
}
будет производить что-то вроде:
plugh
0x4009a0
потому что стандартные библиотеки знают, что строки в стиле C являются особым случаем, но, если вы сказать они — пустой указатель, они выдают указатель в качестве вывода.
Решение в ваш конкретный случай может быть просто бросить char
для int
или какой-то другой тип, который интеллектуально обрабатывает %x
спецификатор формата:
outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));