天天看点

C++标准库 第十三章 字符串--上半节

作者:明政面朝大海春暖花开

C++标准库中的String Class是用来处理字符串的类。它提供了一系列的成员函数和操作符,可以方便地进行字符串的操作和处理。

String Class的目的是为了简化字符串的操作和管理。它封装了字符串的存储和操作细节,使得程序员可以更加专注于字符串的逻辑处理,而不需要关注底层的内存管理和字符串操作的细节。

举例来说,我们可以使用String Class来创建一个字符串对象,并对其进行各种操作,比如拼接、截取、查找等等。下面是一个使用String Class的简单示例:

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";

    // 字符串拼接
    std::string result = str1 + " " + str2;

    // 字符串长度
    std::cout << "Length: " << result.length() << std::endl;

    // 字符串查找
    if (result.find("World") != std::string::npos) {
        std::cout << "Found!" << std::endl;
    }

    return 0;
}
           

在上面的示例中,我们使用了String Class的成员函数来进行字符串的拼接、长度获取和查找操作。这些操作都是通过String Class提供的方法来实现的,使得代码更加简洁和易读。

总而言之,C++标准库中的String Class的目的是为了提供一种方便、高效的方式来处理字符串,使得程序员可以更加专注于字符串的逻辑处理,而不需要关注底层的实现细节。

std::string::npos是一个std::string类中的静态成员常量,表示一个无效的或无法找到的位置。

std::string::npos的值是一个特定的标记值,通常被定义为-1,表示在字符串中无法找到指定的子字符串或字符。

在字符串的相关操作中,std::string::npos常常用于表示找不到匹配的位置或结束标志。

例如,可以使用std::string::find()函数来查找一个子字符串在另一个字符串中的位置,如果找不到该子字符串,则返回std::string::npos。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    std::size_t pos = str.find("abc"); // 在str中查找子字符串"abc"
    
    if (pos == std::string::npos) {
        std::cout << "Subtring not found." << std::endl;
    } else {
        std::cout << "Substring found at position: " << pos << std::endl;
    }
    
    return 0;
}
           

输出结果:

Substring not found.
           

在上述示例中,由于字符串"abc"在str中不存在,因此find()函数返回std::string::npos,表示未找到子字符串。

在C++标准库中,可以使用临时文件名来创建临时文件,这在一些需要临时存储数据的场景中非常有用。通过使用C++标准库中的函数,可以生成唯一的临时文件名,以确保文件名的唯一性和避免冲突。

举例来说,可以使用C++标准库中的函数std::tmpnam来生成临时文件名。该函数接受一个字符数组作为参数,将生成的临时文件名存储在该数组中。下面是一个示例代码:

#include <iostream>
#include <cstdio>

int main() {
    char filename[L_tmpnam];
    std::tmpnam(filename);
    std::cout << "临时文件名:" << filename << std::endl;
    return 0;
}
           

运行以上代码,将会输出一个唯一的临时文件名,例如:

临时文件名:C:\Users\Username\AppData\Local\Temp\fileS7T8Zf
           

这样,我们就可以使用生成的临时文件名来创建临时文件,并进行相应的操作。需要注意的是,std::tmpnam函数并不能保证生成的临时文件名是安全的,因此在实际使用中需要注意安全性。

C++标准库中的String Class是用于处理字符串的类。它提供了许多成员函数和操作符重载,使得对字符串的操作更加方便和高效。

String Class的细节描述如下:

  1. 构造函数:String Class提供了多个构造函数,可以使用不同的方式来创建字符串对象。例如:
  2. String str; // 默认构造函数,创建一个空字符串
  3. String str("Hello"); // 使用C风格字符串创建字符串对象
  4. String str2(str); // 使用另一个字符串对象来初始化新的字符串对象
  5. 成员函数:
  6. length():返回字符串的长度。
  7. empty():检查字符串是否为空。
  8. clear():清空字符串内容。
  9. append():将一个字符串追加到当前字符串的末尾。
  10. substr():返回一个子字符串,可以指定起始位置和长度。
  11. find():在字符串中查找指定的子字符串,并返回第一次出现的位置。
  12. 操作符重载:
  13. =:用于字符串的赋值操作。
  14. +:用于字符串的拼接操作。
  15. []:用于访问字符串中的单个字符。

举例:

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";

    std::string str3 = str1 + " " + str2; // 字符串拼接
    std::cout << str3 << std::endl; // 输出:Hello World

    std::cout << str3.length() << std::endl; // 输出:11

    std::string subStr = str3.substr(0, 5); // 提取子字符串
    std::cout << subStr << std::endl; // 输出:Hello

    int index = str3.find("World"); // 查找子字符串
    std::cout << index << std::endl; // 输出:6

    return 0;
}
           

上述代码演示了如何使用String Class来操作字符串。首先,我们创建了两个字符串对象str1和str2,然后使用+操作符将它们拼接成一个新的字符串对象str3。接着,我们使用length()函数获取字符串的长度,并使用substr()函数提取出子字符串。最后,我们使用find()函数查找子字符串的位置。

