Skip to content

字符串

在C++中,字符串可以通过C风格字符数组或C++的string类来处理。本章将详细介绍C++字符串的定义、操作和常用函数。

C风格字符串

cpp
#include <iostream>
#include <cstring>  // C字符串函数头文件
using namespace std;

int main() {
    // ============ C风格字符串定义 ============
    
    // 字符数组,以'\0'结尾
    char str1[] = "Hello";  // 自动添加'\0',大小为6
    
    // 等价于
    char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};
    
    // 指定大小
    char str3[10] = "Hello";  // 剩余位置填充'\0'
    
    // 指针指向字符串字面量(只读)
    const char* str4 = "Hello";  // 不能修改
    
    
    // ============ 输出C字符串 ============
    
    cout << "str1: " << str1 << endl;
    cout << "str4: " << str4 << endl;
    
    // 逐个字符输出
    cout << "逐个字符: ";
    for (int i = 0; str1[i] != '\0'; i++) {
        cout << str1[i];
    }
    cout << endl;
    
    
    // ============ C字符串函数 ============
    
    char source[] = "Hello, World!";
    char dest[50];
    
    // strlen:获取字符串长度(不包括'\0')
    cout << "\nstrlen: " << strlen(source) << endl;
    
    // strcpy:复制字符串
    strcpy(dest, source);
    cout << "strcpy: " << dest << endl;
    
    // strncpy:安全复制(指定最大长度)
    strncpy(dest, source, 5);
    dest[5] = '\0';  // 手动添加结束符
    cout << "strncpy: " << dest << endl;
    
    // strcat:连接字符串
    char greeting[50] = "Hello";
    strcat(greeting, ", C++!");
    cout << "strcat: " << greeting << endl;
    
    // strncat:安全连接
    char name[50] = "Hello";
    strncat(name, " World!", 4);  // 只连接前4个字符
    cout << "strncat: " << name << endl;
    
    // strcmp:比较字符串
    char s1[] = "apple";
    char s2[] = "banana";
    
    cout << "\nstrcmp(s1, s2): " << strcmp(s1, s2) << endl;  // 负数(s1 < s2)
    cout << "strcmp(s2, s1): " << strcmp(s2, s1) << endl;  // 正数(s2 > s1)
    cout << "strcmp(s1, s1): " << strcmp(s1, s1) << endl;  // 0(相等)
    
    // strchr:查找字符
    char* pos = strchr(source, 'W');
    if (pos != nullptr) {
        cout << "\n找到'W'在位置: " << (pos - source) << endl;
    }
    
    // strstr:查找子字符串
    char* sub = strstr(source, "World");
    if (sub != nullptr) {
        cout << "找到\"World\"在位置: " << (sub - source) << endl;
    }
    
    return 0;
}

C++ string类

cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    // ============ string定义和初始化 ============
    
    // 默认构造
    string s1;  // 空字符串
    
    // 从C字符串构造
    string s2("Hello");
    
    // 从另一个string构造
    string s3(s2);
    
    // 从重复字符构造
    string s4(5, 'a');  // "aaaaa"
    
    // 从子串构造
    string s5("Hello World", 5);  // "Hello"
    
    // 从string的子串构造
    string s6(s2, 2, 3);  // 从位置2开始取3个字符 -> "llo"
    
    // 使用=赋值
    string s7 = "Hello";
    
    // 使用列表初始化
    string s8 = {'H', 'e', 'l', 'l', 'o'};
    
    cout << "s1: \"" << s1 << "\"" << endl;
    cout << "s2: " << s2 << endl;
    cout << "s4: " << s4 << endl;
    cout << "s5: " << s5 << endl;
    cout << "s6: " << s6 << endl;
    
    
    // ============ string基本操作 ============
    
    string str = "Hello";
    
    // 获取长度
    cout << "\n长度: " << str.length() << endl;
    cout << "大小: " << str.size() << endl;  // 等价于length()
    cout << "是否为空: " << (str.empty() ? "是" : "否") << endl;
    
    // 访问字符
    cout << "str[0]: " << str[0] << endl;      // H(不检查边界)
    cout << "str.at(1): " << str.at(1) << endl;  // e(检查边界)
    cout << "str.front(): " << str.front() << endl;  // H
    cout << "str.back(): " << str.back() << endl;    // o
    
    // 修改字符
    str[0] = 'h';
    cout << "修改后: " << str << endl;
    
    // C字符串转换
    const char* cstr = str.c_str();  // 返回C风格字符串
    cout << "C字符串: " << cstr << endl;
    
    
    // ============ string连接 ============
    
    string s = "Hello";
    
    // 使用+=
    s += " ";
    s += "World";
    cout << "\n连接后: " << s << endl;
    
    // 使用append
    s.append("!");
    cout << "append后: " << s << endl;
    
    // 使用+
    string result = s + " Welcome";
    cout << "+连接: " << result << endl;
    
    // push_back添加字符
    s.push_back('!');
    cout << "push_back后: " << s << endl;
    
    
    // ============ string插入和删除 ============
    
    string text = "Hello World";
    
    // insert:在指定位置插入
    text.insert(5, " C++");  // 在位置5插入
    cout << "\ninsert后: " << text << endl;
    
    // erase:删除字符
    text.erase(5, 4);  // 从位置5开始删除4个字符
    cout << "erase后: " << text << endl;
    
    // clear:清空
    string temp = "temp";
    temp.clear();
    cout << "clear后长度: " << temp.length() << endl;
    
    // pop_back:删除最后一个字符
    text.pop_back();
    cout << "pop_back后: " << text << endl;
    
    
    // ============ string子串 ============
    
    string original = "Hello, World!";
    
    // substr:获取子串
    string sub1 = original.substr(7);      // 从位置7到末尾 -> "World!"
    string sub2 = original.substr(0, 5);   // 从位置0开始取5个 -> "Hello"
    
    cout << "\nsubstr(7): " << sub1 << endl;
    cout << "substr(0, 5): " << sub2 << endl;
    
    return 0;
}

