So sánh chuỗi C-style bằng == (sai!)
Vấn đề
Phần tiêu đề “Vấn đề”Với std::string, toán tử == so sánh nội dung của hai chuỗi - đúng như trực giác. Nhưng với chuỗi C-style (char*, const char*), == so sánh địa chỉ, không phải nội dung!
#include <cstring>#include <iostream>
int main() { const char* a = "Hello"; const char* b = "Hello";
std::cout << (a == b) << std::endl; // Kết quả KHÔNG XÁC ĐỊNH TRƯỚC - có thể true hoặc false!
return 0;}Kết quả phụ thuộc vào việc trình biên dịch có “gộp” hai chuỗi literal giống nhau vào cùng một vùng nhớ hay không (một tối ưu hóa gọi là string interning/pooling) - đây là hành vi do trình biên dịch quyết định, không được chuẩn C++ đảm bảo.
Trường hợp rõ ràng sai: chuỗi được tạo động
Phần tiêu đề “Trường hợp rõ ràng sai: chuỗi được tạo động”#include <cstring>#include <iostream>#include <cstdlib>
int main() { char* a = strdup("Hello"); // Cấp phát vùng nhớ MỚI, chứa "Hello" char* b = strdup("Hello"); // Cấp phát vùng nhớ MỚI KHÁC, cũng chứa "Hello"
std::cout << (a == b) << std::endl; // 0 (false) - chắc chắn khác địa chỉ! std::cout << (strcmp(a, b) == 0) << std::endl; // 1 (true) - nội dung giống nhau
free(a); free(b); return 0;}Giải pháp 1: dùng strcmp cho chuỗi C-style
Phần tiêu đề “Giải pháp 1: dùng strcmp cho chuỗi C-style”#include <cstring>#include <iostream>
int main() { const char* a = "Hello"; const char* b = "Hello";
if (strcmp(a, b) == 0) { // strcmp trả về 0 khi hai chuỗi CÓ NỘI DUNG giống nhau std::cout << "Noi dung giong nhau" << std::endl; }
return 0;}Giải pháp 2: dùng std::string (khuyến nghị)
Phần tiêu đề “Giải pháp 2: dùng std::string (khuyến nghị)”#include <string>#include <iostream>
int main() { std::string a = "Hello"; std::string b = "Hello";
std::cout << (a == b) << std::endl; // 1 (true) - luôn đúng, so sánh theo NỘI DUNG
return 0;}Đây là một trong nhiều lý do std::string được khuyến khích dùng thay cho chuỗi C-style trong C++ hiện đại - hành vi của các toán tử luôn đúng như trực giác.
Tóm tắt
Phần tiêu đề “Tóm tắt”
==trênchar*/const char*so sánh địa chỉ, không phải nội dung - kết quả có thể không như mong đợi và phụ thuộc vào trình biên dịch.
- Dùng
strcmp(a, b) == 0để so sánh nội dung chuỗi C-style- Dùng
std::stringđể==hoạt động đúng theo nội dung một cách tự nhiên