Общеизвестно, что для печати значений переменных этот тип является одним из целочисленных типов фиксированной ширины (например, uint32_t
) нужно включить cinttypes
(в C ++) или inttypes.h
(в C) заголовочный файл и использовать макросы спецификаторов формата, такие как PRIu32
, Но как сделать то же самое, когда wprintf
функция используется? Такой макрос должен расширяться как строковый литерал с L
префикс в этом случае.
Будет ли это работать или нет, зависит от того, какой стандарт C использует компилятор.
От эта строковая литеральная ссылка
Только два узких или два широких строковых литерала могут быть объединены.
(до C99)
а также
Если один литерал без префикса, результирующий строковый литерал имеет ширину / кодировку, указанную префиксным литералом. Если два строковых литерала имеют разные префиксы кодирования, конкатенация определяется реализацией. (с C99)
[Акцент мой]
Поэтому, если вы используете старый компилятор или тот, который не поддерживает стандарт C99 (или более поздний), это невозможно. Кроме того целочисленные типы фиксированной ширины был стандартизирован в C99 так макросы на самом деле не существует для таких старых компиляторов, что делает вопрос спорный.
Для более современных компиляторов, которые поддерживают C99 и более поздние версии, это не проблема, так как конкатенация строка-литерал будет работать, и компилятор превратит строку без префикса в строку широких символов, например, так.
wprintf(L"Value = %" PRIu32 "\n", uint32_t_value);
будет работать нормально.
Если у вас есть компилятор до C99, но у вас все еще есть макросы и целочисленные типы фиксированной ширины, вы можете использовать функциональные макросы для добавления L
префикс к строковым литералам. Что-то вроде
#define LL(s) L ## s
#define L(s) LL(s)
...
wprintf(L"Value = %" L(PRIu32) L"\n", uint32_t_value);
Не уверен, где проблема, но здесь (VS 2015) оба
wprintf(L"AA %" PRIu32 L" BB", 123);
а также
printf("AA %" PRIu32 " BB", 123);
правильно скомпилировать и дать следующий вывод:
AA 123 BB
Даже если ваш компилятор не поддерживает конкатенацию литералов с разными префиксами, вы всегда можете расширить узкий:
#define WIDE(X) WIDE2(X)
#define WIDE2(X) L##X
wprintf(L"%" WIDE(PRIu32), foo);
(Более слабая) альтернатива использованию макросов из <inttypes.h>
должен преобразовать / привести тип фиксированной ширины к эквивалентному или большему стандартному типу.
wprintf(L"%lu\n", 0ul + some_uint32_t_value);
// or
wprintf(L"%lu\n", (unsigned long) some_uint32_t_value);