string查找和替换

cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    // ============ 查找 ============
    
    string text = "Hello, World! Hello, C++!";
    
    // find:查找子串,返回位置(未找到返回string::npos)
    size_t pos = text.find("World");
    if (pos != string::npos) {
        cout << "找到\"World\"在位置: " << pos << endl;
    }
    
    // 从指定位置开始查找
    pos = text.find("Hello", 5);  // 从位置5开始
    if (pos != string::npos) {
        cout << "第二个\"Hello\"在位置: " << pos << endl;
    }
    
    // rfind:从后向前查找
    pos = text.rfind("Hello");
    cout << "rfind \"Hello\"位置: " << pos << endl;
    
    // find_first_of:查找第一个匹配字符集中的任一字符
    pos = text.find_first_of("aeiou");
    cout << "第一个元音字母位置: " << pos << endl;
    
    // find_last_of:查找最后一个匹配字符集中的任一字符
    pos = text.find_last_of("aeiou");
    cout << "最后一个元音字母位置: " << pos << endl;
    
    // find_first_not_of:查找第一个不匹配的字符
    pos = text.find_first_not_of("Helo, !");
    cout << "第一个不匹配的字符位置: " << pos << endl;
    
    
    // ============ 替换 ============
    
    string str = "Hello, World!";
    
    // replace:替换指定范围的字符
    str.replace(7, 5, "C++");  // 从位置7开始替换5个字符
    cout << "\nreplace后: " << str << endl;
    
    // 替换所有出现的子串
    string message = "I like cats. Cats are cute. cats are friendly.";
    string from = "cats";
    string to = "dogs";
    
    pos = 0;
    while ((pos = message.find(from, pos)) != string::npos) {
        message.replace(pos, from.length(), to);
        pos += to.length();
    }
    cout << "替换后: " << message << endl;
    
    
    // ============ 比较 ============
    
    string a = "apple";
    string b = "banana";
    
    cout << "\n比较结果:" << endl;
    cout << "a.compare(b): " << a.compare(b) << endl;  // 负数(a < b)
    cout << "b.compare(a): " << b.compare(a) << endl;  // 正数(b > a)
    cout << "a.compare(a): " << a.compare(a) << endl;  // 0(相等)
    
    // 比较运算符
    cout << "a == b: " << (a == b) << endl;
    cout << "a < b: " << (a < b) << endl;
    cout << "a != b: " << (a != b) << endl;
    
    return 0;
}

字符串流

cpp
#include <iostream>
#include <string>
#include <sstream>  // 字符串流头文件
using namespace std;

int main() {
    // ============ stringstream ============
    
    // 字符串到数字的转换
    string numStr = "123 45.67";
    istringstream iss(numStr);
    
    int intVal;
    double doubleVal;
    iss >> intVal >> doubleVal;
    
    cout << "字符串转数字:" << endl;
    cout << "int: " << intVal << endl;
    cout << "double: " << doubleVal << endl;
    
    
    // 数字到字符串的转换
    ostringstream oss;
    oss << "整数: " << 123 << ", 浮点数: " << 45.67;
    string result = oss.str();
    
    cout << "\n数字转字符串:" << endl;
    cout << result << endl;
    
    
    // ============ C++11转换函数 ============
    
    // 数字转字符串
    string s1 = to_string(123);
    string s2 = to_string(3.14);
    string s3 = to_string(123.456789);
    
    cout << "\nto_string:" << endl;
    cout << "int: " << s1 << endl;
    cout << "double: " << s2 << endl;
    cout << "double: " << s3 << endl;
    
    // 字符串转数字
    int i = stoi("123");
    long l = stol("1234567890");
    double d = stod("3.14");
    float f = stof("3.14");
    
    cout << "\n字符串转数字:" << endl;
    cout << "stoi: " << i << endl;
    cout << "stol: " << l << endl;
    cout << "stod: " << d << endl;
    cout << "stof: " << f << endl;
    
    // 处理不同进制的字符串
    int binary = stoi("1010", nullptr, 2);   // 二进制
    int octal = stoi("12", nullptr, 8);      // 八进制
    int hex = stoi("FF", nullptr, 16);       // 十六进制
    
    cout << "\n不同进制:" << endl;
    cout << "二进制1010: " << binary << endl;
    cout << "八进制12: " << octal << endl;
    cout << "十六进制FF: " << hex << endl;
    
    
    // ============ 分割字符串 ============
    
    string sentence = "Hello World C++ Programming";
    istringstream iss2(sentence);
    string word;
    
    cout << "\n分割字符串:" << endl;
    while (iss2 >> word) {
        cout << word << endl;
    }
    
    // 使用自定义分隔符
    string data = "apple,banana,orange,grape";
    istringstream iss3(data);
    string item;
    
    cout << "\n逗号分隔:" << endl;
    while (getline(iss3, item, ',')) {
        cout << item << endl;
    }
    
    return 0;
}

