Setelah bisa menyalin string, operasi berikutnya yang sering diperlukan adalah menggabungkan dua string—misalnya menyusun path file dari direktori dan nama file, atau membangun pesan dari beberapa fragmen teks. Standard library C menyediakan strcat dan strncat untuk pekerjaan ini. Sama seperti pasangan strcpy/strncpy, strcat tidak menerima parameter ukuran sehingga rentan buffer overflow, sementara strncat menerima batas n untuk membatasi jumlah byte yang digabung. Akan tetapi, semantik strncat sedikit berbeda dari strncpy dan sering disalahpahami: strncat selalu menambahkan null terminator di akhir hasil. Pada chapter ini kita akan menelusuri kedua fungsi ini, menjelaskan perbedaan semantiknya, dan membangun pola aman untuk penggabungan string.

strcat: Gabung Tanpa Batas #

strcat(dst, src) menambahkan isi src ke akhir dst. Fungsi ini mencari null terminator di dst lalu menyalin byte src (termasuk null terminator) mulai dari posisi tersebut. Buffer dst harus cukup besar untuk menampung hasil penggabungan.

c
#include <stdio.h>
#include <string.h>

int main(void) {
    char buf[40] = "Halo, ";
    char nama[] = "Budi!";

    /* strcat: cari null terminator di buf, lalu tempel src */
    strcat(buf, nama);
    printf("Hasil: %s\n", buf);

    /* Bisa dipanggil berturut-turut untuk membangun string */
    char kalimat[60] = "Belajar";
    strcat(kalimat, " pemrograman");
    strcat(kalimat, " C");
    strcat(kalimat, " itu menyenangkan.");
    printf("Kalimat: %s\n", kalimat);
    printf("Panjang: %zu\n", strlen(kalimat));
    return 0;
}

Output yang Dihasilkan:

text
Hasil: Halo, Budi!
Kalimat: Belajar pemrograman C itu menyenangkan.
Panjang: 39

Mari kita telaah baris-baris kode di atas:

  1. Baris 6 (char buf[40] = "Halo, ";): kita mengalokasikan buffer 40 byte dan menginisialisasi 7 byte pertama dengan "Halo, " (6 karakter + null terminator). Tiga puluh tiga byte sisanya tidak terpakai.
  2. Baris 10 (strcat(buf, nama);): strcat mencari null terminator di buf (ditemukan di indeks 6), lalu menyalin byte nama (B, u, d, i, !, '\0') mulai dari posisi tersebut. Setelah pemanggilan, buf berisi "Halo, Budi!".
  3. Baris 14-17 (tiga pemanggilan strcat berturut-turut): setiap strcat menambahkan fragmen baru ke akhir kalimat. Karena strcat mengembalikan pointer ke dst, pemanggilan dapat dirantaikan—tetapi di sini kita memilih pemanggilan terpisah demi keterbacaan.
  4. Baris 19 (printf("Panjang: %zu\n", strlen(kalimat));): hasil akhir adalah "Belajar pemrograman C itu menyenangkan." dengan panjang 39 karakter.

strncat: Gabung dengan Batas #

strncat(dst, src, n) menambahkan maksimal n karakter dari src ke akhir dst. Berbeda dari strncpy, strncat selalu menambahkan null terminator setelah byte yang disalin—selama buffer tujuan menyediakan ruang untuknya.

c
#include <stdio.h>
#include <string.h>

int main(void) {
    char buf[10] = "ID:";
    char src[] = "1234567890ABCDEF";

    /* strncat: tempel maksimal n karakter, LALU tambah '\0' */
    strncat(buf, src, 5);   /* buf sekarang "ID:12345" + '\0' = 9 byte */
    printf("buf = %s\n", buf);
    printf("strlen buf = %zu\n", strlen(buf));
    printf("sizeof buf = %zu\n", sizeof buf);

    /* Bandingkan: strncat menambahkan '\0' otomatis (berbeda dari strncpy) */
    char buf3[8] = "Awal";
    /* src lebih panjang dari ruang tersisa, kita potong pakai n */
    strncat(buf3, "XYZ", 2);   /* hanya tempel 2 karakter "XY" + '\0' */
    printf("buf3 = %s (panjang %zu, sizeof %zu)\n",
           buf3, strlen(buf3), sizeof buf3);
    return 0;
}

Output yang Dihasilkan:

text
buf = ID:12345
strlen buf = 8
sizeof buf = 10
buf3 = AwalXY (panjang 6, sizeof 8)

