Menu

Fungsi String di C: strlen, strcpy, strcat, strcmp, dan Lainnya

Tur praktis <string.h>: mengukur dengan strlen, menyalin dengan strcpy dan strncpy, menggabungkan dengan strcat, membandingkan dengan strcmp, mencari dengan strchr dan strstr, serta cara menentukan ukuran buffer supaya tidak ada yang overflow.

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

Setiap fungsi di <string.h> adalah perulangan kecil atas array char yang berhenti di null terminator. Begitu itu jelas, library ini tidak lagi tampak seperti daftar nama yang samar, melainkan beberapa perulangan yang sebenarnya bisa kamu tulis sendiri. Halaman ini membahas fungsi-fungsi yang menangani hampir semua pekerjaan nyata, beserta aturan ukuran yang mencegahnya menulis melewati ujung buffer-mu.

Semua yang ada di sini butuh satu include:

#include <string.h>

strlen: Berapa Banyak Karakter

strlen menghitung byte sampai terminator, tanpa menghitung terminatornya. Hasilnya bertipe size_t, jadi cetak dengan %zu.

strlen bernilai 6; sizeof bernilai 32. Yang pertama adalah teksnya, yang kedua adalah penyimpanannya. Lihat halaman string untuk tahu kenapa perbedaan itu sangat penting.

strlen menelusuri seluruh string di setiap pemanggilan, jadi jangan menaruhnya di kondisi perulangan untuk string yang sama dan tidak berubah:

/* re-counts the whole string on every iteration */
for (size_t i = 0; i < strlen(s); i++) { ... }

/* count once */
size_t n = strlen(s);
for (size_t i = 0; i < n; i++) { ... }

strcpy dan strncpy: Menyalin

strcpy(dst, src) menyalin karakter-karakternya beserta terminator. Fungsi ini tidak tahu seberapa besar dst, jadi pemanggil harus menjamin dst muat setidaknya strlen(src) + 1 byte.

strncpy menerima jumlah maksimum, tetapi punya jebakan terkenal: jika sumbernya setidaknya n byte, fungsi ini menyalin tepat n karakter dan tanpa terminator. Selalu tambahkan terminatornya sendiri:

sizeof dst - 1 ditambah terminator eksplisit adalah pola yang perlu kamu hafalkan. (strncpy juga mengisi sumber yang pendek dengan nol sampai n byte, yang membuang waktu untuk buffer besar. Fungsi ini dirancang untuk record dengan lebar tetap, bukan untuk keamanan.)

strcat dan strncat: Menggabungkan

strcat(dst, src) menambahkan src ke akhir isi dst yang sudah ada. Tujuannya harus muat kedua string ditambah satu terminator, dan harus sudah berisi string yang valid. Menambahkan ke memori yang belum diinisialisasi adalah undefined behavior.

Perhatikan char path[64] = "/home/ada";, bukan char path[64];. Inisialisasi itulah yang membuatnya menjadi string valid untuk strcat pertama.

strncat(dst, src, n) menambahkan paling banyak n karakter dan selalu menambahkan terminator, jadi n adalah sisa ruang, bukan total ukuran buffer:

strncat(dst, src, sizeof dst - strlen(dst) - 1);

Pemanggilan strcat berulang kali selalu memindai ulang tujuannya untuk mencari ujungnya. Menyusun string panjang di dalam perulangan dengan cara itu bersifat kuadratik; untuk apa pun yang cukup besar, catat sendiri posisi tulisanmu atau pakai snprintf, yang dibahas di halaman konversi string.

strcmp: Membandingkan

== membandingkan alamat, jadi hasilnya salah untuk dua array berbeda yang berisi teks yang sama. strcmp membandingkan karakternya dan mengembalikan tanda dari selisihnya.

Tiga aturan:

  • Uji strcmp(a, b) == 0 untuk kesamaan. Menulis if (strcmp(a, b)) berarti "jika keduanya berbeda", yang terbaca terbalik bagi hampir semua orang.
  • Hanya tandanya yang terdefinisi. Jangan bandingkan hasilnya dengan 1 atau -1.
  • Urutannya berdasarkan nilai byte, jadi "Zebra" berada sebelum "apple" di ASCII. Untuk perbandingan yang tidak membedakan huruf besar dan kecil, ubah dulu kedua salinannya menjadi huruf kecil. strcasecmp yang sering terlihat adalah ekstensi POSIX, bukan C standar.

