Fungsi printf dan scanf dari <stdio.h> menggunakan format string berisi teks biasa dan conversion specifier yang dimulai dengan tanda %. Pemilih specifier yang tepat menentukan apakah nilai diterjemahkan sebagai integer, floating point, string, atau pointer—serta bagaimana nilai tersebut dirapikan (lebar, presisi, alignment). Bab ini berisi tabel lengkap specifier beserta modifier dan contoh output aktual yang dapat kita rujuk saat menulis kode.

Conversion Specifier Dasar #

Setiap specifier dimulai dengan % lalu diikuti satu huruf konversi. Tabel berikut mencantumkan specifier yang didukung C standar.

SpecifierTipe argumenOutputContoh
%d / %iintBilangan desimal bertanda42
%uunsigned intBilangan desimal tak bertanda4294967290
%xunsigned intHeksadesimal lowercase2a
%Xunsigned intHeksadesimal uppercase2A
%ounsigned intOktal52
%cint (char)KarakterA
%schar *String null-terminatedBudi
%fdoubleFloating point desimal3.141593
%FdoubleSama seperti %f (uppercase NAN/INF)3.141593
%edoubleNotasi ilmiah lowercase3.141593e+00
%EdoubleNotasi ilmiah uppercase3.141593E+00
%gdouble%e atau %f otomatis (yang lebih pendek)3.14159
%GdoubleSama seperti %g uppercase3.14159
%adoubleHeksadesimal floating point0x1.921f9f01b866ep+1
%AdoubleSama, uppercase0X1.921F9F01B866EP+1
%pvoid *Alamat pointer0x7ffea173a05c
%nint *Menyimpan jumlah karakter tercetak(side effect)
%%—Literal %%

Length Modifier #

Modifier panjang ditempatkan di antara % dan huruf konversi, misalnya %ld untuk long. Modifier menentukan bagaimana argumen dibaca dari stack (atau register) sehingga ukuran yang benar dipakai.

ModifierTipe argumenSpecifier
(none)int, unsigned int%d %u %x %o
hhchar, unsigned char%hhd %hhu
hshort, unsigned short%hd %hu
llong, unsigned long%ld %lu %lx
lllong long, unsigned long long%lld %llu %llx
jintmax_t, uintmax_t%jd %ju
zsize_t, ssize_t%zd %zu
tptrdiff_t%td %tu
Llong double%Lf %Le %Lg

Lebar, Presisi, dan Flag #

Kita dapat mengontrol tampilan dengan menempatkan flag, lebar minimum, dan presisi setelah %.

ModifierBentukEfek
Flag -%-5dRata kiri (default kanan)
Flag 0%05dPad dengan nol (hanya numerik)
Flag +%+dSelalu tampilkan tanda + atau -
Flag (spasi)% dSpasi untuk nilai positif, - untuk negatif
Flag #%#x, %#oTambahkan prefix 0x atau 0
Lebar%5dLebar minimum 5 karakter
Presisi%.2f, %.5s2 desimal / maks 5 karakter string
Gabungan%08.3fLebar 8, presisi 3, pad nol

Program Lengkap #

Program berikut mendemonstrasikan specifier dasar, length modifier, lebar, alignment, dan presisi dalam satu output yang dapat kita pakai sebagai patokan.

c
/* File: fmt1.c - Format specifier untuk printf */
#include <stdio.h>

