2016-04-29 8 views
0

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

+2

В каких из C и C++ вы программируете? Выберите не более одного. – fuz

+1

@FUZxxl Почему я должен выбрать только один? – Constructor

+1

В чем проблема? Не компилируется ли ваш код? Отображает ли 'wprintf' что-то еще, чем вы ожидаете? –

ответ

5

Если это будет работать или не зависит от того, какой стандарт C используется компилятором.

От this string literal reference

только две узкие или две широкие строковые литералы могут быть соединены. (до C99)

и

Если один литерал без префикса, в результате строка символов не имеет ширину/кодирования, указанного префикса буквально. Если два строковых литерала имеют разные префиксы кодирования, конкатенация определяется реализацией. (так C99)

[выделено мной]

Так что, если вы используете старый компилятор или тот, который не поддерживает стандарт C99 (или позже), это не представляется возможным. Кроме fixed-width integer types был стандартизирован в 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); 
+0

Благодарим вас за ответ. Вы правы, я использую старый компилятор, и это проблема с ним. – Constructor

+0

Есть ли какое-либо решение для компиляторов, совместимых с C89? – Constructor

+0

@Constructor Должно быть возможно использование некоторых макросов типа функции. Обновлен мой ответ. –

3

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

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

и

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

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

AA 123 BB 
+0

Код, который компилируется одним компилятором, не является обязательным стандартным. – Constructor

+0

@ Конструктор Я никогда не утверждал этого. –

1

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

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

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

Demo

1

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

wprintf(L"%lu\n", 0ul + some_uint32_t_value); 
// or 
wprintf(L"%lu\n", (unsigned long) some_uint32_t_value); 

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

  • Нет связанных вопросов^_^