Как вывести значение переменных uint32_t через функцию wprintf?

Общеизвестно, что для печати значений переменных этот тип является одним из целочисленных типов фиксированной ширины (например, uint32_t) нужно включить cinttypes (в C ++) или inttypes.h (в C) заголовочный файл и использовать макросы спецификаторов формата, такие как PRIu32, Но как сделать то же самое, когда wprintf функция используется? Такой макрос должен расширяться как строковый литерал с L префикс в этом случае.

0

Решение

Будет ли это работать или нет, зависит от того, какой стандарт 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);
5

Другие решения

Не уверен, где проблема, но здесь (VS 2015) оба

wprintf(L"AA %" PRIu32 L" BB", 123);

а также

printf("AA %" PRIu32 " BB", 123);

правильно скомпилировать и дать следующий вывод:

AA 123 BB
3

Даже если ваш компилятор не поддерживает конкатенацию литералов с разными префиксами, вы всегда можете расширить узкий:

#define WIDE(X) WIDE2(X)
#define WIDE2(X) L##X

wprintf(L"%" WIDE(PRIu32), foo);

демонстрация

1

(Более слабая) альтернатива использованию макросов из <inttypes.h> должен преобразовать / привести тип фиксированной ширины к эквивалентному или большему стандартному типу.

wprintf(L"%lu\n", 0ul + some_uint32_t_value);
// or
wprintf(L"%lu\n", (unsigned long) some_uint32_t_value);
1
По вопросам рекламы [email protected]