Các thao tác với chuỗi
Độ dài chuỗi kí tự
Lớp string định nghĩa cho chúng ta 2 phương thức để thực hiện việc lấy ra độ dài của chuỗi ký tự được lưu trong standard container.
string my_favorite_quote = "By my will, this shall be finished";
cout << "Length of the quote: " << my_favorite_quote.length() << endl;
cout << "Length of the quote: " << my_favorite_quote.size() << endl;
Hai phương thức length và size của lớp string đều được dung để tính độ dài của chuỗi ký tự trong standard container.
Khi string có độ dài chuỗi ký tự là 0, nó được xem là string rỗng. Để kiểm tra xem string có rỗng hay không, chúng ta sử dụng phương thức empty, phương thức này trả về giá trị true khi string rỗng, ngược lại, trả về giá trị false.
string empty_string = "";
if(empty_string.empty())
cout << "string is empty" << endl;
Chúng ta có thể làm một string có dữ liệu trở thành string rỗng bằng phương thức clear.
string str = "This is a sample string";
str.clear();
if(str.empty())
cout << "str is now empty" << endl;
Truy cập phần tử trong string
Cũng tương tự như việc truy cập phần tử trong mảng ký tự, chúng ta sử dụng cặp dấu ngoặc vuông và truyền vào một giá trị số nguyên đại diện cho chỉ số của phần tử cần truy xuất.
string str = "Learn from others people";
for(int32_t index = 0; index <= str.length() - 1; index++) {
cout << str[index] << " ";
}
cout << endl;
for(int32_t index = 0; index <= str.length() - 1; index++) {
cout << str.at(index) << " ";
}
Phương thức at của lớp string cũng thực hiện truy xuất đến phần tử có chỉ số index tương tự cặp ngoặc vuông.
Nếu chương trình phát hiện hành vi truy xuât đến phần tử có chỉ số index tương tự có chỉ số không hợp lệ (index < 0 hoặc index => string length), Assertion sẽ ép buộc chương trình kết thúc và thông báo lỗi.
Hai cách truy cập phần tử trên được dung để truy xuất phần tử có chỉ số không cố định. Lớp string còn cung cấp cho chúng ta hai phương thức để truy xuất nhanh đến phần tử đầu tiên cuối cùng của chuỗi ký tự trong standard container.
string sample = "Access to the first and the last element";
cout << "First: " << sample.front() << endl;
cout << "Last: " << sample.back() << endl;
Assertion đặt trong hai phương thức front và back sẽ được kích hoạt nếu string rỗng.
Thay đổi dữ liệu trong string
Có khá nhiều phương thức được lớp string định nghĩa dung để thay đổi dữ liệu trong standard container.
Nối thêm ký tự vào sau string.
Chúng ta chỉ cần truyền vào phương thức push_back ký tự mà chúng ta muốn thêm vào sau chuỗi ký tự trong standard container.
string str = "A sentence must end with a dot";
str.push_back('.');
Xóa phần tử
Ngược lại với phương thức push_back ở trên, phương thức pop_back xóa đi kí tự cuối cùng trong string. Nếu các bạn thực hiện phương thức này khi string rỗng, chương trình sẽ gây ra lỗi xung đột vùng nhớ, vì thế, các bạn cần kiểm tra trước khi xóa.
string str = "The dot will be removed.";
if(!str.empty())
str.pop_back();
Nối chuỗi ký tự vào sau string
Chúng ta có thể sử dụng phương thức append của lớp string để nối thêm một chuỗi kí tự vào sau chuỗi kí tự trong standard container.
string& append (const string& str);
string& append (const char* s);
Các bạn có thể truyền vào phương thức append một đối tượng có kiểu string hoặc tên của một mảng kí tự nào đó.
string str = "";
str.append("Duong");
str.append(" ");
str.append("Dang");
str.append("Thanh");
Bên cạnh đó, lớp string cũng đã định nghĩa lại toán tử nối chuỗi kí tự giúp chúng ta tiết kiệm thời gian viết code hơn.
string str = "";
str += "Use \"+=\" operator ";
str += "to append string";
Toán tử ‘+=’ có chức năng hoàn toàn giống với phương thức append.
Chèn một string vào vị trí bât kì trong string.
Phương thức insert có thể giúp chúng ta chèn một string vào vị trí pos.
string& insert (size_t pos, const string & str);
Ví dụ:
string str = "how to use.";
string str2 = "i will introduce you ";
cout << str << endl;
str.insert(0, str2);
cout << str << endl;
str.insert(str.length() - 1, " string in C++");
cout << str << endl;
Trong lần sử dụng phương thức insert đầu tiên, mình chèn str2 vào str tại vị trí đầu tiên. Sau đó, mình chèn them một chuỗi ký tự tại vị trí str.length()-1 (trước dấu chấm kết thúc câu).
Sử dụng phương thức insert với vị trí chèn không hợp lệ sẽ gây ra lỗi xung đột vùng nhớ.
Thay thế một thành phần của string
Chắc các bạn cũng có thể đoán được tên của phương thức mà mình chuẩn bị nói tới. Phương thức replace dùng để thay thế một đoạn con của chuỗi kí tự lưu trong standard container bằng 1 string hoặc 1 mảng kí tự khác.
Ví dụ:
string my_string = "This string will be replaced";
cout << my_string << endl;
my_string.replace(20, 8, "changed");
cout << my_string << endl;
Nhìn vào kết quả đoạn chương trình trên và hình dung điều gì vừa được diễn ra.
Hình 8.4. Mô phỏng kết quả chương trình
Tại vị trí pos của string gốc, chương trình xóa đi len ký tự, và chèn str vào string gốc tại vị trí pos. Đó là cách mà phương thức replace hoạt động.
Tìm kiếm
Có nhiều phương thức trong lớp string được định nghĩa cho các trường hợp tìm kiếm phức tạp. Mình chỉ hướng dẫn các bạn sử dụng phương thức find của lớp string để tìm kiếm vị trí xuất hiện của chuỗi con bên trong đối tượng mà bạn đang dùng để gọi phương thức find.
Ví dụ mình có string dung để lưu một số tên của các thành viên trong nhóm thực hiện tutorial này.
string name_list = "Le Tran Dat\nDuong Dang Thanh\nLe Tuan Anh\nNguyen Hai Ha";
Yêu cầu nhập vào một cái tên từ bàn phím và xác định xem tên đó có tồn tại trong danh sách trên hay không.
Sau đây là một số khai báo phương thức find trong lớp string sẽ giúp các bạn giải quyết vấn đề mình vừa đặt ra.
size_t find (const string& str, size_t pos = 0) const;
Tìm kiếm sự xuất hiện của chuỗi con str bên trong standard container của đối tượng mà các bạn dùng để gọi phương thức find, vị trí bắt đầu tìm kiếm mặc định là 0.
string name;
cout << "Enter a name: ";
getline(cin, name);
int32_t search_index = name_list.find(name);
if(search_index == -1)
cout << name << " is not exist in name_list" << endl;
else
cout << "Found at: " << search_index << endl;
Nếu name được tìm thấy bên trong name_list, biến search_index sẽ nhận được giá trị là chỉ sổ mà name được tìm thấy. Nếu không được tìm thấy, biến search_index nhận giá trị -1.
Phương thức find này dễ sử dụng hơn so với việc sử dụng hàm strstr trong thư viện cstring để tìm kiếm trong mảng kí tự.
So sánh 2 string
Phép so sánh 2 string cũng được thực hiện theo thứ tự từ điển (từ trái sang phải) giống như khi so sánh hai mảng kí tự.
int compare (const string& str) const;
Hoặc
int compare (const char* s) const;
Phương thức so sánh compare trả về một giá trị số nguyên. Tương tự như so sánh 2 mảng kí tự bằng hàm strcmp, giá trị trả về sẽ là 1 trong 3 trường hợp:
- Giá trị trả về là 0:
Điều này có nghĩa nội dung của hai chuỗi kí tự này hoàn toàn giống nhau. Ví dụ:
string str1 = "This is a string";
string str2 = "This is a string";
if(str1.compare(str2) == 0) {
cout << "str1 and str2 are equal" << endl;
}
else {
cout << "str1 ans str2 are not equal" << endl;
}
- Giá trị trả về nhỏ hơn 0:
Điều này có nghĩa tại vị trí phát hiện cặp kí tự không tương xứng giữa str1 và str2 tạm gọi là vị trí index_not_match, ta có:
str1[index_not_match] < str[index_not_match]
Ví dụ:
string str1 = "abcDEF";
string str2 = "abcdef";
Khi so sánh string str1 và string str2 như trên bằng dòng lệnh str1.compare(str2), ta nhận được giá trị trả về nhỏ hơn 0, vì tại vị trí có chỉ số là 3, kí tự 'D' của str1 có mã ASCII nhỏ hơn kí tự 'd' của str2.
- Giá trị trả về lớn hơn 0:
Ngược lại với việc giá trị trả về nhỏ hơn 0. Mình lấy lại ví dụ trên:
string str1 = "abcDEF";
string str2 = "abcdef";
Nếu các bạn thực hiện so sánh như sau:
str2.compare(str1);
Giá trị trả về sẽ lớn hơn 0.
Một cách sử dụng khác của phương thức compare:
int compare (size_t pos, size_t len, const string& str) const;
Ví dụ:
string my_string = "Make a comparison";
int comparison = my_string.compare(7, 10, "comparison");
cout << "Result of the comparison: " << comparison << endl;
Đối số pos được mình gán giá trị 7, đại diện cho vị trí bắt đầu so sánh. Tại vị trí có chỉ số 7, mình lấy ra 10 kí tự liên tiếp nhau để lần lượt so sánh với chuỗi "comparison" được mình truyền vào ở đối số thứ 3 trong phương thức compare.
Hình 8.5. Mô phỏng kết quả chương trình dùng phương thức compare
Chương trình phát hiện 2 chuỗi kí tự con này giống nhau, nên giá trị trả về là 0.