Hướng dẫn và ví dụ C/C++ string

1- C-Style String

1.1- C-style String

Trong C++ có hai loại chuỗi (string), chuỗi theo phong cách của C (C-style string), và chuỗi theo phong cách của C++ (C++-Style string).

C-Style string thực sự là một mảng các ký tự, nhưng có một số hàm khác nhau được sử dụng cho các chuỗi, ví dụ như thêm vào các chuỗi, tìm chiều dài của chuỗi, và các hàm kiểm tra phù hợp của string với một biểu thức chính quy (regular expression).

Định nghĩa của một chuỗi sẽ là cái gì đó chứa nhiều hơn một ký tự kết hợp với nhau. Ví dụ, “this” là một chuỗi. Tuy nhiên, một ký tự đơn lẻ không được coi là một chuỗi, mặc dù chúng được sử dụng giống như một chuỗi.

String thực chất là một mảng các ký tự. Sử dụng dấu nháy kép để dánh dấu một chuỗi chữ (string literals)


// Khai báo một string theo kiểu mảng. Với ký tự null ở cuối.
char mystring[] = { 't', 'h', 'i', 's', ' ', 'i', 's' ,' ', 't', 'e', 'x', 't', '\0'};

// Đây là một string literal
char mystring[] = "this is text'';

StringLiteralExample. cpp


#include 

int main() {

  // Khai báo một String (String literal).
  char s1[] = "What is this";

  // In ra nội dung của string.
  printf("Your string = %s", s1);

  fflush(stdout);

  return 0;
}

Kết quả chạy ví dụ :

  • char mystr[] = “what is this”;

Đoạn string ở trên có 12 ký tự, để khai báo string đó trong C bạn cần khai báo một mảng ký tự có 13 phần tử, hãy nhớ rằng phần tử cuối cùng trong mảng là ký tự null (mã là ‘\0’), nó có ý nghĩa kết thúc của string. Ký tự cuối cùng này không có ý nghĩa trong chuỗi của bạn, nhưng nó cần thiết cho chương trình C, chẳng hạn con trỏ (pointer) trỏ tới một ví trí của string nó sẽ đứng ở vị trí ký tự đầu tiên, và muốn lấy ra nội dung của chuỗi, chương trình sẽ duyệt tiếp các phần tử tiếp theo cho tới khi bắt gặp ký tự null.

Trong tình huống bạn có một mảng các ký tự và trong đó có phần tử ký tự null không nằm ở cuối của mảng, hoặc có nhiều phần tử ký tự null ở trong mảng. Tuy nhiên C sẽ chỉ coi mảng này chứa một string, bao gồm các ký tự đầu tiên cho tới ký tự null đầu tiên trong mảng.

Ví dụ sau đây khai báo một mảng các ký tự có 100 phần tử dùng để lưu trữ đoạn text do người dùng nhập vào từ bàn phím. Trong tình huống này các ký tự của chuỗi nhập vào sẽ được gán cho các phần tử đầu tiên của mảng và sau đó là ký tự null. Và các phần tử tiếp theo có thể không được gán.


StringFromKeyboardExample. cpp


#include 

int main() {

  // Khai báo 1 mảng ký tự có 100 phần tử
  // dùng để lưu trữ string người dùng nhập vào từ bàn phím.
  char s1[100];

  printf("Enter your string: \n");
  fflush(stdout);

  // Hàm scanf chờ đợi người dùng nhập vào.
  // Nó sẽ quét string (định dạng bởi %s) và truyền vào biến s1.
  // Chú ý định dạng %s sẽ quét lấy đoạn string đầu tiên không chứa khoảng trắng.
  scanf("%s", s1);

  printf("Your string = %s", s1);

  fflush(stdout);

  return 0;
}

Kết quả chạy ví dụ :

1.2- Các hàm cho C-style String

C cung cấp một số hàm để làm việc với String. Nó nằm trong thư viện chuẩn . Dưới đây tôi liệt kê một vài hàm thông dụng của C liên quan string (không phải là tất cả).

Bạn hoàn toàn có thể khám phá tại liệu về những hàm tiêu chuẩn của C tại :

  • TODO

Một số hàm cho String.

Tên hàm Mô tả
size_t strlen(const char *str) Tính toán độ dài của chuỗi, không tính ký tự kết thúc (ký tự null)
char *strcpy(char *dest, const char *src) Copy string ‘src’ sang cho ‘dest’.
int strcmp(const char *str1, const char *str2) So sánh hai string cho bởi tham số con trỏ str1, và str2. Nó trả về một số nguyên > 0 nghĩa là str1 > str2. Và = 0 nghĩa là 2 chuỗi giống nhau, ngược lại str1 < str2.
char *strcat(char *dest, const char *src) Appends the string pointed to by src to the end of the string pointed to by dest.
char *strchr(const char *str, int c) Searches for the first occurrence of the character c (an unsigned char) in the string pointed to by the argument str.

StringFunctionsExample. cpp


#include 

// Khai báo sử dụng thư viện string.h
#include 

int main() {

   // Khai báo một String (String literal).
   char s1[] = "This is ";

   // Khai báo một string theo kiểu khai báo mảng
   // Với phần tử null ở cuối.
   char s2[] = { 't', 'e', 'x', 't', '\0' };

   // Hàm: size_t strlen(const char *str)
   // Sử dụng hàm strlen để kiểm tra độ dài chuỗi.
   // size_t là kiểu dữ liệu số nguyên không dấu.
   size_t len1 = strlen(s1);
   size_t len2 = strlen(s2);

   printf("Length of s1 = %d \n", len1);
   printf("Length of s2 = %d \n", len2);

   // Khai báo một mảng ký tự có 100 phần tử
   // (100 phần tử là đủ dùng trong trường hợp này).
   char mystr[100];

   // Hàm: char *strcpy(char *dest, const char *src)
   // Copy string s1 vào mystr
   strcpy(mystr, s1);

   // Hàm: char *strcat(char *dest, const char *src)
   // Sử dụng hàm strcat để nối s2 vào mystr
   strcat(mystr, s2);

   // In ra nội dung của string.
   printf("Your string = %s", mystr);

   fflush(stdout);

   return 0;
}

Kết quả chạy ví dụ :

2- C++ Style String

C++ cung cấp cho bạn class string, nó giúp bạn làm việc dễ dàng hơn với các chuỗi. Các phương thức mà class string cung cấp vẫn hỗ trợ để làm việc với các C-Style string.

2.1- Khai báo thư viện string

Để sử dụng string bạn phải khai báo chỉ thị tiền sử lý (Preprocessor Directives) #include và khai báo sử dụng không gian tên std.


// Khai báo chỉ thị tiền sử lý (Preprocessor Directives)

#include 

// Khai báo sử dụng không gian tên std.

using namespace std;

Khai báo string :


// Khai báo một string.

string mystring = "Hello World";

// Nếu bạn không khai báo sử dụng namespace std.
// Bạn phải sử dụng tên đầy đủ:

std::string mystring = "Hello World";

2.2- Các phương thức của String

Dưới đây là danh sách các phương thức của String.

length() là một trong các phương thức thông dụng nhất của String, nó trả về độ dài chuỗi (Số ký tự của chuỗi).

LengthDemo. cpp


#include 
using namespace std;

int main() {
    string str = "This is text";
    int len = str.length();

    cout << "String Length is : " << len << endl;
    return 0;
}

Kết quả chạy ví dụ :

2.2.2- append

AppendDemo. cpp


#include 
using namespace std;

int main() {

      string s1 = "One";
      string s2 = "Two";
      string s3 = "Three";

      cout << "s1 = " + s1 << endl;
      cout << "s2 = " + s2 << endl;
      cout << "s3 = " + s3 << endl;
      cout << " ------------ " << endl;

      // Nối thêm s2 vào s1.
      // Làm thay đổi s1 và trả về tham chiếu của s1.
      string s = s1.append(s2);


      cout << "s1 = " + s1 << endl; // ==> OneTwo
      cout << "s = " + s << endl;   // ==> OneTwo

      cout << " ------------ " << endl;

      // Nối s2 và s3 vào s1.
      // Làm thay đổi s1 và trả về tham chiếu của s1.
      s = s1.append(s2).append(s3); // ==> OneTwoTwoThree

      cout << "s1.append(s2).append(s3) = " + s << endl;

}

Kết quả chạy ví dụ :

2.2.3- find

find là phương thức tìm vị trí xuất hiện của một chuỗi con trong chuỗi hiện tại. Phương thức này trả về hằng số string::npos nếu không tìm thấy.


FindDemo. cpp


#include 
using namespace std;

int main() {

   string str = "This is text";
 
   // Tìm vị trí xuất hiện ký tự 'i' đầu tiên.
   // ==> 2
   string::size_type idx = str.find('i');

   cout << "- find('i') = " << idx << endl;

 
   // Tìm vị trí xuất hiện ký tự 'i' đầu tiên
   // tính từ chỉ số thứ 4 trở về cuối chuỗi.
   // ==> 5
   idx = str.find('i', 4);
   cout << "- find('i',4) = " << idx << endl;

 
   // Tìm vị trí xuất hiện chuỗi con "te" đầu tiên.
   // ==> 8
   idx = str.find("te");
   cout << "- find('te') = " << idx << endl;

}

Kết quả chạy ví dụ :

2.2.4- substr


SubstrDemo. cpp


#include 
using namespace std;

int main() {

   string str = "This is text";

 
   // Trả về chuỗi con từ chỉ số thứ 3 tới cuối chuỗi.
   string substr = str.substr(3);

   cout << "- str.substr(3)=" << substr << endl;

 
   // Trả về chuỗi con từ chỉ số thứ 2 cho tới chỉ số 7
   substr = str.substr(2, 7);

   cout << "- str.substr(2, 7) =" << substr << endl;

}

Kết quả chạy ví dụ :

2.2.5- replace

Một số phương pháp tương quan tới sửa chữa thay thế .

ReplaceDemo. cpp


#include 
using namespace std;

int main() {

   string str = "This is text";

   // Thay thế các chuỗi con 4 ký tự bắt đầu từ vị trí 8
   // bởi chuỗi "string", và trả về tham chiếu
   string s2 = str.replace(8, 4, "string");

   cout << "- str=" << str << endl; // This is string
   cout << "- s2=" << s2 << endl;   // This is string
   cout << " -------------- " << endl;

   // Sét lại str
   str = "This is text";

   // Thay thế chuỗi con 4 ký tự bắt đầu từ chỉ số 8, bởi một chuỗi con của
   // một chuỗi khác, 6 ký tự bắt đầu từ chỉ số 0.
   // ==> It is string
   string s3 = str.replace(8, 4, "string is important", 0, 6);

   cout << "- str=" << str << endl; // It is string
   cout << "- s3=" + s3 << endl;    // It is string
   cout << " -------------- " << endl;

}

Kết quả chạy ví dụ :

Một ví dụ kết hợp giữa find & replace để thay thế tất cả các chuỗi con cụ thể bởi một chuỗi mới.

ReplaceAllDemo. cpp


#include 
using namespace std;

// Một hàm tiện ích tìm kiếm và thay thế các chuỗi con bởi một chuỗi mới.
// search: Chuỗi cần tìm.
// replace: Chuỗi thay thế.
string replaceAll(string subject, const string& search, const string& replace) {
   size_t pos = 0;
   // Hàm find sẽ trả về string::npos nếu không tìm thấy chuỗi con.
   while ((pos = subject.find(search, pos)) != string::npos) {
       subject.replace(pos, search.length(), replace);
       pos += replace.length();
   }
   return subject;
}

int main() {

   string str = "This is text";

   cout << "- str: " << str << endl;
   cout << " --------------------- " << endl;

   // Tìm kiếm các chuỗi con "is" và thay thế bởi "???"
   string result = replaceAll(str,"is", "???");


   cout << "- result: " << result << endl;
   cout << "- str: " << str << endl;
}

Chạy ví dụ :

2.2.6- insert

InsertDemo. cpp


#include 
using namespace std;

int main() {

    string str = "This text";

    string s2 = str.insert(5, "is ");

    cout << "- str=" << str << endl; // This is text
    cout << "- s2=" << s2 << endl;   // This is text
    cout << " -------------- " << endl;

}

Chạy ví dụ :

Mặc dù trong lớp string không cung cấp cho bạn một phương thức nào để chuyển đổi một chuỗi thành chuỗi chữ hoa hoặc chuỗi chữ thường, nhưng bạn có thể làm điều đó với các thư viện khác trong C++.

Sử dụng hàm transform của không gian tên (namespace) std:

UpperLowerDemo1. cpp


#include 
#include 
#include 

using namespace std;

int main() {

   string str = "This is text";

   cout << "- str= " << str << endl;

   cout << " ----------------"  << endl;

   // Chuyển thành chữ hoa
   std::transform(str.begin(), str.end(),str.begin(), ::toupper);


   cout << "- str= " << str << endl;

   // Reset str
   str =  "This is text";

   cout << " -------------- " << endl;

   // Chuyển thành chữ thường.
   std::transform(str.begin(), str.end(),str.begin(), ::tolower);

   cout << "- str= " << str << endl;
}

Chạy ví dụ :