%#08XПеретворення має передувати значення з 0X; що вимагається стандартом. У стандарті немає жодних доказів того, що #слід змінити поведінку 08частини специфікації, за винятком того, що 0Xпрефікс зараховується до частини довжини (так що ви можете хотіти / потрібно використовувати %#010X. Якщо, як я, вам подобається, що ваш шестигранник представлений як 0x1234CDEF, тоді вам доведеться скористатися, 0x%08Xщоб досягти бажаного результату. Ви можете використати, %#.8Xа також слід вставити провідні нулі.
Спробуйте варіанти наступного коду:
#include <stdio.h>
int main(void)
{
int j = 0;
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
for (int i = 0; i < 8; i++)
{
j = (j << 4) | (i + 6);
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
}
return(0);
}
На машині RHEL 5, а також на Mac OS X (10.7.5), вихід:
0x00000000 = 00000000 = 00000000 = 0000000000
0x00000006 = 0X000006 = 0X00000006 = 0x00000006
0x00000067 = 0X000067 = 0X00000067 = 0x00000067
0x00000678 = 0X000678 = 0X00000678 = 0x00000678
0x00006789 = 0X006789 = 0X00006789 = 0x00006789
0x0006789A = 0X06789A = 0X0006789A = 0x0006789a
0x006789AB = 0X6789AB = 0X006789AB = 0x006789ab
0x06789ABC = 0X6789ABC = 0X06789ABC = 0x06789abc
0x6789ABCD = 0X6789ABCD = 0X6789ABCD = 0x6789abcd
Я трохи здивований лікуванню 0; Мені не ясно, чому 0Xпрефікс пропущено, але якщо це роблять дві окремі системи, він повинен бути стандартним. Це підтверджує мої забобони щодо #варіанту.
Обробка нуля відповідає стандарту.
¶6 Символи прапора та їх значення такі:
...
#Результат перетворюється на "альтернативну форму". ... Для x(або X) перетворення, ненульовий результат має 0x(або 0X) префікс до нього. ...
(Наголос додано.)
Зауважте, що при використанні %#Xвикористовуються великі літери для шістнадцяткових цифр і 0Xяк префікса; використання %#xбуде використовувати малі літери для шістнадцяткових цифр і 0xяк префікс. Якщо ви віддаєте перевагу в 0xякості префікса і прописних літер, ви повинні коді 0xокремо: 0x%X. Звичайно, за потреби можна додати інші модифікатори формату.
Для друку адрес використовуйте <inttypes.h>заголовок, uintptr_tтип та PRIXPTRмакрос формату:
#include <inttypes.h>
#include <stdio.h>
int main(void)
{
void *address = &address; // &address has type void ** but it converts to void *
printf("Address 0x%.12" PRIXPTR "\n", (uintptr_t)address);
return 0;
}
Приклад виводу:
Address 0x7FFEE5B29428
Вибирайте свою отруту по довжині - я вважаю, що точність 12 добре працює для адрес на Mac, що працює під управлінням macOS. У поєднанні з .заданою мінімальною точністю (цифрами) він форматує адреси надійно. Якщо ви встановите точність до 16, додаткові 4 цифри завжди є 0 на моєму досвіді на Mac, але, безумовно, слід застосувати випадки використання 16 замість 12 у портативному 64-бітному коді (але ви б використовували 8 для 32-бітний код).
0x%.8X? Це буде призводити заповнюються нулями. (0xце лише преамбула, але, ймовірно, про це вже знаєте).