int main(void) {
    int    i = 42;
    unsigned u = 4294967290u;
    long   l = 9000000000L;
    long long ll = 9000000000000LL;
    double d = 3.14159265;
    char   ch = 'A';
    char   *s = "Budi";
    int    *ptr = &i;

    /* Specifier dasar */
    printf("int       : %d\n", i);
    printf("unsigned  : %u\n", u);
    printf("long      : %ld\n", l);
    printf("long long : %lld\n", ll);
    printf("hex       : %x\n", i);
    printf("HEX       : %X\n", i);
    printf("octal     : %o\n", i);
    printf("char      : %c\n", ch);
    printf("string    : %s\n", s);
    printf("double    : %f\n", d);
    printf("exp       : %e\n", d);
    printf("compact   : %g\n", d);
    printf("pointer   : %p\n", (void*)ptr);
    printf("percent   : %%\n");

    /* Lebar field dan alignment */
    printf("[%5d]\n", i);       /* lebar minimum 5, rata kanan */
    printf("[%-5d]\n", i);       /* rata kiri */
    printf("[%05d]\n", i);      /* pad dengan nol */
    printf("[%+5d]\n", i);      /* tampilkan tanda + */
    printf("[% d]\n", i);        /* spasi untuk positif */

    /* Presisi untuk float */
    printf("[%.2f]\n", d);      /* 2 angka di belakang koma */
    printf("[%.0f]\n", d);      /* tanpa desimal */
    printf("[%8.2f]\n", d);     /* lebar 8, presisi 2 */
    printf("[%-8.2f]\n", d);    /* lebar 8 rata kiri */

    /* Presisi untuk string */
    printf("[%.3s]\n", s);      /* hanya 3 karakter pertama */

    /* Length modifier size_t */
    size_t sz = 1024 * 1024;
    printf("size_t    : %zu\n", sz);

    return 0;
}

Compile dan jalankan:

bash
gcc -std=c11 -Wall -Wextra -o fmt1 fmt1.c
./fmt1

Output yang Dihasilkan:

text
int       : 42
unsigned  : 4294967290
long      : 9000000000
long long : 9000000000000
hex       : 2a
HEX       : 2A
octal     : 52
char      : A
string    : Budi
double    : 3.141593
exp       : 3.141593e+00
compact   : 3.14159
pointer   : 0x7ffea173a05c
percent   : %
[   42]
[42   ]
[00042]
[  +42]
[ 42]
[3.14]
[3]
[    3.14]
[3.14    ]
[Bud]
size_t    : 1048576

Mari kita telaah baris-baris kode di atas:

  1. Baris 6-13 (unsigned u = 4294967290u dst.): Suffix u, L, LL wajib ditambahkan pada literal agar kompilator menafsirkan tipe literal dengan benar. Tanpa LL, literal 9000000000000 dianggap int lalu menyebabkan overflow.
  2. Baris 23 (printf("hex : %x\n", i)): %x mencetak nilai integer dalam basis 16 lowercase. Untuk 42 desimal, hasilnya 2a. Untuk output dengan prefix 0x, gunakan %#x.
  3. Baris 33 (printf("[%+5d]\n", i)): Flag + memaksa tanda ditampilkan—berguna saat kolom angka positif dan negatif perlu sejajar. + hanya bekerja untuk tipe signed.
  4. Baris 39 (printf("[%.0f]\n", d)): Presisi 0 menghilangkan bagian desimal. Nilai 3.14159265 dibulatkan ke 3 (pembulatan ke terdekat, berbeda dengan cast (int)3.99 yang membuang pecahan).
  5. Baris 46 (printf("size_t : %zu\n", sz)): size_t adalah tipe unsigned yang lebar 4 byte di 32-bit dan 8 byte di 64-bit. Specifier %zu memastikan format benar pada kedua platform.

Specifier untuk scanf #

scanf menggunakan specifier yang mirip, tetapi argumennya harus berupa pointer ke variabel yang akan diisi. Beberapa perbedaan penting: %c membaca satu karakter termasuk whitespace; %s berhenti di whitespace; %[...] membaca set karakter tertentu.

SpecifierMembacaContoh
%dInteger bertandascanf("%d", &x)
%uInteger tak bertandascanf("%u", &u)
%ldlongscanf("%ld", &l)
%ffloat (bukan double!)scanf("%f", &f)
%lfdoublescanf("%lf", &d)
%cSatu karakterscanf("%c", &ch)
%sString (stop di whitespace)scanf("%9s", buf)
%[0-9]Hanya digitscanf("%[0-9]", buf)
%[^,]Semua kecuali komascanf("%[^,]", buf)