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.

c
#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:

text
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:

  1. Baris 7 (strlen(nama)): strlen mengembalikan size_t. Format specifier yang benar adalah %zu, bukan %d. Memakai %d pada sistem 64-bit dapat memicu undefined behavior.
  2. Baris 11 (strcpy(a, "Halo");): strcpy menyalin “Halo\0” (5 byte) ke buffer a[16]. Buffer tujuan harus cukup besar—bila tidak, terjadi buffer overflow.
  3. 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 bahwa strncpy tidak menulis '\0' di akhir—kita harus menulisnya manual di baris 16.
  4. Baris 22 (strncat(t, "ABCDEFGHIJ", sizeof(t) - strlen(t) - 1);): argumen ketiga strncat adalah jumlah maksimum byte yang ditambahkan (bukan ukuran buffer). Karena itu kita kurangi dengan panjang string tujuan saat ini dan satu byte lagi untuk '\0'. Hasilnya t berisi "ID:ABCDEFGH" (11 karakter + '\0' = 12 byte, pas dengan sizeof(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.

c
#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:

text
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 8

Fungsi 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.

c
#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:

text
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.