định dạng printf () cho hex


190

Đây là một truy vấn tò mò hơn là một câu hỏi quan trọng, nhưng tại sao khi in hex dưới dạng số có 8 chữ số với các số 0 đứng đầu, điều này %#08Xkhông hiển thị kết quả giống như 0x%08X?

Khi tôi cố gắng sử dụng cái trước, 08cờ định dạng sẽ bị xóa và nó không hoạt động với chỉ 8.

Một lần nữa tôi chỉ tò mò.


3
Ý bạn là 0x%.8Xsao Điều đó sẽ dẫn đầy với số không. ( 0xđây chỉ là một lời mở đầu, nhưng có khả năng bạn đã biết về điều đó).
WhozCraig

Câu trả lời:


282

Phần #cung cấp cho bạn một 0xtrong chuỗi đầu ra. Số lượng 0xsố đếm so với các ký tự "8" của bạn được liệt kê trong 08phần. Bạn cần yêu cầu 10 ký tự nếu bạn muốn nó giống nhau.

int i = 7;

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

Cũng thay đổi trường hợp x, ảnh hưởng đến vỏ của các nhân vật xuất ra.

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

Dòng đầu ra 14F0x00000007 cho tôi. Công việc thứ hai và thứ ba như được viết.
quantumpotato

@quantumpotato - Thật là ... kỳ quặc. Dòng thứ nhất và thứ ba giống hệt nhau ngoại trừ số 0 mà chúng nên tạo. Trình biên dịch / hệ thống / dòng mã của bạn đã tạo ra cái này là gì? Bạn đã có bất kỳ dòng tiến hành một trong những in 14F?
Mike

18
Lưu ý rằng nếu i = 0;, các phiên bản sử dụng %#sẽ không bao gồm 0xtiền tố.
Jonathan Leffler

nhưng làm thế nào về hex: 0x43A66C31C68491C0 Tôi đã thử như sau: __int64 int64 = 0x43A66C31C68491C0; printf_s ("% # 15X% d", int64, int64); Nhưng đầu ra là 0XC68491C0, không phải 0x43A66C31C68491C0
123iamking

Giới thiệu về hex 0x43A66C31C68491C0 ở trên, tôi đã giải quyết nó, giải pháp là 0x% I64X, không phải% # 15X
123iamking

52

"0x" được tính vào số lượng tám ký tự. Bạn cần "%#010x".

Lưu ý rằng #không không gắn 0x 0 - kết quả sẽ là 0000000000- vì vậy bạn có thể thực sự chỉ nên sử dụng "0x%08x"anyway.


34

Việc %#08Xchuyển đổi phải đi trước giá trị với 0X; đó là yêu cầu của tiêu chuẩn. Không có bằng chứng nào trong tiêu chuẩn cho thấy #nên thay đổi hành vi của 08một phần của đặc tả ngoại trừ 0Xtiền tố được tính là một phần của độ dài (vì vậy bạn có thể muốn / cần sử dụng %#010X. Nếu, như tôi, bạn thích hex của bạn được trình bày như 0x1234CDEF, sau đó bạn phải sử dụng 0x%08Xđể đạt được kết quả mong muốn. Bạn có thể sử dụng %#.8Xvà điều đó cũng nên chèn các số 0 đứng đầu.

Hãy thử các biến thể trên mã sau đây:

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

Trên máy RHEL 5 và cả trên Mac OS X (10.7.5), đầu ra là:

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

Tôi hơi ngạc nhiên khi điều trị 0; Tôi không rõ tại sao 0Xtiền tố bị bỏ qua, nhưng với hai hệ thống riêng biệt làm điều đó, nó phải là tiêu chuẩn. Nó xác nhận định kiến ​​của tôi chống lại #lựa chọn.


Việc điều trị bằng 0 là theo tiêu chuẩn.

ISO / IEC 9899: 2011 §7.21.6.1 Các fprintfchức năng

6 Các ký tự cờ và ý nghĩa của chúng là:
...
#Kết quả được chuyển đổi thành "dạng thay thế". ... Đối với x(hoặc X) chuyển đổi, một kết quả khác không0x(hoặc 0X) tiền tố với nó. ...

(Nhấn mạnh thêm.)


Lưu ý rằng việc sử dụng %#Xsẽ sử dụng các chữ cái viết hoa cho các chữ số hex và 0Xlàm tiền tố; việc sử dụng %#xsẽ sử dụng các chữ cái viết thường cho các chữ số hex và 0xlàm tiền tố. Nếu bạn thích 0xlàm tiền tố và chữ in hoa, bạn phải mã 0xriêng : 0x%X. Các sửa đổi định dạng khác có thể được thêm vào khi cần thiết, tất nhiên.

Để in địa chỉ, sử dụng <inttypes.h>tiêu đề và uintptr_tloại và PRIXPTRmacro định dạng:

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

Ví dụ đầu ra:

Address 0x7FFEE5B29428

Chọn chất độc của bạn theo độ dài - Tôi thấy rằng độ chính xác 12 hoạt động tốt cho các địa chỉ trên máy Mac chạy macOS. Kết hợp với .để chỉ định độ chính xác tối thiểu (chữ số), nó định dạng địa chỉ một cách đáng tin cậy. Nếu bạn đặt độ chính xác thành 16, 4 chữ số thêm luôn là 0 theo kinh nghiệm của tôi trên Mac, nhưng chắc chắn sẽ có trường hợp sử dụng 16 thay vì 12 trong mã 64 bit di động (nhưng bạn sẽ sử dụng 8 cho Mã 32 bit).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.