字符串应用

cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;

// ============ 字符串处理函数 ============

// 去除首尾空白
string trim(string str) {
    // 去除前导空白
    size_t start = str.find_first_not_of(" \t\n\r");
    if (start == string::npos) return "";
    
    // 去除尾部空白
    size_t end = str.find_last_not_of(" \t\n\r");
    
    return str.substr(start, end - start + 1);
}

// 分割字符串
vector<string> split(const string& str, char delimiter) {
    vector<string> tokens;
    stringstream ss(str);
    string token;
    
    while (getline(ss, token, delimiter)) {
        tokens.push_back(token);
    }
    
    return tokens;
}

// 连接字符串
string join(const vector<string>& vec, const string& delimiter) {
    string result;
    for (size_t i = 0; i < vec.size(); i++) {
        if (i > 0) result += delimiter;
        result += vec[i];
    }
    return result;
}

int main() {
    // ============ 大小写转换 ============
    
    string text = "Hello World";
    
    // 转大写
    string upper = text;
    transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
    cout << "大写: " << upper << endl;
    
    // 转小写
    string lower = text;
    transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
    cout << "小写: " << lower << endl;
    
    // 手动转换
    string manual = text;
    for (char& c : manual) {
        if (islower(c)) c = toupper(c);
        else if (isupper(c)) c = tolower(c);
    }
    cout << "大小写互换: " << manual << endl;
    
    
    // ============ 字符串反转 ============
    
    string original = "Hello";
    string reversed = original;
    reverse(reversed.begin(), reversed.end());
    
    cout << "\n反转: " << original << " -> " << reversed << endl;
    
    
    // ============ 判断回文 ============
    
    auto isPalindrome = [](const string& s) {
        string filtered;
        for (char c : s) {
            if (isalnum(c)) {
                filtered += tolower(c);
            }
        }
        
        int left = 0, right = filtered.length() - 1;
        while (left < right) {
            if (filtered[left] != filtered[right]) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    };
    
    cout << "\n回文判断:" << endl;
    cout << "A man a plan a canal Panama: " << (isPalindrome("A man a plan a canal Panama") ? "是" : "否") << endl;
    cout << "racecar: " << (isPalindrome("racecar") ? "是" : "否") << endl;
    cout << "hello: " << (isPalindrome("hello") ? "是" : "否") << endl;
    
    
    // ============ 字符串统计 ============
    
    string sentence = "Hello World! 123";
    
    int letters = 0, digits = 0, spaces = 0, others = 0;
    
    for (char c : sentence) {
        if (isalpha(c)) letters++;
        else if (isdigit(c)) digits++;
        else if (isspace(c)) spaces++;
        else others++;
    }
    
    cout << "\n字符串统计:" << endl;
    cout << "字母: " << letters << endl;
    cout << "数字: " << digits << endl;
    cout << "空格: " << spaces << endl;
    cout << "其他: " << others << endl;
    
    
    // ============ 使用自定义函数 ============
    
    string padded = "  Hello World  ";
    cout << "\n去除空白: \"" << trim(padded) << "\"" << endl;
    
    vector<string> parts = split("apple,banana,orange", ',');
    cout << "\n分割结果:" << endl;
    for (const string& part : parts) {
        cout << "- " << part << endl;
    }
    
    vector<string> words = {"Hello", "World", "C++"};
    cout << "\n连接结果: " << join(words, " ") << endl;
    
    return 0;
}

本章小结

本章学习了:

  • C风格字符串:字符数组、strlen、strcpy、strcmp等函数
  • string类:定义、初始化、基本操作
  • string操作:连接、插入、删除、子串
  • string查找:find、rfind、find_first_of等
  • 字符串转换:to_string、stoi、stod、stringstream
  • 字符串应用:大小写转换、反转、回文判断

下一章,我们将学习面向对象基础,了解C++类与对象的概念。