Skip to content

C05: String — Xử lý chuỗi ký tự

Bạn sẽ học được: Khai báo string, các phương thức, xử lý chuỗi trong thi đấu
Yêu cầu: Đã học C04 (Mảng & Vector)
Thời gian: 45 phút


String là gì?

Analogies: String = Chuỗi hạt

flowchart LR
    A["String"] -->|"Như chuỗi hạt"| B["Mỗi hạt = 1 ký tự"]
    B --> C["Có chỉ số: 0, 1, 2..."]
Khái niệm Analogies Ví dụ
String Chuỗi hạt "Hello"
Ký tự Mỗi hạt 'H', 'e', 'l', 'l', 'o'
Chỉ số Vị trí hạt s[0]='H', s[1]='e'
Độ dài Số hạt s.length() = 5

Khai báo String

// Cách 1: Khai báo rỗng
string s;

// Cách 2: Khai báo và khởi tạo
string s = "Hello";

// Cách 3: Khai báo n ký tự giống nhau
string s(5, 'a');  // "aaaaa"

// Cách 4: Copy từ string khác
string s2 = s;

String vs char[]

1
2
3
4
5
// char[] — kiểu C cũ (ít dùng)
char s[] = "Hello";

// string — kiểu C++ (nên dùng)
string s = "Hello";
Ưu tiên dùng string vì dễ sử dụng hơn nhiều!


Truy cập ký tự

1
2
3
4
5
6
7
8
9
string s = "Hello";

cout << s[0] << endl;  // 'H' (ký tự đầu tiên)
cout << s[1] << endl;  // 'e'
cout << s[4] << endl;  // 'o' (ký tự cuối cùng)

// Sửa ký tự
s[0] = 'h';
cout << s << endl;  // "hello"

Chỉ số bắt đầu từ 0

1
2
3
string s = "Hello";
// s[0]='H', s[1]='e', s[2]='l', s[3]='l', s[4]='o'
// KHÔNG CÓ s[5]! (truy cập ngoài chuỗi → lỗi)

Các phương thức cơ bản

Độ dài chuỗi

1
2
3
4
string s = "Hello";

cout << s.length() << endl;   // 5 (cách 1)
cout << s.size() << endl;     // 5 (cách 2)

Nối chuỗi

1
2
3
4
5
6
7
8
string s1 = "Hello";
string s2 = " World";

// Cách 1: Dùng +
string s3 = s1 + s2;  // "Hello World"

// Cách 2: Dùng +=
s1 += s2;  // s1 = "Hello World"

Cắt chuỗi

1
2
3
4
5
6
7
string s = "Hello World";

// Cắt từ vị trí pos, độ dài len
string sub = s.substr(6, 5);  // "World"

// Cắt từ vị trí pos đến hết
string sub2 = s.substr(6);  // "World"

Tìm kiếm

1
2
3
4
5
6
7
8
string s = "Hello World";

// Tìm chuỗi con (trả về vị trí, hoặc string::npos nếu không tìm thấy)
int pos = s.find("World");  // 6
if (pos != string::npos) cout << "Tim thay tai vi tri " << pos;

// Tìm từ vị trí nào
int pos2 = s.find("l", 4);  // Tìm 'l' từ vị trí 4 → 9

So sánh

1
2
3
4
5
6
7
string s1 = "Hello";
string s2 = "Hello";
string s3 = "World";

if (s1 == s2) cout << "Bang nhau";  // true
if (s1 != s3) cout << "Khac nhau";  // true
if (s1 < s3) cout << "Hello truoc World";  // true (theo từ điển)

Các hàm khác

string s = "Hello World";

// Chuyển hoa
string upper = s;
transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
// "HELLO WORLD"

// Chuyển thường
string lower = s;
transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
// "hello world"

// Kiểm tra rỗng
if (s.empty()) cout << "Rong";

// Xóa tất cả
s.clear();

Nhập chuỗi

Nhập 1 từ (không có dấu cách)

1
2
3
string s;
cin >> s;  // Chỉ đọc đến dấu cách
cout << s << endl;

Nhập cả dòng

1
2
3
string s;
getline(cin, s);  // Đọc cả dòng (bao gồm dấu cách)
cout << s << endl;

Lỗi khi dùng getline sau cin

1
2
3
4
5
6
7
8
9
int n;
cin >> n;          // Đọc số, để lại '\n' trong buffer