strncmp(a, b, n) hanya membandingkan n karakter pertama, dan ini cara yang rapi untuk menguji sebuah prefiks:

strchr dan strstr: Mencari

strchr(s, ch) mencari kemunculan pertama sebuah karakter; strrchr mencari yang terakhir. strstr(haystack, needle) mencari sebuah substring. Ketiganya mengembalikan pointer ke dalam string aslinya, atau NULL jika tidak ada yang cocok.

Mengurangkan pointer hasil dengan awal string memberimu indeksnya; tipenya ptrdiff_t, dicetak dengan %td. Karena hasilnya menunjuk ke dalam array aslinya, at + 1 adalah sisa string tanpa penyalinan sama sekali. Ini idiom C yang sangat umum.

Selalu cek NULL sebelum melakukan dereference. strchr(email, '@') + 1 pada string tanpa @ menghitung alamat dari NULL, dan perilaku program tidak lagi terdefinisi.

Memecah String

Tidak ada fungsi split, tetapi strchr ditambah sebuah terminator bisa melakukannya langsung di tempat. Contoh ini memotong email menjadi bagian user dan domain:

memcpy menyalin jumlah byte yang pasti tanpa peduli soal terminator, dan itulah yang kamu inginkan ketika panjangnya sudah diketahui. Terminatornya lalu ditulis secara manual.

Contoh Lengkap: Merapikan Nama

Menggabungkan semua yang sudah dibahas: memangkas, membandingkan, menyalin, dan menggabungkan:

Setiap penulisan dibatasi oleh sizeof milik tujuannya sendiri, dan setiap strncpy diikuti terminator eksplisit. Disiplin itu, jika diterapkan secara konsisten, adalah yang membuat kode string C menjadi aman.

Aturan Ukuran yang Perlu Diingat

  • strcpy butuh strlen(src) + 1 byte kosong di tujuan.
  • strcat butuh strlen(dst) + strlen(src) + 1.
  • Setelah strncpy, tulis dst[n - 1] = '\0' sendiri.
  • Untuk strncat, jumlahnya adalah ruang yang tersisa: sizeof dst - strlen(dst) - 1.
  • Cek hasil strchr dan strstr terhadap NULL sebelum memakainya.
  • Pakai sizeof dst hanya jika dst adalah array sungguhan. Di dalam fungsi yang menerima char *dst, sizeof memberikan ukuran pointer, jadi kirim panjang buffer sebagai parameter terpisah.

Pertanyaan yang sering diajukan

Apa yang dikembalikan strcmp di C?

Nol jika kedua string identik, nilai negatif jika string pertama berada di urutan sebelum string kedua, dan nilai positif jika berada sesudahnya. Hanya tandanya yang bermakna, jadi jangan berasumsi hasilnya -1 atau 1. Pengecekan yang kamu butuhkan hampir selalu if (strcmp(a, b) == 0).

Kenapa saya tidak bisa membandingkan string dengan == di C?

a == b membandingkan dua alamat, bukan karakternya. Dua array terpisah yang sama-sama berisi "cat" berada di alamat berbeda, jadi perbandingannya bernilai salah walaupun teksnya sama. Pakai strcmp(a, b) == 0 dari <string.h>.

Apa perbedaan strcpy dan strncpy?

strcpy menyalin sampai '\0' milik sumber tanpa tahu seberapa besar tujuannya. strncpy berhenti setelah paling banyak n byte, tetapi jika sumbernya sepanjang itu, fungsi ini tidak menyalin terminator, jadi kamu harus menulis dst[n - 1] = '\0'; sendiri. Tidak ada yang otomatis aman; disiplin soal ukuran ada di tanganmu.

Bagaimana cara mencari substring di C?

strstr(haystack, needle) mengembalikan pointer ke kemunculan pertama, atau NULL jika tidak ada. Karena yang dikembalikan adalah pointer ke dalam string aslinya, found - haystack memberimu indeksnya. Pakai strchr jika yang kamu cari hanya satu karakter.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai