printf () format untuk hex

191

Ini lebih merupakan pertanyaan yang aneh daripada pertanyaan penting, tetapi mengapa saat mencetak hex sebagai angka 8 digit dengan angka nol di depan, apakah ini %#08XTidak menampilkan hasil yang sama 0x%08X?

Ketika saya mencoba menggunakan yang pertama, 08bendera pemformatan dihapus, dan itu tidak berfungsi dengan adil 8.

Sekali lagi saya hanya ingin tahu.

wsmccusker
sumber
3
Apakah yang Anda maksud 0x%.8X? Itu akan memimpin-isi dengan nol. ( 0xitu hanya basa-basi, tetapi Anda mungkin sudah tahu itu).
WhozCraig

Jawaban:

283

Bagian #memberi Anda 0xdalam string output. The 0dan xhitungan terhadap karakter "8" Anda tercantum di 08bagian. Anda perlu meminta 10 karakter jika ingin sama.

int i = 7;

printf("%#010x\n", i);  // gives 0x00000007
printf("0x%08x\n", i);  // gives 0x00000007
printf("%#08x\n", i);   // gives 0x000007

Juga mengubah kasus x, mempengaruhi casing karakter yang dihasilkan.

printf("%04x", 4779); // gives 12ab
printf("%04X", 4779); // gives 12AB
Mike
sumber
Output baris atas 14F0x00000007 untuk saya. Karya kedua dan ketiga seperti yang ditulis.
quantumpotato
@quantumpotato - Itu ... aneh. Baris pertama dan ketiga identik dengan pengecualian jumlah 0 yang harus mereka hasilkan. Apa kompiler / sistem / jalur kode Anda yang menghasilkan ini? Apakah Anda memiliki garis melanjutkan yang dicetak 14F?
Mike
19
Perhatikan bahwa jika i = 0;, versi yang menggunakan %#tidak akan menyertakan 0xawalan.
Jonathan Leffler
tapi bagaimana dengan hex: 0x43A66C31C68491C0 Saya telah mencoba yang berikut ini: __int64 int64 = 0x43A66C31C68491C0; printf_s ("% # 15X% d", int64, int64); Tetapi hasilnya adalah 0XC68491C0, bukan 0x43A66C31C68491C0
123iamking
Tentang hex 0x43A66C31C68491C0 di atas, saya telah menyelesaikannya, solusinya adalah 0x% I64X, bukan% # 15X
123iamking
53

"0x" diperhitungkan terhadap delapan karakter. Kamu butuh "%#010x".

Perhatikan bahwa #tidak tidak menambahkan 0x untuk 0 - hasilnya akan 0000000000- sehingga Anda mungkin sebenarnya hanya harus menggunakan "0x%08x"pula.

Random832
sumber
34

The %#08Xkonversi harus mendahului nilai dengan 0X; yang dibutuhkan oleh standar. Tidak ada bukti dalam standar bahwa #harus mengubah perilaku 08bagian dari spesifikasi kecuali bahwa 0Xawalan dihitung sebagai bagian dari panjang (jadi Anda mungkin ingin / perlu menggunakan %#010X. Jika, seperti saya, Anda suka hex Anda disajikan sebagai 0x1234CDEF, maka Anda harus menggunakan 0x%08Xuntuk mencapai hasil yang diinginkan. Anda dapat menggunakan %#.8Xdan itu juga harus memasukkan nol terkemuka.

Coba variasi pada kode berikut:

#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);
}

Pada mesin RHEL 5, dan juga pada Mac OS X (10.7.5), outputnya adalah:

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

Saya sedikit terkejut dengan perlakuan 0; Saya tidak jelas mengapa 0Xawalan dihilangkan, tetapi dengan dua sistem terpisah melakukannya, itu harus standar. Ini menegaskan prasangka saya terhadap #opsi tersebut.


Perlakuan nol sesuai dengan standar.

ISO / IEC 9899: 2011 §7.21.6.1 The fprintfFungsi

¶6 Karakter bendera dan artinya adalah:
...
#Hasilnya dikonversi ke "bentuk alternatif". ... Untuk x(atau X) konversi, hasil bukan nol telah 0x(atau 0X) diawali dengan itu. ...

(Penekanan ditambahkan.)


Perhatikan bahwa menggunakan %#Xakan menggunakan huruf besar untuk digit hex dan 0Xsebagai awalan; menggunakan %#xakan menggunakan huruf kecil untuk digit hex dan 0xsebagai awalan. Jika Anda lebih suka 0xsebagai awalan dan atas-kasus surat, Anda harus kode 0xsecara terpisah: 0x%X. Pengubah format lain dapat ditambahkan sesuai kebutuhan, tentu saja.

Untuk mencetak alamat, gunakan <inttypes.h>tajuk dan uintptr_tjenis dan PRIXPTRformat makro:

#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;
}

Contoh output:

Address 0x7FFEE5B29428

Pilih racun Anda pada panjang - Saya menemukan bahwa ketepatan 12 bekerja dengan baik untuk alamat pada Mac yang menjalankan MacOS. Dikombinasikan dengan .untuk menentukan presisi minimum (digit), ini memformat alamat dengan andal. Jika Anda mengatur presisi ke 16, tambahan 4 digit selalu 0 dalam pengalaman saya di Mac, tetapi pasti ada kasus yang harus dibuat untuk menggunakan 16 bukannya 12 dalam kode 64-bit portabel (tetapi Anda akan menggunakan 8 untuk Kode 32-bit).

Jonathan Leffler
sumber