Chuỗi trong C và C++
Trong bài học này, bạn sẽ so sánh mảng ký tự của C với std::string của C++ qua các thao tác lấy độ dài, nối, so sánh và tìm kiếm chuỗi.
Giới thiệu
C lưu văn bản trong mảng char kết thúc bằng một ký tự ẩn là '\0', và lập trình viên phải tự đảm bảo mảng đủ chỗ chứa dữ liệu. C++ cung cấp std::string, một kiểu chuỗi tự quản lý bộ nhớ, giúp làm việc với văn bản an toàn và thuận tiện hơn nhiều.
Những điểm quan trọng
- Luôn bật cảnh báo của trình biên dịch (compiler warning) và sửa hết các cảnh báo.
- Hiểu rõ kiểu dữ liệu và thời gian tồn tại (lifetime) của từng giá trị.
- Luôn kiểm tra dữ liệu đầu vào và giới hạn chỉ số của mảng.
Code ví dụ bằng C và C++
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
/* A C string is a char array that ends with '\0'. */
char name[32] = "Ada";
printf("%s has %zu letters\n", name, strlen(name));
/* strcat appends; the array must have room for the result. */
strcat(name, " Lovelace");
printf("%s\n", name);
/* strcmp returns 0 when two strings are equal. */
printf("equal: %d\n", strcmp("cat", "cat") == 0);
/* Walk the characters until the terminating '\0'. */
char upper[32];
size_t i = 0;
for (; name[i] != '\0'; i++) {
upper[i] = (char)toupper((unsigned char)name[i]);
}
upper[i] = '\0';
printf("%s\n", upper);
/* strstr finds a substring and returns a pointer to it, or NULL. */
printf("contains \"love\": %s\n", strstr("lovelace", "love") ? "yes" : "no");
return 0;
}
Ada has 3 letters
Ada Lovelace
equal: 1
ADA LOVELACE
contains "love": yes
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
int main() {
// std::string manages its own memory and grows as needed.
std::string name = "Ada";
std::cout << name << " has " << name.size() << " letters\n";
name += " Lovelace";
std::cout << name << '\n';
// == compares the contents of two strings.
std::cout << "equal: " << (std::string("cat") == "cat") << '\n';
std::string upper = name;
std::transform(upper.begin(), upper.end(), upper.begin(),
[](unsigned char c) { return static_cast<char>(std::toupper(c)); });
std::cout << upper << '\n';
// find returns std::string::npos when the text is missing.
std::string word = "lovelace";
std::cout << "contains \"love\": " << (word.find("love") != std::string::npos ? "yes" : "no") << '\n';
std::cout << "first name: " << name.substr(0, 3) << '\n';
}
Ada has 3 letters
Ada Lovelace
equal: 1
ADA LOVELACE
contains "love": yes
first name: Ada
So sánh C và C++
Trong C, các hàm strlen, strcat, strcmp và strstr làm việc trực tiếp trên mảng ký tự, và nếu mảng không đủ lớn khi nối chuỗi, chương trình có thể bị lỗi tràn bộ đệm (buffer overflow). std::string cung cấp size(), +=, ==, find() và substr(), đồng thời tự mở rộng vùng nhớ khi cần, nhờ đó tránh được lỗi này.
C dùng các hàm thủ tục gọn nhẹ và thể hiện rõ cách dữ liệu được biểu diễn trong bộ nhớ.
C++ vẫn cho phép làm việc ở mức thấp nhưng bổ sung các kiểu dữ liệu thư viện và công cụ trừu tượng an toàn hơn.
Bài tập mở rộng
Hãy chạy cả hai phiên bản, sau đó thử thay đổi code để quan sát sự khác biệt về mức độ an toàn mà mỗi ngôn ngữ mang lại.
- Thử nhập dữ liệu sai và các giá trị ở biên.
- Biên dịch với các cờ -Wall -Wextra -Wpedantic để bật thêm cảnh báo.
- Tách phần khai báo dùng chung ra file header và phần cài đặt ra file riêng.
Luyện tập với thử thách
Áp dụng kiến thức của bài học này để giải một bài toán thực tế. Mỗi thử thách chạy ngay trên trình duyệt, có kiểm thử tức thì và AI nhận xét.
- Count Uppercase Letters Count the capital letters in a text. Dễ
- Chữ Viết Tắt Từ Họ Tên Tạo chữ viết tắt in hoa từ một họ tên đầy đủ. Dễ
- Replace Spaces With Dashes Turn spaces into dashes to make a URL-style slug. Dễ