C++标准库中的String类是用来处理字符串的类。它提供了各种方法和操作符,用于处理字符串的创建、修改、查找、比较等操作。下面是C++标准库String类的一些相关类型的解释及举例:

  1. std::string:这是String类的主要类型,用于表示字符串。它是一个可变长度的字符序列,可以包含任意字符,包括空字符。举例:
std::string str = "Hello World!";
std::cout << str << std::endl;  // 输出:Hello World!
           
  1. std::wstring:这是String类的宽字符版本,用于表示宽字符串。它使用wchar_t类型表示字符,可以包含任意Unicode字符。举例:
std::wstring wstr = L"你好,世界!";
std::wcout << wstr << std::endl;  // 输出:你好,世界!
           
  1. std::u16string:这是String类的UTF-16版本,用于表示UTF-16编码的字符串。它使用char16_t类型表示字符,可以包含任意Unicode字符。举例:
std::u16string u16str = u"こんにちは、世界!";
std::wcout << u16str << std::endl;  // 输出:こんにちは、世界!
           
  1. std::u32string:这是String类的UTF-32版本,用于表示UTF-32编码的字符串。它使用char32_t类型表示字符,可以包含任意Unicode字符。举例:
std::u32string u32str = U"안녕하세요, 세상!";
std::wcout << u32str << std::endl;  // 输出:안녕하세요, 세상!
           

这些类型都是String类的不同版本,用于处理不同的字符编码和字符集。可以根据具体需要选择适合的类型来操作字符串。

C++标准库提供了许多操作函数来处理字符串。下面是一些常用的操作函数的概览:

  1. size():返回字符串的长度。
  2. std::string str = "Hello"; std::cout << str.size(); // 输出 5
  3. length():返回字符串的长度,与size()功能相同。
  4. std::string str = "Hello"; std::cout << str.length(); // 输出 5
  5. empty():检查字符串是否为空。
  6. std::string str = "Hello"; if (str.empty()) { std::cout << "字符串为空"; } else { std::cout << "字符串不为空"; }
  7. clear():清空字符串内容。
  8. std::string str = "Hello"; str.clear(); std::cout << str; // 输出空字符串
  9. push_back(char c):在字符串末尾添加一个字符。
  10. std::string str = "Hello"; str.push_back('!'); std::cout << str; // 输出 "Hello!"
  11. pop_back():删除字符串末尾的一个字符。
  12. std::string str = "Hello!"; str.pop_back(); std::cout << str; // 输出 "Hello"
  13. insert(pos, str):在指定位置插入一个字符串。
  14. std::string str = "Hello"; str.insert(2, " world"); std::cout << str; // 输出 "He worldllo"
  15. erase(pos, len):删除指定位置开始的指定长度的字符。
  16. std::string str = "Hello world"; str.erase(6, 5); std::cout << str; // 输出 "Hello"
  17. replace(pos, len, str):用指定字符串替换从指定位置开始的指定长度的字符。
  18. std::string str = "Hello world"; str.replace(6, 5, "C++"); std::cout << str; // 输出 "Hello C++"
  19. substr(pos, len):返回从指定位置开始的指定长度的子字符串。
  20. std::string str = "Hello world"; std::string sub = str.substr(6, 5); std::cout << sub; // 输出 "world"

这些操作函数可以帮助我们对字符串进行常见的操作,如获取长度、判断是否为空、添加、删除、插入、替换和提取子字符串等。

C++标准库中的字符串类(std::string)提供了多个构造函数和析构函数,用于创建和销毁字符串对象。

构造函数用于创建字符串对象,可以接受不同类型的参数:

  1. 默认构造函数:创建一个空字符串对象。
  2. std::string str; // 创建一个空字符串对象
  3. 字符串字面值构造函数:接受一个字符串字面值参数,创建一个字符串对象。
  4. std::string str("Hello"); // 创建一个字符串对象,内容为"Hello"
  5. 拷贝构造函数:接受一个字符串对象作为参数,创建一个新的字符串对象,内容和参数相同。
  6. std::string str1("Hello"); std::string str2(str1); // 创建一个新的字符串对象,内容和str1相同
  7. 带起始位置和长度的构造函数:接受一个字符串对象、起始位置和长度作为参数,创建一个新的字符串对象,内容为参数指定位置和长度的子串。
  8. std::string str1("Hello World"); std::string str2(str1, 6, 5); // 创建一个新的字符串对象,内容为"World"

析构函数用于销毁字符串对象,在对象被销毁时自动调用,释放对象占用的内存。

std::string str("Hello");
// 对象str在这里超出了作用域,析构函数被调用,释放内存           