string s;
getline(cin, s);   // Đọc '\n' còn sót → s rỗng!

// ✅ ĐÚNG: Xóa buffer trước
cin.ignore();
getline(cin, s);

Duyệt chuỗi

string s = "Hello";

// Cách 1: Dùng chỉ số
for (int i = 0; i < s.length(); i++) {
    cout << s[i] << " ";
}

// Cách 2: Dùng range-based for
for (char c : s) {
    cout << c << " ";
}

Bài toán kinh điển

Bài toán 1: Đếm ký tự

1
2
3
4
5
6
7
8
string s;
cin >> s;

int count = 0;
for (char c : s) {
    if (c == 'a') count++;
}
cout << count << endl;

Bài toán 2: Kiểm tra palindrome

string s;
cin >> s;

bool isPalindrome = true;
int n = s.length();
for (int i = 0; i < n / 2; i++) {
    if (s[i] != s[n - 1 - i]) {
        isPalindrome = false;
        break;
    }
}

if (isPalindrome) cout << "Palindrome";
else cout << "Khong phai";

Bài toán 3: Đảo ngược chuỗi

1
2
3
4
5
string s;
cin >> s;

reverse(s.begin(), s.end());
cout << s << endl;

Bài toán 4: Kiểm tra chuỗi con

1
2
3
4
5
6
7
8
string s, sub;
cin >> s >> sub;

if (s.find(sub) != string::npos) {
    cout << "Tim thay";
} else {
    cout << "Khong tim thay";
}

Common Mistakes — Lỗi thường gặp

Lỗi 1: Truy cập ngoài chuỗi

1
2
3
4
5
6
7
string s = "Hello";

// ❌ SAI: Truy cập s[5] (ngoài chuỗi)
cout << s[5] << endl;  // Lỗi runtime hoặc giá trị rác!

// ✅ ĐÚNG: Chỉ truy cập s[0] đến s[4]
for (int i = 0; i < s.length(); i++) cout << s[i];

Lỗi 2: Quên getline

1
2
3
4
5
6
7
// ❌ SAI: Chỉ đọc 1 từ
string s;
cin >> s;  // "Hello World" → chỉ đọc "Hello"

// ✅ ĐÚNG: Đọc cả dòng
string s;
getline(cin, s);  // "Hello World"

Lỗi 3: So sánh string bằng ==

1
2
3
4
5
6
7
8
9
// ✅ C++ cho phép so sánh string bằng ==
string s1 = "Hello";
string s2 = "Hello";
if (s1 == s2) cout << "Bang nhau";  // OK!

// ❌ Nhưng với char[] thì không được!
char s3[] = "Hello";
char s4[] = "Hello";
if (s3 == s4) cout << "Sai!";  // So sánh địa chỉ, không phải nội dung!

Bài tập thực hành

Bài 1: Đếm chữ hoa

Đọc chuỗi s. Đếm số ký tự viết hoa.

Input: HelloWorld
Output: 2

Lời giải
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s;
    cin >> s;
    int count = 0;
    for (char c : s) {
        if (isupper(c)) count++;
    }
    cout << count << endl;
    return 0;
}

Bài 2: Kiểm tra palindrome

Đọc chuỗi s. Kiểm tra s có phải palindrome không.

Input: abcba
Output: YES

Lời giải
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s;
    cin >> s;

    string rev = s;
    reverse(rev.begin(), rev.end());

    if (s == rev) cout << "YES" << endl;
    else cout << "NO" << endl;
    return 0;
}

Bài 3: Đếm từ

Đọc 1 dòng. Đếm số từ trong dòng.

Input: Hello World
Output: 2

Lời giải
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s;
    getline(cin, s);

    int count = 0;
    stringstream ss(s);
    string word;
    while (ss >> word) count++;

    cout << count << endl;
    return 0;
}

Tóm tắt bài học

Nội dung Chi tiết
Khai báo string s = "Hello";
Độ dài s.length() hoặc s.size()
Truy cập s[i] — chỉ số bắt đầu từ 0
Nối chuỗi s1 + s2 hoặc s1 += s2
Cắt chuỗi s.substr(pos, len)
Tìm kiếm s.find(sub)
Nhập dòng getline(cin, s)
Duyệt for (char c : s)

Bài viết liên quan


Bài tiếp theo: C06: Hàm trong C++ →


💬 Bình luận