Menu

String C++: dasar std::string, method, dan jebakannya

Cara memakai std::string di C++: membuat, menggabungkan, mencari, dan memotong teks dengan aman, plus kenapa kamu hampir tidak pernah butuh char* mentah untuk pekerjaan sungguhan.

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

std::string: teks yang mengelola dirinya sendiri

Di halaman sebelumnya kamu sudah melihat bagaimana smart pointer membuat sebuah objek bisa memiliki sumber daya dan membersihkannya secara otomatis. std::string adalah ide yang sama yang diterapkan pada teks: ia memiliki buffer berisi karakter, memperbesarnya saat kamu menambahkan teks, dan membebaskannya saat string keluar dari scope. Kamu tidak pernah memanggil new, tidak pernah menghitung byte, dan tidak pernah khawatir soal null terminator yang hilang.

Untuk memakainya, sertakan <string>. Class ini ada di namespace std.

Operator + itu melakukan kerja sungguhan: ia mengalokasikan buffer baru yang cukup besar untuk kedua potongan lalu menyalinnya ke sana. Dengan char* mentah, yaitu pointer biasa ke sebuah buffer karakter, kamu harus memakai strcpy dan strcat sambil berharap buffer-mu cukup besar. std::string menghilangkan seluruh jenis kesalahan itu.

Membuat dan menggabungkan string

Kamu bisa menggabungkan string dengan +, tapi andalan untuk memperbesar string di tempat adalah +=. Operator ini menambahkan ke buffer yang sudah ada, bukan menghasilkan string baru setiap kali, dan itu penting di dalam loop.

Hal yang sering mengejutkan: + membutuhkan minimal satu operand yang sudah berupa std::string. Dua string literal hanyalah const char*, jadi "a" + "b" tidak bisa dikompilasi, karena tidak ada operator+ untuk dua raw pointer. Jadikan salah satunya string dulu:

string s = "a" + "b";              // error: can't add two const char*
string s = string("a") + "b";      // fine - left side is a std::string
string s = "a"s + "b";             // fine in C++14+, the "s" literal suffix

Perhatikan bahwa bentuk terakhir memakai sufiks s dari <string> (using namespace std::string_literals;), yang langsung mengubah literal menjadi std::string.

Mengakses isi string

std::string berperilaku seperti container berisi char, jadi kamu bisa mengaksesnya dengan indeks, menelusurinya dengan loop, dan mengambil potongannya.

substr(pos, len) mengembalikan string baru yang disalin dari aslinya; ia tidak mengubah sumbernya. Perhatikan batasnya: word[10] pada string 5 karakter adalah undefined behavior. Ia tidak melempar exception, ia hanya membaca nilai sampah. Kalau kamu ingin akses yang dicek dan melempar std::out_of_range, pakai word.at(10) alih-alih word[10].

Jebakan klasik lainnya: .size() mengembalikan tipe unsigned (size_t). Menulis loop mundur seperti for (size_t i = word.size() - 1; i >= 0; --i) tidak akan pernah berhenti, karena i yang unsigned tidak pernah bisa kurang dari nol: nilainya berputar menjadi angka yang sangat besar. Pakai indeks signed atau susun ulang kondisinya saat kamu perlu menelusuri string secara terbalik.

Mencari dan mengganti

find mencari sebuah substring atau karakter dan mengembalikan indeks awalnya. Kalau targetnya tidak ada, ia mengembalikan konstanta khusus std::string::npos. Selalu bandingkan dengan konstanta itu, jangan menganggap find mengembalikan -1.

Untuk mengubah teks di tempat, replace(pos, len, text) menukar sebagian teks dengan isi baru (yang panjangnya bisa berbeda), sedangkan insert/erase menambah atau menghapus potongan:

String dan angka

Teks dan angka tidak berubah dengan sendirinya: "42" adalah tiga karakter, bukan integer 42. Library standar menyediakan fungsi konversi untuk dua arah. Pakai stoi, stod, dan teman-temannya untuk mem-parsing teks menjadi angka, dan to_string untuk arah sebaliknya.

Ada dua jebakan di sini. Pertama, stoi("abc") melempar std::invalid_argument, jadi lindungi input yang tidak bisa dipercaya dengan blok try/catch. Kedua, to_string(3.99) menghasilkan 3.990000 secara lengkap. Kalau kamu butuh kendali atas presisi dan format, itu tugas string stream, dan ke sanalah kita akan menuju berikutnya.

try {
    int n = std::stoi(userInput);
} catch (const std::invalid_argument&) {
    std::cout << "That wasn't a number.\n";
}

Berikutnya: input dan output

Selama ini kamu sudah mencetak string dengan cout, tapi membacanya kembali dari pengguna punya kejutannya sendiri: cin >> name berhenti di spasi pertama, jadi satu baris lengkap seperti "Ada Lovelace" butuh std::getline. Halaman berikutnya membahas input dan output C++ dengan tuntas: operator stream, membaca satu baris penuh, dan mencampur >> dengan getline tanpa tersandung baris baru yang tersisa.

Pertanyaan yang sering diajukan

Apa perbedaan std::string dan char* di C++?

std::string adalah class yang memiliki dan mengelola memorinya sendiri, bertambah besar sesuai kebutuhan, dan membersihkan dirinya secara otomatis. char* hanyalah raw pointer ke karakter-karakter yang diakhiri '\0': kamu sendiri yang mengelola buffer, panjang, dan masa hidupnya. Pilih std::string untuk hampir semua hal, karena ia menghilangkan seluruh jenis bug buffer overflow dan dangling pointer.

Bagaimana cara mendapatkan panjang string di C++?

Panggil .size() atau aliasnya .length() pada std::string: name.size() mengembalikan jumlah karakter sebagai size_t. Keduanya mengembalikan nilai yang sama; size() lebih umum dipakai karena sama dengan semua container STL lainnya.

Bagaimana cara mengonversi string ke angka di C++?

Pakai std::stoi untuk int, std::stod untuk double, dan sejenisnya (stol, stof). Contoh: int n = std::stoi("42");. Fungsi-fungsi ini melempar std::invalid_argument kalau teksnya bukan angka, jadi bungkus dengan try/catch kalau input-nya tidak bisa dipercaya.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai