การจัดรูปแบบ printf () สำหรับฐานสิบหก


191

นี่เป็นคำถามที่น่าสนใจมากกว่าคำถามสำคัญ แต่ทำไมเมื่อพิมพ์เลขฐานสิบหกเป็นตัวเลข 8 หลักพร้อมเลขศูนย์นำหน้าสิ่งนี้จะ%#08Xไม่แสดงผลลัพธ์เดียวกัน0x%08Xหรือไม่

เมื่อฉันพยายามใช้อดีต 088ธงการจัดรูปแบบจะถูกลบออกและมันไม่ได้ทำงานที่มีเพียง

อีกครั้งฉันแค่อยากรู้


3
คุณหมายถึง0x%.8Xอะไร ที่จะนำไปสู่การเติมด้วยศูนย์ ( 0xนี่เป็นเพียงคำนำ แต่คุณก็รู้อยู่แล้ว)
WhozCraig

คำตอบ:


283

#ส่วนหนึ่งจะช่วยให้คุณ0xในสตริงเอาท์พุท 0และxนับต่อ "8" ตัวละครของคุณอยู่ใน08ส่วนหนึ่ง คุณต้องขอ 10 ตัวอักษรหากคุณต้องการให้เหมือนกัน

int i = 7;

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

การเปลี่ยนเคสของจะxส่งผลต่อการส่งออกของอักขระที่ส่งออก

printf("%04x", 4779); // gives 12ab
printf("%04X", 4779); // gives 12AB

บรรทัดด้านบนให้ผลลัพธ์ 14F0x00000007 สำหรับฉัน งานที่สองและสามตามที่เขียนไว้
quantumpotato

@quantumpotato - นั่นคือ ... แปลก บรรทัดแรกและบรรทัดที่สามเหมือนกันยกเว้นจำนวน 0 ที่ควรสร้าง คอมไพเลอร์ / ระบบ / บรรทัดของโค้ดที่ผลิตสิ่งนี้คืออะไร? คุณมีบรรทัดใดที่ดำเนินการกับบรรทัดที่พิมพ์14Fหรือไม่?
Mike

19
โปรดทราบว่าหากi = 0;เวอร์ชันที่ใช้%#จะไม่รวม0xคำนำหน้า
Jonathan Leffler

แต่วิธีการเกี่ยวกับ hex: 0x43A66C31C68491C0 ฉันได้ลองต่อไปนี้: __int64 int64 = 0x43A66C31C68491C0; printf_s ("% # 15X% d", int64, int64); แต่ผลลัพธ์คือ 0XC68491C0 ไม่ใช่ 0x43A66C31C68491C0
123iamking

เกี่ยวกับ hex 0x43A66C31C68491C0 ด้านบนฉันได้แก้แล้วการแก้คือ 0x% I64X ไม่ใช่% # 15X
123iamking

53

ตัวอักษร "0x" จะนับรวมตัวอักษรแปดตัว "%#010x"คุณจำเป็นต้อง

โปรดทราบว่า#ไม่ได้ผนวก 0x เป็น 0 - ผลที่ได้จะเป็น0000000000- ดังนั้นคุณอาจจะจริงก็ควรจะใช้"0x%08x"อยู่แล้ว


34

การ%#08Xแปลงจะต้องนำหน้าค่าด้วย0X; ที่เป็นที่ต้องการโดยมาตรฐาน ไม่มีหลักฐานในมาตรฐานที่#ควรเปลี่ยนพฤติกรรมของ08ส่วนของสเปคยกเว้นว่า0Xคำนำหน้านั้นนับเป็นส่วนหนึ่งของความยาว (ดังนั้นคุณอาจต้องการ / จำเป็นต้องใช้%#010Xถ้าเช่นฉันคุณชอบ hex ของคุณแสดงเป็น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คำนำหน้าถูกละเว้น แต่ด้วยระบบที่แยกกันสองระบบที่ทำมันจึงต้องเป็นมาตรฐาน มันยืนยันอคติของฉันกับ#ตัวเลือก


การรักษาศูนย์เป็นไปตามมาตรฐาน

มาตรฐาน ISO / IEC 9899: 2011 §7.21.6.1 ฟังก์ชั่นfprintf

¶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 บิต)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.