Mari kita telaah baris-baris kode di atas:

  1. Baris 6 (char buf[10] = "ID:";): buffer 10 byte diisi 4 byte pertama (I, D, :, '\0'). Enam byte sisanya bebas.
  2. Baris 10 (strncat(buf, src, 5);): strncat mencari null terminator di buf (di indeks 3), lalu menyalin maksimal 5 karakter dari src (1, 2, 3, 4, 5). Setelah lima karakter disalin, strncat menambahkan null terminator di posisi berikutnya. Total: 3 karakter awal + 5 karakter baru + null terminator = 9 byte. Buffer masih punya 1 byte bebas.
  3. Baris 11-13: buf sekarang berisi "ID:12345" dengan panjang 8 karakter. sizeof buf tetap 10 karena sizeof mencerminkan ukuran buffer, bukan panjang string.
  4. Baris 18 (strncat(buf3, "XYZ", 2);): buf3 berisi "Awal" (4 karakter). strncat menambahkan maksimal 2 karakter (X, Y) lalu null terminator. Hasil: "AwalXY" dengan panjang 6 karakter. Buffer buf3 berukuran 8 byte sehingga masih ada 1 byte bebas setelah null terminator.

Pola Aman: Hitung Ruang Tersisa sebelum strncat #

Untuk memastikan strncat tidak menulis melebihi buffer, kita dapat menghitung ruang tersisa di buffer tujuan lalu memakai nilai tersebut sebagai parameter n. Pola ini menjadi fondasi fungsi pembungkus aman untuk penggabungan.

c
#include <stdio.h>
#include <string.h>

/* Pola aman: hitung ruang tersisa lalu strncat */
void gabung_aman(char *dst, size_t ukuran, const char *src) {
    size_t terpakai = strlen(dst);
    if (terpakai >= ukuran - 1) return;   /* sudah penuh */
    strncat(dst, src, ukuran - terpakai - 1);
}

int main(void) {
    char kalimat[20] = "Halo";
    gabung_aman(kalimat, sizeof kalimat, " Budi dan Siti");
    printf("Hasil: %s\n", kalimat);
    printf("Panjang: %zu\n", strlen(kalimat));

    /* Mencoba gabung lagi setelah penuh */
    gabung_aman(kalimat, sizeof kalimat, " tambahan yang sangat panjang");
    printf("Setelah tambahan: %s\n", kalimat);
    return 0;
}

Output yang Dihasilkan:

text
Hasil: Halo Budi dan Siti
Panjang: 18
Setelah tambahan: Halo Budi dan Siti 

Pada fungsi gabung_aman, kita menghitung terpakai = strlen(dst) untuk mengetahui berapa byte sudah terpakai di buffer. Bila terpakai >= ukuran - 1, buffer sudah penuh (hanya tersisa 1 byte untuk null terminator yang sudah ada) sehingga kita return tanpa menggabung apapun. Bila masih ada ruang, kita memanggil strncat(dst, src, ukuran - terpakai - 1) di mana ukuran - terpakai - 1 adalah jumlah karakter maksimum yang masih bisa disalin tanpa overflow. Pada contoh, buffer 20 byte diisi "Halo" (4 karakter) lalu digabung " Budi dan Siti" (14 karakter). Total: 4 + 14 = 18 karakter + null terminator = 19 byte. Buffer masih menyisakan 1 byte bebas. Saat mencoba menggabung " tambahan yang sangat panjang" (28 karakter), hanya 1 byte tersisa—tidak cukup untuk apa pun, sehingga tidak ada karakter baru yang ditambahkan.

Ringkasan Konsep #

strcat dan strncat menggabungkan string dengan mencari null terminator di buffer tujuan lalu menempelkan byte dari sumber. strcat(dst, src) tidak menerima parameter ukuran sehingga rentan buffer overflow. strncat(dst, src, n) membatasi jumlah karakter yang disalin ke n dan selalu menambahkan null terminator—berbeda dari strncpy yang tidak menambahkannya bila sumber lebih panjang dari n. Pola aman yang direkomendasikan: hitung ruang tersisa di buffer (ukuran - strlen(dst) - 1) dan pakai nilai tersebut sebagai n pada strncat. Atau gunakan snprintf untuk penggabungan kompleks dengan kontrol format. Pada chapter berikutnya kita akan membahas strcmp dan strncmp—fungsi untuk membandingkan isi dua string.