formattazione printf () per hex


192

Si tratta di una query più curiosa di una domanda importante, ma perché quando si stampa un esadecimale come numero di 8 cifre con zeri iniziali, questo %#08Xnon visualizza lo stesso risultato di 0x%08X?

Quando provo a usare il primo, il 08flag di formattazione viene rimosso e non funziona solo con 8.

Ancora una volta ero solo curioso.


3
Intendi 0x%.8X? Quello sarà il piombo-riempimento con zeri. ( 0xè solo un preambolo, ma probabilmente lo sai già).
WhozCraig,

Risposte:


283

La #parte ti dà un 0xnella stringa di output. Il 0e il xconteggio contro i tuoi "8" caratteri elencati nella 08parte. Devi chiedere 10 caratteri se vuoi che sia lo stesso.

int i = 7;

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

Anche la modifica del caso di x, influisce sull'involucro dei caratteri emessi.

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

La linea superiore produce 14F0x00000007 per me. Il secondo e il terzo lavoro come scritto.
quantumpotato,

@quantumpotato - È ... strano. La prima e la terza riga sono identiche ad eccezione del numero di 0 che dovrebbero produrre. Qual è stato il tuo compilatore / sistema / linea di codice che ha prodotto questo? Hai avuto qualche riga che procede a quella stampata 14F?
Mike,

19
Si noti che se i = 0;, le versioni che utilizzano %#non includeranno il 0xprefisso.
Jonathan Leffler,

ma che dire dell'esagono: 0x43A66C31C68491C0 Ho provato quanto segue: __int64 int64 = 0x43A66C31C68491C0; printf_s ("% # 15X% d", int64, int64); Ma l'output è 0XC68491C0, non 0x43A66C31C68491C0
123,

Circa l'esagono 0x43A66C31C68491C0 sopra, l'ho risolto, la soluzione è 0x% I64X, non% # 15X
123liam

53

Lo "0x" conta per il conteggio di otto caratteri. Hai bisogno "%#010x".

Si noti che #non senza aggiungere il 0x per 0 - il risultato sarà 0000000000- quindi probabilmente in realtà dovrebbe semplicemente usare "0x%08x"comunque.


34

La %#08Xconversione deve precedere il valore con 0X; quello è richiesto dalla norma. Non ci sono prove nello standard che ciò #dovrebbe alterare il comportamento della 08parte della specifica, tranne per il fatto che il 0Xprefisso viene conteggiato come parte della lunghezza (quindi potresti volerlo / usarlo %#010X. Se, come me, ti piace il tuo esagono presentato come 0x1234CDEF, quindi è necessario utilizzare 0x%08Xper ottenere il risultato desiderato. È possibile utilizzare %#.8Xe che dovrebbe anche inserire gli zero iniziali.

Prova le variazioni sul seguente codice:

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

Su un computer RHEL 5 e anche su Mac OS X (10.7.5), l'output era:

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

Sono un po 'sorpreso dal trattamento di 0; Non sono chiaro il motivo per cui il 0Xprefisso viene omesso, ma con due sistemi separati che lo fanno, deve essere standard. Conferma i miei pregiudizi contro l' #opzione.


Il trattamento di zero è secondo lo standard.

ISO / IEC 9899: 2011 §7.21.6.1 La fprintffunzione

¶6 I caratteri della bandiera e il loro significato sono:
...
#Il risultato viene convertito in una "forma alternativa". ... Per x(o X) la conversione, un risultato diverso da zero ha 0x(o 0X) preceduto. ...

(Enfasi aggiunta.)


Si noti che l'utilizzo %#Xutilizzerà lettere maiuscole per le cifre esadecimali e 0Xcome prefisso; usando %#xutilizzerà lettere minuscole per le cifre esadecimali e 0xcome prefisso. Se si preferisce 0x, come le lettere di prefisso e minuscole, è necessario il codice 0xa parte: 0x%X. Altri modificatori di formato possono essere aggiunti, se necessario, ovviamente.

Per stampare gli indirizzi, utilizzare l' <inttypes.h>intestazione, il uintptr_ttipo e la PRIXPTRmacro di formato:

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

Esempio di output:

Address 0x7FFEE5B29428

Scegli il tuo veleno sulla lunghezza: trovo che una precisione di 12 funzioni bene per gli indirizzi su un Mac che esegue macOS. In combinazione con il .per specificare la precisione minima (cifre), formatta gli indirizzi in modo affidabile. Se imposti la precisione su 16, le 4 cifre extra sono sempre 0 nella mia esperienza sul Mac, ma c'è sicuramente un caso da fare per usare 16 invece di 12 nel codice portatile a 64 bit (ma useresti 8 per Codice a 32 bit).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.