Sintaks spesifikasi format: printf dan wprintf fungsi

Berbagai printf fungsi dan wprintf mengambil string format dan argumen opsional dan menghasilkan urutan karakter yang diformat untuk output. String format berisi nol atau lebih direktif, yang merupakan karakter harfiah untuk spesifikasi konversi output atau yang dikodekan yang menjelaskan cara memformat argumen dalam output. Artikel ini menguraikan sintaks yang digunakan untuk mengodekan spesifikasi konversi dalam string format. Untuk daftar fungsi-fungsi ini, lihat Streaming I/O.

Spesifikasi konversi terdiri dari bidang opsional dan wajib dalam formulir ini:

%[flags][width][.presisi][ukuran]type

Setiap bidang spesifikasi konversi adalah karakter atau angka yang menandakan opsi format atau penentu konversi tertentu. Bidang jenis yang diperlukan menentukan jenis konversi yang akan diterapkan ke argumen. Bidang bendera, lebar, dan presisi opsional mengontrol aspek format lain seperti spasi atau nol di depan, pembenaran, dan presisi yang ditampilkan. Bidang ukuran menentukan ukuran argumen yang digunakan dan dikonversi.

Spesifikasi konversi dasar hanya berisi tanda persen dan karakter jenis . Misalnya, %s menentukan konversi string. Untuk mencetak karakter tanda persen, gunakan %%. Jika tanda persen diikuti oleh karakter yang tidak memiliki arti sebagai bidang format, handler parameter yang tidak valid dipanggil. Untuk informasi selengkapnya, lihat Validasi parameter.

Penting

Untuk keamanan dan stabilitas, pastikan bahwa string spesifikasi konversi format tidak ditentukan pengguna akhir. Misalnya, pertimbangkan program yang meminta pengguna untuk memasukkan nama dan menyimpan input dalam variabel string yang bernama user_name. Untuk mencetak user_name, jangan pernah lakukan ini:

printf( user_name ); /* Danger! If user_name contains "%s", program will crash */

Sebagai gantinya, lakukan ini:

printf( "%s", user_name );

Catatan

Di Visual Studio 2015 Dan printfscanf keluarga fungsi dinyatakan sebagai inline dan dipindahkan ke <stdio.h> header dan <conio.h> . Jika Anda memigrasikan kode lama, Anda mungkin melihat LNK2019 sehubungan dengan fungsi-fungsi ini. Untuk informasi selengkapnya, lihat Riwayat perubahan Visual C++ 2003 - 2015.

Penentu konversi jenis

Karakter penentu konversi jenis menentukan apakah akan menginterpretasikan argumen yang sesuai sebagai karakter, string, penunjuk, bilangan bulat, atau angka floating-point. Karakter jenis adalah satu-satunya bidang spesifikasi konversi yang diperlukan, dan muncul setelah bidang opsional apa pun.

Argumen yang mengikuti string format ditafsirkan sesuai dengan karakter jenis yang sesuai dan awalan ukuran opsional. Konversi untuk jenis char karakter dan wchar_t ditentukan dengan menggunakan c atau C, dan string byte tunggal dan multi-byte atau karakter lebar ditentukan dengan menggunakan s atau S, tergantung pada fungsi pemformatan mana yang digunakan. Argumen karakter dan string yang ditentukan dengan menggunakan c dan s ditafsirkan sebagai char dan char* oleh printf fungsi keluarga, atau sebagai wchar_t dan wchar_t* oleh wprintf fungsi keluarga. Argumen karakter dan string yang ditentukan dengan menggunakan C dan S ditafsirkan sebagai wchar_t dan wchar_t* oleh printf fungsi keluarga, atau sebagai char dan char* oleh wprintf fungsi keluarga. Perilaku ini khusus Microsoft. Untuk alasan historis, wprintf fungsi menggunakan c dan s untuk merujuk ke wchar_t karakter, dan C menentukan S karakter sempit.

Jenis bilangan bulat seperti short, , longint, long long, dan variannyaunsigned, ditentukan dengan menggunakan d, , i, o, ux, dan X. Jenis floating-point seperti float, , doubledan long double, ditentukan dengan menggunakan a, , A, Ee, f, F, g, dan G. Secara default, kecuali dimodifikasi oleh awalan ukuran , argumen bilangan bulat dikoerasi untuk int mengetik, dan argumen floating-point dikoerasikan ke double. Pada sistem 64-bit, adalah int nilai 32-bit; jadi, bilangan bulat 64-bit akan dipotong ketika diformat untuk output kecuali awalan ll ukuran atau I64 digunakan. Jenis penunjuk yang ditentukan dengan p menggunakan ukuran penunjuk default untuk platform.

Catatan

Khusus Microsoft:
Karakter Z jenis, dan perilaku ckarakter , , Cs, dan S jenis saat digunakan dengan printf fungsi dan wprintf , adalah ekstensi Microsoft. Standar ISO C menggunakan c dan s secara konsisten untuk karakter dan string sempit, dan C dan S untuk karakter dan string yang luas, di semua fungsi pemformatan.

Ketik karakter bidang

Ketik karakter Argumen Format output
c karakter Saat digunakan dengan printf fungsi, menentukan karakter byte tunggal; saat digunakan dengan wprintf fungsi, menentukan karakter yang luas.
C karakter Saat digunakan dengan printf fungsi, menentukan karakter lebar; saat digunakan dengan wprintf fungsi, menentukan karakter byte tunggal.
d Bilangan bulat Bilangan bulat desimal yang ditandatangani.
i Bilangan bulat Bilangan bulat desimal yang ditandatangani.
o Bilangan bulat Bilangan bulat oktal yang tidak ditandatangani.
u Bilangan bulat Bilangan bulat desimal yang tidak ditandatangani.
x Bilangan bulat Bilangan bulat heksadesimal yang tidak ditandatangani; menggunakan "abcdef".
X Bilangan bulat Bilangan bulat heksadesimal yang tidak ditandatangani; menggunakan "ABCDEF".
e Floating-point Nilai yang ditandatangani yang memiliki formulir [-]d.dddde[-+|]dd[d], di mana d adalah satu digit desimal, dddd adalah satu atau beberapa digit desimal tergantung pada presisi yang ditentukan, atau enam secara default, dan dd[d] adalah dua atau tiga digit desimal tergantung pada format output dan ukuran eksponen.
E Floating-point Identik e dengan format kecuali daripada Ee memperkenalkan eksponen.
f Floating-point Nilai yang ditandatangani yang memiliki formulir [-]dddd.dddd, di mana dddd adalah satu atau beberapa digit desimal. Jumlah digit sebelum titik desimal tergantung pada besarnya angka, dan jumlah digit setelah titik desimal tergantung pada presisi yang diminta, atau enam secara default.
F Floating-point Identik dengan f format kecuali bahwa output infinity dan NaN dikapitalisasi.
g Floating-point Nilai yang ditandatangani ditampilkan dalam f format atau e , mana yang lebih ringkas untuk nilai dan presisi yang diberikan. e Format hanya digunakan ketika eksponen nilai kurang dari -4 atau lebih besar dari atau sama dengan argumen presisi. Nol berikutnya dipotong, dan titik desimal hanya muncul jika satu atau beberapa digit mengikutinya.
G Floating-point Identik dengan g format, kecuali bahwa E, bukan e, memperkenalkan eksponen (jika sesuai).
a Floating-point Nilai floating-point presisi ganda heksadesimal yang ditandatangani yang memiliki bentuk [-]0xh.hhhhp[-+|]dd, di mana h.hhhh adalah digit hex (menggunakan huruf kecil) dari mantissa, dan dd adalah satu atau beberapa digit untuk eksponen. Presisi menentukan jumlah digit setelah titik .
A Floating-point Nilai floating-point presisi ganda heksadesimal yang ditandatangani yang memiliki bentuk [-]0Xh.hhhhP[-+|]dd, di mana h.hhhh adalah digit heks (menggunakan huruf besar) dari mantissa, dan dd adalah satu atau beberapa digit untuk eksponen. Presisi menentukan jumlah digit setelah titik .
n Pointer ke bilangan bulat Jumlah karakter yang berhasil ditulis sejauh ini ke aliran atau buffer. Nilai ini disimpan dalam bilangan bulat yang alamatnya diberikan sebagai argumen. Ukuran bilangan bulat yang diarahkan dapat dikontrol oleh prefiks spesifikasi ukuran argumen. Penentu n dinonaktifkan secara default; untuk informasi lihat catatan keamanan penting.
p Jenis penunjuk Tampilkan argumen sebagai alamat dalam digit heksadesimal.
s String Saat digunakan dengan printf fungsi, menentukan string karakter byte tunggal atau multi-byte; saat digunakan dengan wprintf fungsi, menentukan string karakter lebar. Karakter ditampilkan hingga karakter null pertama atau hingga nilai presisi tercapai.
S String Saat digunakan dengan printf fungsi, menentukan string karakter lebar; saat digunakan dengan wprintf fungsi, menentukan string karakter byte tunggal atau multi-byte. Karakter ditampilkan hingga karakter null pertama atau hingga nilai presisi tercapai.
Z ANSI_STRING atau UNICODE_STRING struktur VS 2013 dan yang lebih lama
Ketika alamat ANSI_STRING struktur atau UNICODE_STRING diteruskan sebagai argumen, tampilkan string yang terkandung dalam buffer yang diarahkan ke Buffer bidang struktur. Gunakan awalan w pengubah ukuran untuk menentukan UNICODE_STRING argumen—misalnya, %wZ. Bidang Length struktur harus diatur ke panjang, dalam byte, dari string. Bidang MaximumLength struktur harus diatur ke panjang, dalam byte, dari buffer.