C++标准库中的字符串类(std::string)和C-字符串(C-String)是两种不同的字符串表示方式。

  1. 字符串类(std::string)是C++标准库提供的字符串类型,它是一个类模板,封装了字符串的操作和功能。使用字符串类可以方便地进行字符串的操作和处理。
  2. #include <iostream> #include <string> int main() { std::string str = "Hello"; std::cout << str << std::endl; // 输出 Hello str += " World"; std::cout << str << std::endl; // 输出 Hello World return 0; }
  3. C-字符串是以字符数组的形式表示的字符串,以null字符('\0')作为字符串的结束标志。C-字符串使用C语言的字符数组和字符指针来表示和操作。
  4. #include <iostream> #include <cstring> int main() { char str[6] = "Hello"; std::cout << str << std::endl; // 输出 Hello strcat(str, " World"); std::cout << str << std::endl; // 输出 Hello World return 0; }

需要注意的是,C++标准库中的字符串类和C-字符串是不兼容的,不能直接进行赋值或比较操作。如果需要将字符串类和C-字符串进行转换,可以使用字符串类的成员函数c_str()和C-字符串的转换函数std::string()。

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello";
    const char* cstr = str.c_str();
    std::cout << cstr << std::endl; // 输出 Hello

    std::string newStr = std::string(cstr);
    std::cout << newStr << std::endl; // 输出 Hello

    return 0;
}           

在C++标准库中,字符串类(std::string)提供了两个成员函数来获取字符串的大小和容量。

  1. 大小(Size):字符串的大小指的是字符串中字符的个数,不包括结尾的空字符。可以使用成员函数size()或length()来获取字符串的大小。
  2. std::string str = "Hello"; int size = str.size(); // 获取字符串的大小,size的值为5
  3. 容量(Capacity):字符串的容量指的是为字符串分配的内存空间的大小。可以使用成员函数capacity()来获取字符串的容量。
  4. std::string str = "Hello"; int capacity = str.capacity(); // 获取字符串的容量,capacity的值可能大于等于5

需要注意的是,字符串的大小和容量不总是相等的。当字符串的大小超过了当前容量时,字符串会自动重新分配更大的内存空间来容纳更多的字符。这个过程称为动态内存分配。因此,字符串的容量可能会大于其大小。

在C++标准库中,字符串类(std::string)提供了多种方法来访问字符串的元素。

  1. 使用下标运算符[]:可以使用下标运算符[]来访问字符串中的单个字符。下标从0开始,可以使用正整数或负整数作为索引。
  2. #include <iostream> #include <string> int main() { std::string str = "Hello"; char ch1 = str[0]; // 访问第一个字符 'H' char ch2 = str[4]; // 访问最后一个字符 'o' std::cout << ch1 << " " << ch2 << std::endl; return 0; }
  3. 使用at()函数:at()函数与下标运算符类似,可以用来访问字符串中的单个字符。但是,与下标运算符不同的是,at()函数会进行边界检查,如果索引超出了字符串的范围,会抛出一个std::out_of_range异常。
  4. #include <iostream> #include <string> int main() { std::string str = "Hello"; char ch1 = str.at(0); // 访问第一个字符 'H' char ch2 = str.at(4); // 访问最后一个字符 'o' std::cout << ch1 << " " << ch2 << std::endl; return 0; }
  5. 使用front()和back()函数:front()函数用于访问字符串的第一个字符,back()函数用于访问字符串的最后一个字符。
  6. #include <iostream> #include <string> int main() { std::string str = "Hello"; char first = str.front(); // 访问第一个字符 'H' char last = str.back(); // 访问最后一个字符 'o' std::cout << first << " " << last << std::endl; return 0; }

总结:字符串类提供了多种方法来访问字符串的元素,包括下标运算符[]、at()函数、front()函数和back()函数。可以根据需要选择合适的方法来访问字符串中的元素。

在C++标准库中,字符串类(std::string)提供了多种方法来比较字符串的内容。

  1. 使用比较运算符:可以使用比较运算符(==、!=、<、>、<=、>=)来比较两个字符串的内容。比较运算符会按照字典序比较字符串的字符。
  2. #include <iostream> #include <string> int main() { std::string str1 = "Hello"; std::string str2 = "World"; if (str1 == str2) { std::cout << "str1 is equal to str2" << std::endl; } else if (str1 < str2) { std::cout << "str1 is less than str2" << std::endl; } else { std::cout << "str1 is greater than str2" << std::endl; } return 0; }
  3. 使用成员函数compare():字符串类提供了成员函数compare()来比较两个字符串的内容。compare()函数返回一个整数,表示两个字符串的比较结果。如果返回值为0,则表示两个字符串相等;如果返回值小于0,则表示第一个字符串小于第二个字符串;如果返回值大于0,则表示第一个字符串大于第二个字符串。
  4. #include <iostream> #include <string> int main() { std::string str1 = "Hello"; std::string str2 = "World"; int result = str1.compare(str2); if (result == 0) { std::cout << "str1 is equal to str2" << std::endl; } else if (result < 0) { std::cout << "str1 is less than str2" << std::endl; } else { std::cout << "str1 is greater than str2" << std::endl; } return 0; }

总结:字符串类提供了比较运算符和compare()函数来比较字符串的内容。可以根据需要选择合适的方法来进行字符串的比较。

在C++标准库中,字符串类(std::string)提供了多种方法来修改字符串的内容。

  1. 使用赋值运算符=:可以使用赋值运算符=来将一个字符串赋值给另一个字符串。
  2. #include <iostream> #include <string> int main() { std::string str1 = "Hello"; std::string str2 = "World"; str1 = str2; // 将str2的内容赋值给str1 std::cout << str1 << std::endl; // 输出 "World" return 0; }
  3. 使用assign()函数:assign()函数可以用来将一个字符串赋值给另一个字符串,或者将一个子字符串赋值给另一个字符串的一部分。
  4. #include <iostream> #include <string> int main() { std::string str1 = "Hello"; std::string str2 = "World"; str1.assign(str2); // 将str2的内容赋值给str1 std::cout << str1 << std::endl; // 输出 "World" std::string str3 = "Hello"; std::string str4 = "World"; str3.assign(str4, 0, 3); // 将str4的前三个字符赋值给str3 std::cout << str3 << std::endl; // 输出 "Wor" return 0; }
  5. 使用insert()函数:insert()函数可以在指定位置插入一个字符串或字符。
  6. #include <iostream> #include <string> int main() { std::string str = "Hello"; str.insert(2, "World"); // 在位置2插入字符串 "World" std::cout << str << std::endl; // 输出 "HeWorldllo" str.insert(5, 1, '-'); // 在位置5插入字符 '-' std::cout << str << std::endl; // 输出 "HeWor-ldllo" return 0; }
  7. 使用erase()函数:erase()函数可以删除指定位置的字符或一段字符。
  8. #include <iostream> #include <string> int main() { std::string str = "Hello World"; str.erase(5, 5); // 删除从位置5开始的5个字符 std::cout << str << std::endl; // 输出 "Hello" str.erase(2); // 删除从位置2开始到末尾的所有字符 std::cout << str << std::endl; // 输出 "He" return 0; }

总结:字符串类提供了多种方法来修改字符串的内容,包括赋值运算符=、assign()函数、insert()函数和erase()函数。可以根据需要选择合适的方法来修改字符串的内容。

在C++标准库中,字符串类(std::string)提供了子字符串和字符串接合的功能。

  1. 子字符串:可以使用substr()函数来获取原字符串的子字符串。该函数接受两个参数,第一个参数是子字符串的起始位置,第二个参数是子字符串的长度。
  2. #include <iostream> #include <string> int main() { std::string str = "Hello World"; std::string subStr = str.substr(6, 5); // 获取从位置6开始的长度为5的子字符串 std::cout << "Sub String: " << subStr << std::endl; return 0; }
  3. 输出结果为:Sub String: World
  4. 字符串接合:可以使用+运算符或append()函数来将两个字符串连接起来。
  5. #include <iostream> #include <string> int main() { std::string str1 = "Hello"; std::string str2 = "World"; std::string result = str1 + " " + str2; // 使用+运算符连接字符串 std::cout << "Concatenated String: " << result << std::endl; str1.append(" "); // 使用append()函数连接字符串 str1.append(str2); std::cout << "Concatenated String: " << str1 << std::endl; return 0; }
  6. 输出结果为:Concatenated String: Hello World

在C++标准库中,I/O操作符(输入/输出操作符)用于从输入流(如键盘、文件)读取数据或将数据写入输出流(如屏幕、文件)。

  1. 输入操作符(>>):用于从输入流中读取数据并将其存储到变量中。
  2. #include <iostream> int main() { int num; std::cout << "Enter a number: "; std::cin >> num; // 从键盘读取一个整数 std::cout << "You entered: " << num << std::endl; return 0; }
  3. 输出操作符(<<):用于将数据写入输出流。
  4. #include <iostream> int main() { std::cout << "Hello, World!" << std::endl; // 将字符串输出到屏幕 return 0; }

这些操作符可以用于各种数据类型,包括整数、浮点数、字符、字符串等。

在C++标准库中,npos是一个常量,表示无效的或不存在的位置。

它通常与字符串类(如std::string)的成员函数find()一起使用,用于指示未找到匹配项的情况。

举例来说,假设我们有一个字符串str,我们想要查找子字符串"abc"的位置:

#include <iostream>
#include <string>

int main() {
    std::string str = "defghijklm";
    std::string subStr = "abc";

    size_t found = str.find(subStr);
    if (found != std::string::npos) {
        std::cout << "Substring found at position: " << found << std::endl;
    } else {
        std::cout << "Substring not found" << std::endl;
    }

    return 0;
}
           

在上面的例子中,由于字符串str中不存在子字符串"abc",find()函数返回了npos,因此输出结果为"Substring not found"。

npos的值是一个特定的无符号整数,通常是一个很大的值(如std::string::npos的值是-1)。因此,我们可以通过检查find()函数的返回值是否等于npos来判断是否找到了匹配项。

在C++标准库中,数值转换是指将不同类型的数值进行转换的过程。C++标准库提供了一些函数和类来执行数值转换操作。

  1. stoi()和stol():这些函数用于将字符串转换为整数或长整数。例如:
#include <iostream>
#include <string>

int main() {
    std::string str = "12345";
    int num = std::stoi(str);
    std::cout << num << std::endl; // 输出:12345
    return 0;
}
           
  1. to_string():这个函数用于将数字转换为字符串。例如:
#include <iostream>
#include <string>

int main() {
    int num = 12345;
    std::string str = std::to_string(num);
    std::cout << str << std::endl; // 输出:12345
    return 0;
}
           
  1. stringstream类:这个类可以用于在字符串和数值之间进行转换。例如:
#include <iostream>
#include <string>
#include <sstream>

int main() {
    std::string str = "12345";
    int num;
    std::stringstream ss(str);
    ss >> num;
    std::cout << num << std::endl; // 输出:12345

    num = 67890;
    std::stringstream ss2;
    ss2 << num;
    std::string str2 = ss2.str();
    std::cout << str2 << std::endl; // 输出:67890

    return 0;
}
           

这些是C++标准库中一些常用的数值转换函数和类的例子。它们可以帮助我们在不同的数值类型之间进行转换,方便数据处理和操作。

在C++标准库中,字符串类std::string提供了对迭代器的支持。迭代器是一种类似指针的对象,可以用于遍历容器中的元素。

std::string类提供了begin()和end()成员函数,用于获取指向字符串的第一个字符和最后一个字符之后的位置的迭代器。这样,我们可以使用迭代器来遍历字符串中的每个字符。

以下是一个示例:

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";
    
    // 使用迭代器遍历字符串
    for (auto it = str.begin(); it != str.end(); ++it) {
        std::cout << *it;
    }
    
    return 0;
}
           

输出结果为:

Hello, World!
           

在上面的示例中,我们使用迭代器it来遍历字符串str中的每个字符,并使用*it来访问迭代器指向的字符。

在C++标准库中,国际化(Internationalization)是指为了适应不同地区和语言的需求,提供了一些函数和类来处理多语言和多地区的问题。

C++标准库中的国际化支持主要通过locale类来实现。locale类提供了一种机制,可以根据特定的地区和语言设置来调整程序的行为。

例如,可以使用locale类的facet来设置日期、时间、货币、数字格式等。下面是一个示例:

#include <iostream>
#include <locale>

int main() {
    std::locale::global(std::locale("")); // 设置当前地区的默认locale

    std::cout.imbue(std::locale()); // 使用默认locale来格式化输出

    double num = 12345.6789;
    std::cout << num << std::endl; // 输出:12,345.6789

    return 0;
}
           

在这个示例中,使用std::locale::global()函数设置了当前地区的默认locale为系统默认的地区设置。然后使用std::cout.imbue()函数将默认locale应用于std::cout流,以便在输出时使用正确的数字格式。最后输出一个浮点数,会根据地区的不同而使用适当的数字格式。

在C++标准库中,效率(Performance)是指库中的函数和类在执行时所消耗的时间和资源的数量。C++标准库的设计目标之一就是提供高效的实现,以最大限度地减少执行时间和资源消耗。

C++标准库提供了许多经过优化的算法和数据结构,以提高程序的执行效率。例如,标准库中的容器类(如std::vector、std::list、std::map等)都是经过优化的数据结构,它们在插入、删除和访问元素时都具有高效的性能。

另外,标准库中的算法函数(如std::sort、std::find、std::accumulate等)也经过了优化,以提供高效的执行速度。这些算法函数使用了各种优化技术,如使用快速排序算法、二分查找算法等,以提高执行效率。

以下是一个示例,展示了如何使用C++标准库中的算法函数来实现对一个数组的排序:

#include <iostream>
#include <algorithm>

int main() {
    int arr[] = {5, 2, 8, 1, 9};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    std::sort(arr, arr + size);
    
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    
    return 0;
}
           

该示例使用std::sort函数对数组进行排序,std::sort函数使用了高效的排序算法来提高执行效率。

C++标准库中的String和Vector是两个常用的容器类。

String类是用于处理字符串的类,提供了一系列的成员函数来进行字符串的操作。例如,可以使用String类的成员函数来获取字符串的长度、连接字符串、截取子串等。下面是一个使用String类的示例:

#include <iostream>
#include <string>

int main() {
    std::string str1 = "Hello";
    std::string str2 = "World";

    std::string str3 = str1 + " " + str2; // 连接字符串
    std::cout << str3 << std::endl; // 输出 "Hello World"

    std::string subStr = str3.substr(6, 5); // 截取子串
    std::cout << subStr << std::endl; // 输出 "World"

    return 0;
}
           

Vector类是一个动态数组容器,可以在运行时动态地调整数组的大小。Vector类提供了一系列的成员函数来进行数组的操作。例如,可以使用Vector类的成员函数来添加元素、删除元素、访问元素等。下面是一个使用Vector类的示例:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec;

    vec.push_back(1); // 添加元素
    vec.push_back(2);
    vec.push_back(3);

    std::cout << "Size: " << vec.size() << std::endl; // 输出数组大小

    vec.pop_back(); // 删除最后一个元素

    std::cout << "Size: " << vec.size() << std::endl; // 输出数组大小

    std::cout << "Elements: ";
    for (int i : vec) {
        std::cout << i << " "; // 输出数组元素
    }
    std::cout << std::endl;

    return 0;
}
           

这是使用C++标准库中String和Vector的基本示例,它们是非常常用的容器类,可以方便地进行字符串和数组的操作。

C++标准库中的String类是用于处理字符串的类,它提供了一系列的成员函数和操作符重载,方便进行字符串的操作。

String类的特点包括:

  1. 动态内存管理:String类会自动管理字符串的内存,无需手动分配和释放内存。
  2. 可变性:String类中的字符串是可变的,可以通过成员函数修改字符串的内容。
  3. 字符串操作:String类提供了丰富的字符串操作函数,如字符串的拼接、查找、替换、截取等。

下面是一个使用String类的简单示例:

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World!";

    // 获取字符串长度
    std::cout << "Length: " << str.length() << std::endl;

    // 字符串拼接
    str += " I'm C++.";
    std::cout << "Concatenated string: " << str << std::endl;

    // 查找子串
    std::size_t found = str.find("C++");
    if (found != std::string::npos) {
        std::cout << "Substring found at index: " << found << std::endl;
    } else {
        std::cout << "Substring not found." << std::endl;
    }

    // 替换子串
    str.replace(found, 3, "C++ programming");
    std::cout << "Replaced string: " << str << std::endl;

    return 0;
}
           

输出结果:

Length: 13
Concatenated string: Hello, World! I'm C++.
Substring found at index: 17
Replaced string: Hello, World! I'm C++ programming.
           

在这个示例中,我们使用了String类的length()函数获取字符串的长度,使用+=操作符进行字符串的拼接,使用find()函数查找子串的位置,使用replace()函数替换子串。

C++标准库中定义了许多常用的类型和静态值,这些定义可以在程序中直接使用,无需额外的声明或定义。

一些常用的类型定义包括:

  1. size_t:无符号整数类型,用于表示对象的大小或数组的长度。
  2. iterator:迭代器类型,用于遍历容器中的元素。
  3. string:字符串类型,用于表示文本数据。
  4. vector:向量类型,用于表示可变长度的数组。
  5. map:映射类型,用于表示键值对的集合。

一些常用的静态值包括:

  1. nullptr:表示空指针。
  2. true和false:表示布尔类型的真和假。
  3. numeric_limits<T>::max():表示类型T的最大值。
  4. numeric_limits<T>::min():表示类型T的最小值。

以下是一个使用C++标准库类型定义和静态值的示例:

#include <iostream>
#include <cstddef>
#include <vector>
#include <string>

int main() {
    size_t size = 10;
    std::vector<int> numbers(size);
    
    for (size_t i = 0; i < size; i++) {
        numbers[i] = i;
    }
    
    std::string message = "Hello, world!";
    
    std::cout << "Size of numbers vector: " << numbers.size() << std::endl;
    std::cout << "Message: " << message << std::endl;
    
    return 0;
}
           

在上面的示例中,使用了size_t类型来表示向量的大小,使用vector类型来定义一个可变长度的数组,使用string类型来表示一个字符串。同时,使用了cout和endl来输出结果。

在C++标准库中,创建、复制和销毁是针对容器和对象的三个重要操作。

  1. 创建(Create):创建操作用于创建容器或对象的实例。在C++标准库中,我们可以使用类模板来创建容器,例如vector、list等。同时,也可以使用类的构造函数来创建对象。
  2. 复制(Copy):复制操作用于将一个容器或对象的值复制到另一个容器或对象中。在C++标准库中,提供了复制构造函数和赋值运算符重载函数,用于实现容器和对象的复制。
  3. 销毁(Destroy):销毁操作用于释放容器或对象占用的资源,并将其从内存中删除。在C++标准库中,提供了析构函数来实现容器和对象的销毁。

下面是一个使用C++标准库进行创建、复制和销毁操作的示例:

#include <iostream>
#include <vector>

class MyClass {
public:
    MyClass() {
        std::cout << "Creating MyClass object" << std::endl;
    }
    
    MyClass(const MyClass& other) {
        std::cout << "Copying MyClass object" << std::endl;
    }
    
    ~MyClass() {
        std::cout << "Destroying MyClass object" << std::endl;
    }
};

int main() {
    std::vector<MyClass> vec;
    
    // 创建容器并添加对象
    vec.push_back(MyClass());
    
    // 复制容器
    std::vector<MyClass> vec2 = vec;
    
    // 销毁容器
    vec.clear();
    
    return 0;
}
           

在上面的示例中,我们定义了一个名为MyClass的类,其中包含了构造函数、复制构造函数和析构函数。然后,我们创建了一个vector容器,并在其中添加了一个MyClass对象。接着,我们使用赋值运算符将vec复制给vec2。最后,我们通过调用clear()函数销毁了vec容器中的所有对象。

输出结果:

Creating MyClass object
Copying MyClass object
Destroying MyClass object
Destroying MyClass object           

在C++标准库中,比较(Comparison)是用于比较容器和对象之间的大小关系的操作。

比较操作通常用于判断两个容器或对象是否相等、大小关系等。在C++标准库中,比较操作符和函数被提供用于实现这些比较操作。

以下是一些常用的比较操作符和函数:

  1. 比较操作符:C++标准库提供了一系列的比较操作符,如==、!=、<、>、<=、>=等,用于比较容器和对象之间的大小关系。例如:
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {1, 2, 3};

if (vec1 == vec2) {
    // vec1和vec2相等
}

if (vec1 < vec2) {
    // vec1小于vec2
}
           
  1. 比较函数:C++标准库还提供了一些比较函数,如std::equal、std::lexicographical_compare等,用于比较容器和对象之间的大小关系。例如:
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {1, 2, 3};

if (std::equal(vec1.begin(), vec1.end(), vec2.begin())) {
    // vec1和vec2相等
}

if (std::lexicographical_compare(vec1.begin(), vec1.end(), vec2.begin(), vec2.end())) {
    // vec1小于vec2
}
           

通过比较操作,我们可以判断容器和对象之间的大小关系,从而进行相应的处理。

  1. 符:
#include <iostream>
#include <string>
#include <algorithm>

int main() {
    std::string str = "Hello, World!";
    
    // 使用算法访问字符
    char c = *std::find(str.begin(), str.end(), 'W'); // 使用find算法查找字符
    std::cout << "Character found: " << c << std::endl;
    
    return 0;
}
           

以上示例展示了如何使用索引、迭代器和算法来访问字符串或字符序列中的单个字符。

在C++标准库中,可以使用多种方法来生成C-String(以null结尾的字符数组)和字符数组。

  1. 使用字符串字面值生成C-String:
  2. const char* cString = "Hello World";
  3. 使用字符数组生成C-String:
  4. char charArray[] = {'H', 'e', 'l', 'l', 'o', '\0'}; const char* cString = charArray;
  5. 使用字符串对象生成C-String:
  6. std::string str = "Hello World"; const char* cString = str.c_str();
  7. 使用字符数组生成字符数组:
  8. char charArray[] = {'H', 'e', 'l', 'l', 'o'}; char charArray2[6]; std::copy(std::begin(charArray), std::end(charArray), std::begin(charArray2));

在上述示例中,我们使用了不同的方法来生成C-String和字符数组。注意在生成C-String时,我们需要确保字符串以null字符('\0')结尾,以便正确表示字符串的结束。

在C++标准库中,有多种操作可以对字符串进行修改。

  1. 修改字符:
  2. 使用索引修改字符:
  3. std::string str = "Hello World"; str[0] = 'h'; // 将第一个字符改为小写
  4. 使用迭代器修改字符:
  5. std::string str = "Hello World"; std::string::iterator it = str.begin(); *it = 'h'; // 将第一个字符改为小写
  6. 插入字符:
  7. 使用insert函数在指定位置插入字符:std::string str = "Hello"; str.insert(5, " World"); // 在第5个位置插入字符串 " World"
  8. 删除字符:
  9. 使用erase函数删除指定位置的字符:
  10. std::string str = "Hello World"; str.erase(5); // 删除第5个字符
  11. 使用erase函数删除指定范围的字符:
  12. std::string str = "Hello World"; str.erase(6, 5); // 删除从第6个字符开始的5个字符
  13. 替换字符:
  14. 使用replace函数替换指定位置的字符:
  15. std::string str = "Hello World"; str.replace(0, 5, "Hi"); // 将前5个字符替换为 "Hi"
  16. 使用replace函数替换指定范围的字符:
  17. std::string str = "Hello World"; str.replace(6, 5, "Universe"); // 将从第6个字符开始的5个字符替换为 "Universe"

在C++标准库中,有多种方法可以进行字符串的查找和定位。

  1. find()函数:用于在字符串中查找指定的子字符串,并返回第一次出现的位置。
  2. std::string str = "Hello World"; size_t found = str.find("World"); // 返回6,表示子字符串"World"在字符串中的位置
  3. rfind()函数:用于在字符串中从后往前查找指定的子字符串,并返回最后一次出现的位置。
  4. std::string str = "Hello World"; size_t found = str.rfind("o"); // 返回7,表示子字符串"o"最后一次出现的位置
  5. find_first_of()函数:用于在字符串中查找任意一个指定的字符,并返回第一次出现的位置。
  6. std::string str = "Hello World"; size_t found = str.find_first_of("o"); // 返回4,表示字符"o"第一次出现的位置
  7. find_last_of()函数:用于在字符串中从后往前查找任意一个指定的字符,并返回最后一次出现的位置。
  8. std::string str = "Hello World"; size_t found = str.find_last_of("o"); // 返回7,表示字符"o"最后一次出现的位置
  9. find_first_not_of()函数:用于在字符串中查找第一个不属于指定字符集的字符,并返回其位置。
  10. std::string str = "Hello World"; size_t found = str.find_first_not_of("Helo "); // 返回5,表示第一个不属于字符集"Helo "的字符位置
  11. find_last_not_of()函数:用于在字符串中从后往前查找第一个不属于指定字符集的字符,并返回其位置。
  12. std::string str = "Hello World"; size_t found = str.find_last_not_of("dlroW"); // 返回8,表示最后一个不属于字符集"dlroW"的字符位置

在C++标准库中,有多种方法可以处理子字符串和字符串的连接。

  1. 子字符串:
  2. substr()函数:用于从一个字符串中提取子字符串。std::string str = "Hello World"; std::string sub = str.substr(6, 5); // 从位置6开始提取长度为5的子字符串
  3. 字符串连接:
  4. 使用"+"运算符:可以将两个字符串连接起来。
  5. std::string str1 = "Hello"; std::string str2 = "World"; std::string result = str1 + " " + str2; // 连接两个字符串
  6. 使用append()函数:将一个字符串追加到另一个字符串的末尾。
  7. std::string str1 = "Hello"; std::string str2 = "World"; str1.append(" "); // 在str1的末尾追加一个空格 str1.append(str2); // 将str2追加到str1的末尾
  1. 准输出设备(通常是屏幕)输出数据。
  2. int num = 10; std::cout << "The number is: " << num << std::endl; // 输出 "The number is: 10"
  3. cerr:用于向标准错误设备(通常是屏幕)输出错误信息。
  4. std::cerr << "Error: Invalid input!" << std::endl; // 输出错误信息
  5. clog:用于向标准错误设备(通常是屏幕)输出一般信息。
  6. std::clog << "Processing..." << std::endl; // 输出一般信息

这些函数可以用于处理各种输入和输出操作,从控制台读取用户输入,向控制台输出结果,以及处理文件的输入输出等。

在C++标准库中,有多种方法可以进行数值转换。

  1. 字符串转换为数值:
  2. stoi()函数:用于将字符串转换为整数。
  3. std::string str = "12345"; int num = std::stoi(str); // 将字符串转换为整数
  4. stof()函数:用于将字符串转换为浮点数。
  5. std::string str = "3.14"; float num = std::stof(str); // 将字符串转换为浮点数
  6. 数值转换为字符串:
  7. to_string()函数:用于将数值转换为字符串。
  8. int num = 12345; std::string str = std::to_string(num); // 将整数转换为字符串
  9. to_string()函数:用于将浮点数转换为字符串。
  10. float num = 3.14; std::string str = std::to_string(num); // 将浮点数转换为字

在C++标准库中,可以使用生成器(Generator)来生成迭代器(Iterator)。

生成器是一种可以生成序列的函数或类,而迭代器是一种用于遍历序列的对象。

C++标准库提供了多种生成器,如下所示:

  1. iota()函数:用于生成序列中的连续整数。
  2. #include <iostream> #include <vector> #include <numeric> int main() { std::vector<int> numbers(10); std::iota(numbers.begin(), numbers.end(), 1); // 生成从1到10的整数序列 for (auto num : numbers) { std::cout << num << " "; } return 0; }
  3. 输出结果:
  4. 1 2 3 4 5 6 7 8 9 10
  5. generate()函数:用于使用自定义函数生成序列中的元素。
  6. #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> numbers(10); int value = 0; std::generate(numbers.begin(), numbers.end(), [&]() { return value++; }); // 生成从0到9的整数序列 for (auto num : numbers) { std::cout << num << " "; } return 0; }
  7. 输出结果:
  8. 0 1 2 3 4 5 6 7 8 9

这些生成器可以方便地生成序列,并通过迭代器进行遍历和操作。

在C++标准库中,Allocator是一个用于管理内存分配和释放的模板类。它提供了一种通用的方式来分配和释放内存,可以与其他容器类一起使用,以控制它们的内存分配行为。

Allocator的主要作用是将内存分配和释放的细节与容器的实现分离开来,从而提高代码的可重用性和灵活性。

以下是Allocator的一些常见用法示例:

  1. 使用默认的Allocator分配内存:
  2. std::vector<int> vec; vec.push_back(10); // 使用默认的Allocator分配内存
  3. 自定义Allocator:
  4. template <typename T> class MyAllocator { public: using value_type = T; T* allocate(std::size_t n) { return static_cast<T*>(std::malloc(n * sizeof(T))); } void deallocate(T* p, std::size_t n) { std::free(p); } }; std::vector<int, MyAllocator<int>> vec; vec.push_back(10); // 使用自定义的Allocator分配内存
  5. 使用Allocator进行内存分配和释放:
  6. std::allocator<int> alloc; int* p = alloc.allocate(5); // 分配5个int类型的内存空间 for (int i = 0; i < 5; ++i) { alloc.construct(p + i, i); // 在分配的内存空间中构造对象 } for (int i = 0; i < 5; ++i) { std::cout << p[i] << " "; // 输出:0 1 2 3 4 } for (int i = 0; i < 5; ++i) { alloc.destroy(p + i); // 销毁对象 } alloc.deallocate(p, 5); // 释放内存空间