String literal di C dibatasi oleh tanda kutip ganda, sehingga karakter tertentu seperti kutipan ganda itu sendiri, backslash, atau newline tidak bisa ditulis begitu saja di dalam string. Untuk memasukkan karakter-karakter ini, C menyediakan escape sequence — kombinasi backslash \ diikuti satu atau beberapa karakter. Pada chapter ini kita akan mempelajari escape sequence yang paling sering dipakai, perilaku escape sequence yang efeknya bergantung pada terminal, serta kapan kita harus memakai \\ di dalam path berkas Windows. Pemahaman yang benar tentang escape sequence mencegah bug halus seperti string yang terpotong karena karakter \0 disisipkan tanpa sengaja.

Escape Sequence yang Umum Dipakai #

Escape sequence paling sering kita temui adalah \n (newline), \t (tab horizontal), \\ (backslash literal), dan \" (kutipan ganda literal). Selain keempat itu, ada juga \0 (karakter null sebagai penanda akhir string), \' (kutipan tunggal), \xhh (karakter heksadesimal), dan \ooo (karakter oktal).

c
#include <stdio.h>

int main(void) {
    printf("Baris pertama\nBaris kedua\n");
    printf("Kolom 1\tKolom 2\tKolom 3\n");
    printf("Kutipan: \"Belajar C itu seru\"\n");
    printf("Path folder: C:\\Users\\Budi\\Documents\n");
    printf("Tanda persen: 100%%\n");
    printf("Huruf A pakai hex  : \\x41 -> \x41\n");
    printf("Huruf A pakai oktal: \\101 -> \101\n");
    printf("Tanda kutip tunggal dalam char: '%c'\n", '\'');
    return 0;
}

Output yang Dihasilkan:

text
Baris pertama
Baris kedua
Kolom 1 Kolom 2 Kolom 3
Kutipan: "Belajar C itu seru"
Path folder: C:\Users\Budi\Documents
Tanda persen: 100%
Huruf A pakai hex  : \x41 -> A
Huruf A pakai oktal: \101 -> A
Tanda kutip tunggal dalam char: '''

Mari kita telaah baris-baris kode di atas:

  1. Baris 4 (printf("Baris pertama\nBaris kedaua\n");): escape sequence \n memerintahkan terminal untuk pindah ke baris berikutnya. Tanpa \n, kedua teks akan tergabung dalam satu baris.
  2. Baris 5 (printf("Kolom 1\tKolom 2\tKolom 3\n");): escape sequence \t menghasilkan karakter tab horizontal. Pada output, “Kolom 2” dimulai pada posisi tab berikutnya (umumnya setiap 8 kolom).
  3. Baris 6 (printf("Kutipan: \"...\"...\n");): escape \" menulis karakter kutipan ganda secara literal. Tanpa backslash, " akan menutup string literal lebih awal.
  4. Baris 7 (printf("Path folder: C:\\Users\\...")): escape \\ menulis satu backslash literal. Path berkas Windows menggunakan backslash sebagai pemisah folder, jadi setiap backslash di source code harus ditulis dua kali.
  5. Baris 8 (printf("Tanda persen: 100%%\n");): %% bukan escape sequence melainkan format specifier khusus printf. Disertakan di sini agar tidak tertukar dengan \\.
  6. Baris 9 (printf("Huruf A pakai hex : \\x41 -> \x41\n");): \x41 adalah notasi heksadesimal untuk karakter ASCII 0x41, yaitu huruf 'A'. Bagian \\x41 di awal menulis \x41 sebagai teks biasa agar pembaca melihat keduanya berdampingan.
  7. Baris 10 (printf("Huruf A pakai oktal: \\101 -> \101\n");): \101 adalah notasi oktal untuk karakter ASCII 0101 (desimal 65), juga huruf 'A'.
  8. Baris 11 (printf("...'%c'\n", '\'');): escape \' hanya relevan di dalam character literal yang dibatasi kutip tunggal. Argumen yang dilewatkan adalah karakter kutip tunggal itu sendiri, lalu dicetak memakai %c.

Escape Sequence yang Bergantung Terminal #

Sebagian escape sequence menghasilkan karakter kontrol ASCII yang perilakunya bergantung pada perangkat output. Contohnya \a (alert/bel), \b (backspace), \r (carriage return), \f (form feed), dan \v (vertical tab). Pada terminal modern, efek visualnya mungkin tidak terlihat atau hanya sebagian, tetapi byte yang dihasilkan tetap konsisten.

c
#include <stdio.h>

int main(void) {
    /* Karakter kontrol yang efeknya bergantung terminal */
    printf("Bel alert    : [\\a]\a\n");
    printf("Backspace    : ABCDE[\\b\\b]X\b\bX\n");
    printf("Carriage ret : Lama[\\r]Baru\rBaru\n");
    printf("Form feed    : Hal1[\\f]Hal2\fHal2\n");
    printf("Vertical tab : V1[\\v]V2\vV2\n");
    printf("Null char    : A\\0B (byte null disisipkan)\n");
    return 0;
}

Karena efek escape sequence ini bergantung pada terminal, kita periksa byte yang dihasilkan dengan od -c:

text
$ ./program | od -c
0000000   B   e   l       a   l   e   r   t                   :       [
0000020   \   a   ]  \a  \n   B   a   c   k   s   p   a   c   e
0000040       :       A   B   C   D   E   [   \   b   \   b   ]   X  \b
0000060  \b   X  \n   C   a   r   r   i   a   g   e       r   e   t
0000100   :   L   a   m   a   [   \   r   ]   B   a   r   u  \r   B   a
0000120   r   u  \n   H   a   l   1   [   \   f   ]   H   a   l   2  \f
0000140   H   a   l   2  \n   V   1   [   \   v   ]   V   2  \v   V   2
0000160  \n   N   u   l   l       c   h   a   r           :   A   \   0
0000200   B       (   b   y   t   e       n   u   l   l       d   i   s
0000220   i   s   i   p   k   a   n   )  \n
0000225

Mari kita telaah baris-baris kode di atas berdasarkan byte yang dihasilkan:

  1. Baris 4 (printf("Bel alert ... [\\a]\a\n");): byte \a (ASCII 7) muncul tepat setelah [ di output. Pada terminal yang mendukung, byte ini memicu bunyi bel atau kedipan visual. Pada file biasa, byte ini tersimpan apa adanya.
  2. Baris 5 (printf("Backspace : ABCDE[\\b\\b]X\b\bX\n");): dua byte \b muncul di antara X pertama dan X kedua. Pada terminal interaktif, \b menggerakkan kursor satu kolom ke kiri tanpa menghapus karakter. Hasil visual pada terminal: ABCX (huruf D dan E tertimpa).
  3. Baris 6 (printf("Carriage ret : Lama[\\r]Baru\rBaru\n");): byte \r mengembalikan kursor ke awal baris. Setelah \r, string Baru menimpa empat karakter pertama Lama dan seterusnya. Pada terminal, baris ini terlihat sebagai Baruge ret: Lama[\r]Baru.
  4. Baris 7 (printf("Form feed ... Hal1[\\f]Hal2\fHal2\n");): byte \f (ASCII 12) pada printer tradisional memicu ganti halaman. Pada terminal, umumnya diabaikan atau hanya menggerakkan kursor ke bawah beberapa baris.
  5. Baris 8 (printf("Vertical tab : V1[\\v]V2\vV2\n");): byte \v (ASCII 11) menggerakkan kursor ke tab vertikal berikutnya. Perilaku terminal sangat bervariasi.
  6. Baris 9 (printf("Null char ... A\\0B ...\n");): di sini \\0 adalah backslash literal diikuti angka nol. Bukan escape sequence karena backslash-nya ditulis dua kali. Jika kita menulis \0 di dalam string, byte null akan disisipkan dan printf akan berhenti mencetak di titik tersebut karena \0 adalah penanda akhir string.

Memakai Escape Sequence di Konteks Nyata #

Salah satu skenario paling umum adalah menulis path berkas Windows atau membuat payload JSON di dalam string literal. Berikut contoh yang menggabungkan beberapa escape sequence menjadi output yang rapi:

c
#include <stdio.h>

int main(void) {
    /* Tabel rapi memakai tab */
    printf("No\tNama\tNilai\n");
    printf("--\t----\t-----\n");
    printf("1\tBudi\t85\n");
    printf("2\tSiti\t92\n");
    printf("3\tAndi\t78\n");

    /* Path Windows di string literal */
    printf("\nLokasi file: \"C:\\Program Files\\App\\config.ini\"\n");

    /* JSON-like string dengan banyak escape */
    printf("{\"nama\": \"Budi\", \"path\": \"C:\\\\data\"}\n");
    return 0;
}

Output yang Dihasilkan:

text
No      Nama    Nilai
--      ----    -----
1       Budi    85
2       Siti    92
3       Andi    78

Lokasi file: "C:\Program Files\App\config.ini"
{"nama": "Budi", "path": "C:\\data"}

Mari kita telaah baris-baris kode di atas:

  1. Baris 4-8 (tabel): setiap kolom dipisahkan dengan satu tab \t. Pada terminal, tab rata ke kolom berikutnya (umumnya setiap 8 kolom), sehingga output membentuk tabel yang rapi meskipun panjang teks berbeda.
  2. Baris 11 (printf("...\"C:\\Program Files\\App\\config.ini\"...")): setiap backslash di path Windows harus ditulis \\. Kutipan ganda di sekeliling path memakai \".
  3. Baris 14 (printf("{\"nama\": \"Budi\", \"path\": \"C:\\\\data\"}\n");): untuk menghasilkan \\ (dua backslash) di output, kita menulis \\\\ (empat backslash) di source code. Aturannya: setiap backslash literal di output butuh dua backslash di source code.