Universal C Runtime (UCRT)
Ada masalah yang diketahui dalam UCRT yang saat ini dipertahankan untuk kompatibilitas. Seperti penentuS, penentu tanpa awalan pengubah ukuran mengacu pada UNICODE_STRING saat menggunakan fungsi pencetakan sempit (seperti printf) dan ANSI_STRING saat menggunakan fungsi pencetakan yang luas (seperti wprintfZ ).
Alih-alih Z, gunakan hZ untuk menentukan ANSI_STRING. wZ (atau lZ) masih dapat digunakan untuk menentukan UNICODE_STRING.

Biasanya, Z karakter jenis hanya digunakan dalam fungsi penelusuran kesalahan driver yang menggunakan spesifikasi konversi, seperti dbgPrint dan kdPrint.

Di Visual Studio 2015 dan versi yang lebih baru, jika argumen yang sesuai dengan penentu konversi floating-point (a, , fAEFeg) Gtidak terbatas, tidak terbatas, atau NaN, output yang diformat sesuai dengan standar C99. Tabel ini mencantumkan output yang diformat:

Nilai Hasil
Tak terbatas inf
NaN Tenang nan
NaN Sinyal nan(snan)
NaN Tidak Terbatas nan(ind)

Salah satu string ini dapat diawali dengan tanda. Jika karakter penentu konversi jenis floating-point adalah huruf kapital, output juga diformat dalam huruf kapital. Misalnya, jika penentu format bukan %F%f, tak terbatas diformat sebagai INF alih-alih inf. Fungsi juga scanf dapat mengurai string ini, sehingga nilai-nilai ini dapat melakukan perjalanan pulang pergi printf dan scanf fungsi.

Sebelum Visual Studio 2015, CRT menggunakan format non-standar yang berbeda untuk output nilai tak terbatas, tidak terbatas, dan NaN:

Nilai Hasil
+ Tak terbatas 1.#INFdigit acak
-Infinity -1.#INFdigit acak
Tidak terbatas (sama dengan NaN yang tenang) digit.#INDdigit acak-digit
NaN digit.#NANdigit acak-digit

Salah satu string ini mungkin telah diawali oleh tanda, dan mungkin telah diformat secara berbeda tergantung pada lebar bidang dan presisi, kadang-kadang dengan efek yang tidak biasa. Misalnya, printf("%.2f\n", INFINITY) cetakan 1.#J karena #INF akan "dibulatkan" hingga dua digit presisi.

Catatan

Jika argumen yang sesuai dengan %s atau , atau Buffer bidang argumen yang sesuai dengan %Z, adalah penunjuk null, "(null%S)" ditampilkan.

Catatan

Dalam semua format eksponensial, jumlah minimum digit eksponen untuk ditampilkan adalah dua, menggunakan tiga hanya jika perlu. Dengan menggunakan fungsi , _set_output_format Anda dapat mengatur jumlah digit yang ditampilkan ke tiga untuk kompatibilitas mundur dengan kode yang ditulis untuk Visual Studio 2013 dan sebelumnya.

Penting

%n Karena formatnya secara inheren tidak aman, format dinonaktifkan secara default. Jika %n ditemui dalam string format, handler parameter yang tidak valid dipanggil, seperti yang dijelaskan dalam Validasi parameter. Untuk mengaktifkan %n dukungan, lihat _set_printf_count_output.

Arahan bendera

Bidang opsional pertama dalam spesifikasi konversi berisi arahan bendera. Bidang ini berisi nol atau lebih karakter bendera yang menentukan output justifikasi dan output kontrol tanda, kosong, nol di depan, titik desimal, dan awalan oktal dan heksadesimal. Lebih dari satu direktif bendera dapat muncul dalam spesifikasi konversi, dan karakter bendera dapat muncul dalam urutan apa pun.

Bendera karakter

Bendera Makna Default
- Rata kiri hasil dalam lebar bidang yang diberikan. Rata kanan.
+ Gunakan tanda (+ atau -) untuk mengawali nilai output jika merupakan jenis yang ditandatangani. Tanda hanya muncul untuk nilai bertanda tangan negatif (-).
0 Jika lebar diawali dengan 0, nol di depan ditambahkan hingga lebar minimum tercapai. Jika keduanya 0 dan - muncul, 0 diabaikan. Jika 0 ditentukan untuk format bilangan bulat (i, , u, x, Xo, ) ddan spesifikasi presisi juga ada—misalnya, %04.d0yang diabaikan. Jika 0 ditentukan untuk a format atau A floating-point, nol di depan diawali ke mantissa, setelah awalan 0x atau 0X . Tidak ada padding.
kosong (' ') Gunakan kosong untuk mengawali nilai output jika ditandatangani dan positif. Kosong diabaikan jika bendera kosong dan + muncul. Tidak ada kosong yang muncul.
# Ketika digunakan dengan oformat , , xatau X , # bendera menggunakan 0, , 0xatau 0X, masing-masing, untuk mengawali nilai output bukan nol apa pun. Tidak ada awalan yang muncul.
Ketika digunakan dengan eformat , , E, fF, a, atau A , bendera # memaksa nilai output untuk berisi titik desimal. Titik desimal hanya muncul jika digit mengikutinya.
Ketika digunakan dengan g format atau G , # bendera memaksa nilai output untuk berisi titik desimal dan mencegah pemotongan nol berikutnya.

Diabaikan saat digunakan dengan c, , di, u, atau s.
Titik desimal hanya muncul jika digit mengikutinya. Nol berikutnya dipotong.

Spesifikasi lebar

Dalam spesifikasi konversi, bidang spesifikasi lebar opsional muncul setelah karakter bendera apa pun. Argumen width adalah bilangan bulat desimal non-negatif yang mengontrol jumlah minimum karakter yang merupakan output. Jika jumlah karakter dalam nilai output kurang dari lebar yang ditentukan, kosong ditambahkan ke kiri atau kanan nilai—tergantung pada apakah bendera perataan kiri (-) ditentukan—hingga lebar minimum tercapai. Jika width diawali dengan 0, nol di depan ditambahkan ke bilangan bulat atau konversi floating-point hingga lebar minimum tercapai, kecuali ketika konversi ke tak terbatas atau NaN.

Spesifikasi lebar tidak pernah menyebabkan nilai terpotong. Jika jumlah karakter dalam nilai output lebih besar dari lebar yang ditentukan, atau jika width tidak disediakan, semua karakter nilai adalah output, tunduk pada spesifikasi presisi.

Jika spesifikasi lebar adalah tanda bintang (*), int argumen dari daftar argumen menyediakan nilai . Argumen width harus mendahului nilai yang sedang diformat dalam daftar argumen, seperti yang ditunjukkan dalam contoh ini:

printf("%0*d", 5, 3); /* 00003 is output */

Nilai yang hilang atau kecil width dalam spesifikasi konversi tidak menyebabkan pemotongan nilai output. Jika hasil konversi lebih luas dari width nilai, bidang akan diperluas untuk berisi hasil konversi.

Spesifikasi presisi

Dalam spesifikasi konversi, bidang opsional ketiga adalah spesifikasi presisi. Ini terdiri dari titik (.) diikuti dengan bilangan bulat desimal non-negatif yang, tergantung pada jenis konversi, menentukan jumlah karakter string, jumlah tempat desimal, atau jumlah digit signifikan yang akan dihasilkan.

Tidak seperti spesifikasi lebar, spesifikasi presisi dapat menyebabkan pemotongan nilai output atau pembulatan nilai floating-point. Jika precision ditentukan sebagai 0, dan nilai yang akan dikonversi adalah 0, hasilnya tidak ada output karakter, seperti yang ditunjukkan dalam contoh ini:

printf( "%.0d", 0 ); /* No characters output */

Jika spesifikasi presisi adalah tanda bintang (*), int argumen dari daftar argumen memasok nilai. Dalam daftar argumen, precision argumen harus mendahului nilai yang sedang diformat, seperti yang ditunjukkan dalam contoh ini:

printf( "%.*f", 3, 3.14159265 ); /* 3.142 output */

Karakter type menentukan interpretasi precision atau presisi default saat precision dihilangkan, seperti yang ditunjukkan dalam tabel berikut.

Bagaimana nilai presisi memengaruhi jenis

Jenis Makna Default
a, A Presisi menentukan jumlah digit setelah titik . Presisi default adalah 13. Jika presisi adalah 0, tidak ada titik desimal yang dicetak kecuali # bendera digunakan.
c, C Presisi tidak berpengaruh. Karakter dicetak.
d, i, o, u, x, X Presisi menentukan jumlah minimum digit yang akan dicetak. Jika jumlah digit dalam argumen kurang dari presisi, nilai output diisi di sebelah kiri dengan nol. Nilai tidak dipotong ketika jumlah digit melebihi presisi. Presisi default adalah 1.
e, E Presisi menentukan jumlah digit yang akan dicetak setelah titik desimal. Digit terakhir yang dicetak dibulatkan. Presisi default adalah 6. Jika presisi adalah 0 atau titik (.) muncul tanpa angka setelahnya, tidak ada titik desimal yang dicetak.
f, F Nilai presisi menentukan jumlah digit setelah titik desimal. Jika titik desimal muncul, setidaknya satu digit muncul sebelum titik desimal muncul. Nilai dibulatkan ke jumlah digit yang sesuai. Presisi default adalah 6. Jika presisi adalah 0, atau jika titik (.) muncul tanpa angka setelahnya, tidak ada titik desimal yang dicetak.
g, G Presisi menentukan jumlah maksimum digit signifikan yang dicetak. Enam digit signifikan dicetak, dan nol berikutnya dipotong.
s, S Presisi menentukan jumlah maksimum karakter yang akan dicetak. Karakter yang melebihi presisi tidak dicetak. Karakter dicetak hingga karakter null ditemukan.

Spesifikasi ukuran argumen

Dalam spesifikasi konversi, bidang ukuran adalah pengubah panjang argumen untuk penentu konversi jenis . Bidang ukuran awalan ke bidang jenishh, h, , jl (huruf kecil L), L, , , twll, , Iz(huruf besar i), I32, dan I64—menentukan "ukuran" argumen yang sesuai—panjang atau pendek, 32-bit atau 64-bit, karakter byte tunggal atau karakter lebar—tergantung pada penentu konversi yang mereka ubah. Prefiks ukuran ini digunakan dengan karakter jenis dalam printf keluarga fungsi dan wprintf untuk menentukan interpretasi ukuran argumen, seperti yang ditunjukkan dalam tabel berikut. Bidang ukuran bersifat opsional untuk beberapa jenis argumen. Ketika tidak ada awalan ukuran yang ditentukan, pemformat menggunakan argumen bilangan bulat—misalnya, jenis enumerasi , , , , , dan yang ditandatangani atau tidak charditandatangani—sebagai jenis 32-bitint, dan floatargumen , , doubledan long double floating-point digunakan sebagai jenis 64-bitdouble. longintshort Perilaku ini cocok dengan aturan promosi argumen default untuk daftar argumen variabel. Untuk informasi selengkapnya tentang promosi argumen, lihat Elipsis dan Argumen Default dalam ekspresi Postfix. Pada sistem 32-bit dan 64-bit, spesifikasi konversi argumen bilangan bulat 64-bit harus menyertakan awalan ll ukuran atau I64. Jika tidak, perilaku pemformat tidak ditentukan.

Beberapa jenis adalah ukuran yang berbeda dalam kode 32-bit dan 64-bit. Misalnya, size_t panjangnya 32 bit dalam kode yang dikompilasi untuk x86, dan 64 bit dalam kode yang dikompilasi untuk x64. Untuk membuat kode pemformatan platform-agnostik untuk jenis lebar variabel, Anda dapat menggunakan pengubah ukuran argumen lebar variabel. Sebagai gantinya, gunakan pengubah ukuran argumen 64-bit dan secara eksplisit mempromosikan jenis argumen lebar variabel menjadi 64 bit. Pengubah ukuran argumen khusus I Microsoft (huruf besar i) menangani argumen bilangan bulat lebar variabel, tetapi kami merekomendasikan pengubah , , tdan z khusus jjenis untuk portabilitas.

Prefiks ukuran untuk penentu jenis format cetak dan wprintf

Untuk menentukan Gunakan awalan Dengan penentu tipe
char
unsigned char
hh d, i, o, u, x, atau X
short int
short unsigned int
h d, i, o, u, x, atau X
__int32
unsigned __int32
I32 d, i, o, u, x, atau X
__int64
unsigned __int64
I64 d, i, o, u, x, atau X
intmax_t
uintmax_t
j atau I64 d, i, o, u, x, atau X
long double l (huruf kecil L) atau L a, A, e, E, f, F, g, atau G
long int
long unsigned int
l (huruf kecil L) d, i, o, u, x, atau X
long long int
unsigned long long int
ll (huruf kecil LL) d, i, o, u, x, atau X
ptrdiff_t t atau I (huruf besar i) d, i, o, u, x, atau X
size_t z atau I (huruf besar i) d, i, o, u, x, atau X
Karakter byte tunggal h c atau C
Karakter lebar l (huruf kecil L) atau w c atau C
String karakter byte tunggal h s, S, atau Z
String karakter lebar l (huruf kecil L) atau w s, S, atau Z

Jenis ptrdiff_t dan size_t adalah __int32 atau unsigned __int32 pada platform 32-bit, dan __int64 atau unsigned __int64 pada platform 64-bit. I Awalan (huruf besar i), j, , tdan z ukuran mengambil lebar argumen yang benar untuk platform.

Di Visual C++, meskipun long double merupakan jenis yang berbeda, ia memiliki representasi internal yang sama dengan double.

Penentu hc jenis atau hC identik dengan c dalam printf fungsi dan dengan C dalam wprintf fungsi. Penentu lcjenis , lC, wc, atau wC identik dengan C dalam printf fungsi dan dengan c dalam wprintf fungsi. Penentu hs jenis atau hS identik dengan s dalam printf fungsi dan dengan S dalam wprintf fungsi. Penentu lsjenis , lS, ws, atau wS identik dengan S dalam printf fungsi dan dengan s dalam wprintf fungsi.

Catatan

Khusus Microsoft:
I Awalan pengubah ukuran (huruf besar i), I32, , I64dan w argumen adalah ekstensi Microsoft dan tidak kompatibel dengan ISO C. h Awalan saat digunakan dengan data jenis char dan l awalan (huruf kecil L) saat digunakan dengan data jenis double adalah ekstensi Microsoft.

Baca juga

printf, _printf_l, wprintf, _wprintf_l
printf_s, _printf_s_l, wprintf_s, _wprintf_s_l
printf_p Parameter Posisi