Saya mencoba membaca dalam sebaris karakter, lalu mencetak karakter yang setara heksadesimal.
Misalnya, jika saya memiliki string yaitu "0xc0 0xc0 abc123"
, di mana 2 karakter pertama c0
dalam hex dan karakter yang tersisa abc123
dalam ASCII, maka saya harus mendapatkan
c0 c0 61 62 63 31 32 33
Namun, printf
menggunakan %x
memberi saya
ffffffc0 ffffffc0 61 62 63 31 32 33
Bagaimana cara mendapatkan keluaran yang saya inginkan tanpa "ffffff"
? Dan mengapa hanya c0 (dan 80) yang memiliki karakter ffffff
, tetapi tidak karakter lainnya?
"\xc0\xc0abc123"
Jawaban:
Anda melihat
ffffff
karenachar
ditandatangani di sistem Anda. Di C, fungsi vararg sepertiprintf
akan mempromosikan semua bilangan bulat yang lebih kecil dariint
padaint
. Karenachar
merupakan integer (integer bertanda 8-bit dalam kasus Anda), karakter Anda sedang dipromosikanint
melalui ekstensi tanda.Sejak
c0
dan80
memiliki 1-bit terdepan (dan negatif sebagai integer 8-bit), mereka diperpanjang tanda sementara yang lain dalam sampel Anda tidak.Inilah solusinya:
Ini akan menutupi bit atas dan menyimpan hanya 8 bit bawah yang Anda inginkan.
sumber
unsigned char
adalah satu instruksi yang lebih kecil di gcc4.6 untuk x86-64 ...x
membutuhkan tipe unsigned, tetapi ch dipromosikan menjadi int. Kode yang benar hanya akan dilemparkan ch untuk unsigned, atau menggunakan cor untuk unsigned char dan specifier yang:hhx
.printf("%x", 0)
, tidak ada yang dicetak.printf("%.2x", 0);
yang akan meningkatkan karakter minimum yang ditarik ke 2. Untuk menyetel maks, tambahkan. dengan nomor. Misalnya, Anda dapat memaksa hanya 2 karakter yang ditarik dengan melakukanprintf("%2.2x", 0);
printf("%x", ch & 0xff)
harus lebih baik daripada hanya menggunakanprintf("%02hhX", a)
seperti dalam jawaban @ brutal_lobster ?Memang, ada jenis konversi ke int. Anda juga bisa memaksa tipe menjadi char dengan menggunakan% hhx specifier.
Dalam kebanyakan kasus, Anda mungkin ingin mengatur panjang minimum juga untuk mengisi karakter kedua dengan nol:
ISO / IEC 9899: 201x mengatakan:
sumber
Anda dapat membuat karakter unsigned:
Mencetaknya akan memberi
C5
dan tidakffffffc5
.Hanya karakter yang lebih besar dari 127 yang dicetak dengan
ffffff
karena negatif (karakter ditandatangani).Atau Anda dapat melakukan cast
char
sambil mencetak:sumber
Anda mungkin menyimpan nilai 0xc0 dalam
char
variabel, yang mungkin merupakan tipe bertanda, dan nilai Anda negatif (kumpulan bit paling signifikan). Kemudian, ketika mencetak, itu diubah menjadiint
, dan untuk menjaga kesetaraan semantik, kompilator mengisi byte ekstra dengan 0xff, sehingga negatifint
akan memiliki nilai numerik yang sama dari negatif Andachar
. Untuk memperbaikinya, cukup transmisikan keunsigned char
saat mencetak:sumber
Anda bisa menggunakan
hh
untuk memberitahuprintf
bahwa argumennya adalah unsigned char. Gunakan0
untuk mendapatkan bantalan nol dan2
untuk mengatur lebar ke 2.x
atauX
untuk karakter hex huruf besar / kecil.Sunting : Jika pembaca prihatin tentang pernyataan 2501 bahwa ini bukan penentu format yang 'benar', saya sarankan mereka membaca
printf
tautan itu lagi. Secara khusus:Adapun maksudnya tentang signed vs unsigned, dalam hal ini tidak masalah karena nilainya harus selalu positif dan mudah sesuai dengan int yang ditandatangani. Tidak ada penentu format heksideximal bertanda.
Edit 2 : (edisi "ketika-mengakui-Anda-salah"):
Jika Anda membaca standar C11 yang sebenarnya pada halaman 311 (329 PDF) Anda menemukan:
sumber
inttypes.h
char
danunsigned char
dipromosikan menjadiint
) [ en.cppreference.com/w/cpp/language/variadic_arguments] . Anda hanya perlu menggunakan penentu PRI untuk hal-hal yang tidak sesuai dengan platform Andaint
- misunsigned int
.%x
benar untuk unsigned int bukan int. Jenis char dan unsigned char dipromosikan menjadi int. Selain itu, tidak ada jaminan bahwa uint8_t didefinisikan sebagai unsigned char.Anda mungkin mencetak dari array karakter yang ditandatangani. Cetak dari array karakter yang tidak bertanda tangan atau tutupi nilainya dengan 0xff: misalnya ar [i] & 0xFF. Nilai c0 diberi tanda diperpanjang karena bit (tanda) tinggi diset.
sumber
Coba sesuatu seperti ini:
Yang menghasilkan ini:
sumber