Header <string.h> menyediakan operasi string dan blok memori di C. Berbeda dengan bahasa modern yang punya tipe String dengan manajemen memori otomatis, di C string hanyalah array char berakhir '\0'—tanpa informasi panjang terpisah. Karena itu hampir semua operasi string di C melibatkan <string.h>. Selain fungsi string berakhiran '\0', header ini juga menyediakan fungsi memori mentah seperti memcpy, memset, memcmp yang bekerja pada blok byte tanpa peduli isi. Pada chapter ini kita akan meninjau tiga kelompok fungsi: manipulasi string, pencarian, dan operasi memori.
strlen, strcpy, strncpy, strcat, strncat #
Fungsi strlen menghitung panjang string dengan menelusuri byte sampai menemukan '\0'—tidak termasuk '\0' itu sendiri. Fungsi strcpy menyalin seluruh string termasuk '\0' ke buffer tujuan; strncpy membatasi salinan ke n byte tetapi tidak menambah '\0' bila sumber lebih panjang dari n. Fungsi strcat menggabung string ke akhir string tujuan; strncat membatasi jumlah byte yang ditambahkan.
#include <stdio.h>
#include <string.h>
int main(void) {
/* strlen: panjang string tanpa \0 */
const char *nama = "Belajar C";
printf("strlen(\"%s\") = %zu\n", nama, strlen(nama));
/* strcpy vs strncpy */
char a[16];
strcpy(a, "Halo");
printf("strcpy hasil: \"%s\"\n", a);
char b[8];
strncpy(b, "123456789", sizeof(b) - 1);
b[sizeof(b) - 1] = '\0'; /* strncpy tidak menambah \0 bila penuh */
printf("strncpy hasil: \"%s\" (dipotong)\n", b);
/* strcat */
char s[32] = "Halo, ";
strcat(s, "Budi!");
printf("strcat hasil: \"%s\"\n", s);
/* strncat: tambah dengan batas */
char t[12] = "ID:";
strncat(t, "ABCDEFGHIJ", sizeof(t) - strlen(t) - 1);
printf("strncat hasil: \"%s\"\n", t);
return 0;
}Output yang Dihasilkan:
strlen("Belajar C") = 9
strcpy hasil: "Halo"
strncpy hasil: "1234567" (dipotong)
strcat hasil: "Halo, Budi!"
strncat hasil: "ID:ABCDEFGH"Mari kita telaah baris-baris kode di atas:
- Baris 7 (
strlen(nama)):strlenmengembalikansize_t. Format specifier yang benar adalah%zu, bukan%d. Memakai%dpada sistem 64-bit dapat memicu undefined behavior. - Baris 11 (
strcpy(a, "Halo");):strcpymenyalin “Halo\0” (5 byte) ke buffera[16]. Buffer tujuan harus cukup besar—bila tidak, terjadi buffer overflow. - Baris 15 (
strncpy(b, "123456789", sizeof(b) - 1);): kita batasi salinan ke 7 byte (sizeof(b) - 1). Karena sumber 9 byte, hanya 7 byte pertama yang disalin. Perhatikan bahwastrncpytidak menulis'\0'di akhir—kita harus menulisnya manual di baris 16. - Baris 22 (
strncat(t, "ABCDEFGHIJ", sizeof(t) - strlen(t) - 1);): argumen ketigastrncatadalah jumlah maksimum byte yang ditambahkan (bukan ukuran buffer). Karena itu kita kurangi dengan panjang string tujuan saat ini dan satu byte lagi untuk'\0'. Hasilnyatberisi"ID:ABCDEFGH"(11 karakter +'\0'= 12 byte, pas dengansizeof(t)).
Pencarian dengan strcmp, strncmp, strchr, strstr #
Fungsi strcmp membandingkan dua string lexicographically; return value negatif bila a < b, nol bila sama, positif bila a > b. strncmp membatasi perbandingan ke n byte pertama. strchr mencari karakter pertama yang cocok, sedangkan strstr mencari substring.
#include <stdio.h>
#include <string.h>
int main(void) {
/* strcmp dan strncmp */
printf("strcmp(\"apel\", \"apel\") = %d\n", strcmp("apel", "apel"));
printf("strcmp(\"apel\", \"mangga\") = %d\n", strcmp("apel", "mangga"));
printf("strcmp(\"mangga\", \"apel\") = %d\n", strcmp("mangga", "apel"));
printf("strncmp(\"hello world\", \"hello\", 5) = %d\n",
strncmp("hello world", "hello", 5));
/* strchr: cari karakter pertama */
const char *kal = "Belajar pemrograman C";
char *p = strchr(kal, 'p');
if (p) printf("strchr: 'p' ditemukan di indeks %ld\n", p - kal);
/* strstr: cari substring */
char *q = strstr(kal, "pemrograman");
if (q) printf("strstr: \"pemrograman\" di indeks %ld\n", q - kal);
return 0;
}Output yang Dihasilkan:
strcmp("apel", "apel") = 0
strcmp("apel", "mangga") = -1
strcmp("mangga", "apel") = 1
strncmp("hello world", "hello", 5) = 0
strchr: 'p' ditemukan di indeks 8
strstr: "pemrograman" di indeks 8Fungsi strcmp membandingkan karakter per karakter menggunakan kode ASCII: 'a' (97) < 'm' (109), jadi strcmp("apel", "mangga") mengembalikan nilai negatif. Jangan menganggap return value persis -1/0/1—standard hanya menjamin tanda (negatif, nol, positif). Ekspresi p - kal menghasilkan offset pointer, yaitu indeks karakter yang ditemukan. Bila karakter atau substring tidak ditemukan, fungsi mengembalikan NULL—selalu periksa sebelum memakai return value-nya.
Operasi Memori: memcpy, memset, memcmp #
Tiga fungsi ini bekerja pada blok memori mentah, tidak peduli apakah isinya string, integer, atau struct. memcpy menyalin n byte dari sumber ke tujuan; memset mengisi n byte dengan nilai byte tertentu; memcmp membandingkan n byte. Karena beroperasi di level byte, fungsi-fungsi ini sangat cepat dan sering dipakai untuk inisialisasi array, struct, atau buffer.
#include <stdio.h>
#include <string.h>
int main(void) {
/* memcpy: salin blok memori (sumber dan tujuan tidak boleh overlap) */
int src[] = {10, 20, 30, 40, 50};
int dst[5];
memcpy(dst, src, sizeof(src));
printf("memcpy: %d %d %d %d %d\n",
dst[0], dst[1], dst[2], dst[3], dst[4]);
/* memset: isi blok dengan byte tertentu */
char buf[16];
memset(buf, '-', sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
printf("memset: \"%s\"\n", buf);
/* memcmp: bandingkan n byte */
int x[] = {1, 2, 3};
int y[] = {1, 2, 3};
int z[] = {1, 2, 4};
printf("memcmp(x,y) = %d (sama)\n", memcmp(x, y, sizeof(x)));
printf("memcmp(x,z) = %d (beda)\n", memcmp(x, z, sizeof(x)));
return 0;
}Output yang Dihasilkan:
memcpy: 10 20 30 40 50
memset: "---------------"
memcmp(x,y) = 0 (sama)
memcmp(x,z) = -1 (beda)Fungsi memcpy(dst, src, sizeof(src)) menyalin seluruh array src ke dst tanpa peduli tipe elemen. memset(buf, '-', 15) mengisi 15 byte pertama buf dengan karakter '-' (kode ASCII 45). Argumen kedua memset bertipe int tetapi hanya byte terendah yang dipakai—biasanya kita isi 0 untuk mengenol-kan struct atau buffer. memcmp membandingkan byte demi byte; return value mengikuti tanda perbedaan pertama yang ditemukan.