Menu

String di C: Array Char, Null Terminator, dan Contohnya

C tidak punya tipe string: string adalah array char yang diakhiri byte '\0'. Halaman ini membangun gambaran mental itu, lalu membahas literal, mencetak, menelusuri string, dan kenapa kamu tidak bisa menyalin string dengan =.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Sebagian besar bahasa memberimu tipe string yang tahu panjangnya sendiri. C tidak. Di C, string hanyalah array char dengan satu aturan tambahan: teksnya diikuti sebuah byte bernilai nol, ditulis '\0' dan disebut null terminator. Semua hal lain tentang string di C berawal dari satu konvensi itu.

String Adalah Array Char Ditambah '\0'

Deklarasikan string dengan menginisialisasi array char dari sebuah literal:

Array itu berisi empat byte, bukan tiga:

name:  +-----+-----+-----+------+
       | 'A' | 'd' | 'a' | '\0' |
       +-----+-----+-----+------+
index:    0     1     2     3

sizeof(name) bernilai 4. Compiler menghitung karakternya, menambahkan satu untuk terminator, dan menentukan ukuran array untukmu. Byte tambahan itulah alasan char name[3] = "Ada"; adalah bug yang menunggu waktu: teksnya muat tetapi terminatornya tidak, sehingga tidak ada kode sesudahnya yang bisa tahu di mana string itu berakhir.

Jika kamu ingin ruang untuk mengubah isinya nanti, tentukan ukurannya sendiri dan sisakan ruang:

char name[32] = "Ada";   /* 3 characters, a terminator, 28 bytes spare */

Byte yang tidak terpakai diisi nol oleh inisialisasi, dan itu tidak berbahaya.

Kenapa Terminator Itu Penting

Tidak ada fungsi C yang menerima panjang string. printf("%s", s) hanya diberi satu alamat dan berjalan maju mencetak byte sampai bertemu '\0'. Jadi array char tanpa terminator bukanlah string, dan memperlakukannya sebagai string berarti membaca memori apa pun yang kebetulan ada sesudahnya.

Aturan yang perlu dihafal: sizeof memberimu ukuran penyimpanan, strlen memberimu teksnya. Untuk char buf[32] = "Ada", sizeof buf bernilai 32 dan strlen(buf) bernilai 3. Keduanya menjawab pertanyaan yang berbeda, dan mencampuradukkannya adalah salah satu bug C yang paling umum.

Literal String vs Array Char

Dua baris ini terlihat mirip tetapi berperilaku sangat berbeda:

char  a[] = "hello";   /* an array you own, initialized from the literal */
char *p   = "hello";   /* a pointer aimed at the literal itself */

a adalah array 6 byte yang berisi salinan teks milikmu sendiri. Kamu bisa mengubahnya. p menunjuk ke data string read-only milik program; literal itu dipakai bersama, dan menulis lewat p adalah undefined behavior yang biasanya membuat program crash saat berjalan, bukan saat kompilasi.

Tulis const char * setiap kali sebuah pointer menunjuk ke literal. Compiler lalu menolak penulisan itu saat kompilasi, alih-alih membiarkannya menjadi crash. Memilih di antara keduanya sebenarnya adalah pertanyaan tentang pointer dan array, yang dibahas di halaman pointer dan array.

Satu perbedaan lagi yang perlu diketahui: sizeof a bernilai 6, tetapi sizeof p adalah ukuran pointer (8 di kebanyakan sistem), berapa pun panjang teksnya.

Mencetak dan Membaca String

%s mencetak sebuah string; %c mencetak satu karakter.

Untuk input, hindari gets sepenuhnya. Fungsi itu dihapus dari bahasa C karena tidak bisa dipakai dengan aman. Pakai fgets, yang menerima ukuran buffer dan tidak akan overflow:

fgets menyimpan newline dari tombol Enter yang kamu tekan, dan itu hampir tidak pernah kamu inginkan di dalam string. Baris strcspn mencari '\n' pertama dan menimpanya dengan terminator. Ini cara standar yang ringkas untuk membuangnya.

Menelusuri String Karakter demi Karakter

Karena akhir string ditandai, bukan dihitung, perulangan yang idiomatis menguji karakternya langsung:

Kondisi text[i] != '\0' sering disingkat menjadi text[i] saja, karena '\0' bernilai nol dan karena itu bernilai salah. Keduanya benar; bentuk yang eksplisit lebih mudah dibaca selama kamu masih belajar.

Kamu juga bisa menelusurinya dengan pointer alih-alih indeks, yang sama idiomatisnya di C:

Cast ke unsigned char sebelum memanggil toupper bukan hiasan: fungsi-fungsi <ctype.h> tidak terdefinisi untuk nilai negatif, dan char biasa bisa bernilai negatif untuk byte di atas 127.

Kamu Tidak Bisa Menyalin String dengan =

Inilah tembok yang ditabrak setiap pemula:

char a[10];
a = "hello";        /* error: assignment to expression with array type */

char b[10] = "hi";
char c[10];
c = b;              /* error - same reason */

Nama array bukan nilai yang bisa diubah, jadi = tidak punya apa-apa untuk dikerjakan. Satu-satunya tempat bentuk singkat itu berlaku adalah inisialisasi saat deklarasi, yang merupakan operasi lain yang dikerjakan compiler.

Untuk menyalin saat program berjalan, salin byte-nya dengan strcpy dari <string.h>:

Alasan yang sama menjelaskan kenapa == tidak membandingkan string. if (a == b) membandingkan dua alamat, jadi hasilnya salah untuk dua array berbeda yang berisi teks identik. Pakai strcmp(a, b) == 0. Kedua fungsi ini dan kerabatnya yang lebih aman dibahas di halaman fungsi string.

Array dari String

Daftar string bisa berupa array pointer (untuk teks tetap yang hanya dibaca) atau array char dua dimensi (jika setiap isinya harus bisa diubah):

Array pointer menyimpan tiga alamat yang menunjuk ke literal read-only: ringkas, tetapi tidak bisa diubah. Bentuk char[3][16] memesan 48 byte memori milikmu sendiri, jadi setiap barisnya bisa ditulis ulang.

Kesalahan Umum

  • Lupa byte untuk terminator. char s[5] = "hello" tidak punya ruang untuk '\0'. Tentukan ukurannya sebesar strlen + 1.
  • Memakai sizeof padahal maksudnya strlen. sizeof pada pointer memberikan ukuran pointer, bukan panjang teksnya.
  • Menulis lewat char * ke sebuah literal. Deklarasikan pointer seperti itu sebagai const char *.
  • Membandingkan dengan ==. Itu membandingkan alamat. Pakai strcmp.
  • Membaca dengan scanf("%s", buf). Tidak ada batas ukurannya dan dengan senang hati overflow; pilih fgets.

Pertanyaan yang sering diajukan

Bagaimana cara mendeklarasikan string di C?

Sebagai array char: char name[] = "Ada";. C tidak punya tipe string bawaan. Array itu berisi 'A', 'd', 'a' dan byte keempat yang tersembunyi, '\0', yang menandai akhirnya. Jika kamu ingin ruang untuk mengubah teksnya nanti, beri array ukuran yang eksplisit: char name[32] = "Ada";.

Apa itu null terminator di C?

Byte '\0' (bernilai nol) yang menandai tempat sebuah string berakhir. Setiap fungsi standar, seperti printf("%s"), strlen, strcpy, membaca maju sampai menemukan byte itu. Array char tanpa terminator bukanlah string, dan mengirimnya ke fungsi-fungsi tersebut akan membaca melewati ujung memorimu.

Kenapa saya tidak bisa mengisi string dengan = di C?

Karena array bukan nilai yang bisa kamu salin dengan =. char a[10]; a = "hi"; tidak akan bisa di-compile. Salin karakternya dengan strcpy(a, "hi") dari <string.h>, atau inisialisasi saat deklarasi, char a[10] = "hi";, satu-satunya tempat bentuk singkat ini berlaku.

Apa perbedaan char * dan char [] di C?

char s[] = "hi" membuat array yang bisa diubah dan berisi salinan teks milikmu sendiri. char *p = "hi" membuat pointer ke literal string, yang berada di memori read-only: membacanya tidak masalah, menulis lewat pointer itu membuat program crash. Pakai array jika kamu berniat mengubah isinya, dan pointer jika hanya membaca.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai