/ / Как да използваме stdint типове с _tprintf в Visual Studio 2013? - c, visual-studio-2013, unicode

Как да използвате stdint типове с _tprintf в Visual Studio 2013? - c, визуално-студио-2013, unicode

Вземете следния пример:

char* fileName = "C:\windows\system32\kernel32.dll";
uint32_t fileSize = 1163264;
printf("The size of %s is %"PRIu32"n", fileName, fileSize);

Всичко е наред, сега, ако искаме прозрачна Unicode поддръжка чрез tchar.h кодът ще изглежда така:

TCHAR* fileName = _T("C:\windows\system32\kernel32.dll");
uint32_t fileSize = 1163264;
_tprintf(_T("The size of %s is %")_T(PRIu32)_T("n"), fileName, fileSize);

Това работи, ако е unicode не дефинирани. Въпреки това, ако unicode е дефиниран, компилаторът прекъсва със следната грешка:

error C2308: concatenating mismatched strings
Concatenating wide "The size of %s is %l" with narrow "u"

Сега гледам в Microsoft inttypes.h виждам:

...
#define _PFX_32  "l"
...
#define PRIu32       _PFX_32 "u"

Което означава, че _T(PRIu32) в горния пример решава да:

_T("l" "u")

... която не може да работи, разбира се и обяснява правилната грешка при съставянето.

Така че въпросът ми е как Microsoft си представя, че използваме техните inttypes.h определя с _tprintf?

Отговори:

3 за отговор № 1

Според1 към текущия стандарт C, само един отсимволните последователности (прочетени като: низ) трябва да са с представка от кодиращ префикс, а останалите да бъдат третирани така, че да имат един и същ префикс и да са свързани в един единствен низ.

Префиксът за кодиране се определя от макроса _T. Той ще се реши до нищо, ако UNICODE не е дефиниран, в противен случай ще го прибави L на аргумента.

Решението би било да се използва макроса _T на първия низ, а на останалите няма макрос и те ще използват едно и също кодиране:

_tprintf(_T("The size of %s is %") PRIu32 "n", fileName, fileSize);

Но версията на Visual Studio, която използвате, не е съвместима с C99, така че тази функция липсва. Изглежда, че това е било поправено във Visual Studio 2015.

Същото използване е показано в примера2 в стандарта.


1 (Цитирано от: ISO / IEC 9899: 201x 6.4.5 Струнни литерали 5)
В транслация фаза 6, многобайтовия характерпоследователности, определени от всяка последователност от символите на съседни символи и идентични с префикс символни символи се свързват в a единична многобайтова символна последователност. Ако някой от символите има префикс за кодиране, получената многобайтова символна последователност се третира като имаща същия префикс; в противен случай се третира като буквален символен низ. Дали ли е различен префикс с широк литерал жетоните могат да бъдат свързани и ако е така, третирането на получения мултибайтов характер последователността са дефинирани за изпълнение.

2 (Цитирано от: ISO / IEC 9899: 201x 7.8.1 Макроси за спецификатори на формат 7)
wprintf(L"The largest integer value is %020" PRIxMAX "n", i);