16進数のprintf()のフォーマット


190

これは重要な質問というよりは奇妙なクエリですが、16進数を先頭に0を付けた8桁の数値%#08Xとして出力すると、同じ結果が表示され0x%08Xないのはなぜですか。

前者を使用しようとすると、08フォーマットフラグが削除され、だけでは機能しません8

再び私はただ気になった。


3
もしかして0x%.8X?それゼロでリードフィルされます。(これ0xは単なるプリアンブルですが、おそらくすでにご存じでしょう)。
WhozCraig 2013

回答:


282

#一部はあなた与え0x、出力文字列に。0xに記載されているあなたの「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を出力します。書かれたとおりの2番目と3番目の作品。
クォンタムポテト2014年

@quantumpotato-それは...奇妙です。1行目と3行目は、生成する0の数を除いて同じです。これを生み出したコンパイラ/システム/コード行は何でしたか?印刷した行に続く行はありました14Fか?
マイク

18
の場合i = 0;、使用%#するバージョンには0xプレフィックスが含まれないことに注意してください。
ジョナサンレフラー2014年

しかし、16進数はどうですか:0x43A66C31C68491C0私は以下を試しました:__int64 int64 = 0x43A66C31C68491C0; printf_s( "%#15X%d"、int64、int64); しかし、出力は0XC68491C0ではなく、0x43A66C31C68491C0
123iamking

上記の16進数0x43A66C31C68491C0について、解決しました。解決策は0x%I64Xで、%#15Xではありません
123iamking

52

「0x」は8文字カウントにカウントされます。あなたが必要"%#010x"です。

0xに0xを追加#ないことに注意してください-結果は0000000000-になるので、おそらく実際には"0x%08x"とにかく使用する必要があります。


34

%#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プレフィックスが省略されているのかははっきりしませんが、2つの別々のシステムがそれを行っているので、それは標準でなければなりません。#オプションに対する私の偏見を裏付けるものです。


ゼロの扱いは標準に従います。

ISO / IEC 9899:2011 §7.21.6.1 機能fprintf

¶6フラグ文字とその意味は次のとおり
です。...
#結果は「代替形式」に変換されます。... x(またはX)変換の場合、ゼロ以外の結果には0x(または0X)が前に付きます。...

(強調が追加されました。)


を使用%#Xすると、16進数と0Xプレフィックスとして大文字が使用されることに注意してください。を使用%#xすると、16進数の小文字と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

長さで毒を選択します— macOSを実行しているMacのアドレスには12の精度が適切に機能します。と組み合わせて.最小精度(桁)を指定し、アドレスを確実にフォーマットします。Macでの私の経験では、精度を16に設定すると、余分な4桁は常に0になりますが、ポータブル64ビットコードでは12ではなく16を使用するケースが確かにあります(ただし、 32ビットコード)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.