(c++)string字符串操作函数

目录

1、string 类概述

2.  string的构造函数

3. 字符串存取

3.1 下标运算符[ ]与at()的区别:

3.1.1 使用下标运算符[ ]访问:

3.1.2 使用at()成员函数访问

4. 赋值操作

5. 查找和替换

5.1 find()与rfind()

5.2 replace()

5.2.1基本语法

5.2.2其他版本

6.  拼接

7. 字符串比较

8.获得子串

9.  字符串的插入和删除


1、string 类概述

C++标准库中的string类是一个专门用于处理字符串的类,它封装了字符串的常见操作,比C风格的字符数组更安全、更方便。string类位于<string>头文件中,是std命名空间的一部分。


2.  string的构造函数

string();                      // 默认构造,创建空字符串
string(const char* s);         // 用C风格字符串构造
string(const string& str);     // 拷贝构造
string(size_t n, char c);      // 用n个字符c构造

string s1;                   // 空字符串
string s2("Hello");          // 从C字符串构造
string s3(s2);               // 拷贝构造
string s4(5, 'A');           // "AAAAA"
string s5(s2.begin(), s2.begin()+3); // "Hel"

易错点:

  • 未初始化的字符串:默认构造的字符串是空的,直接访问可能导致未定义行为

  • NULL指针:用NULL指针构造会引发未定义行为

  • 拷贝开销:大字符串的拷贝构造可能带来性能问题(C++11后可用移动语义优化)


3. 字符串存取

//字符的存取
//char& operator[](int n);                    //通过[]方式取字符
//char& at(int n);                    //通过at方法获取字符

    string str = "Hello World";
    
// 1. 使用[]访问字符
    cout << "使用[]访问: ";
    for(size_t i = 0; i < str.size(); i++) {
        cout << str[i] << " ";
    }
    cout << endl;

// 2. 使用at()访问字符
    cout << "使用at()访问: ";
    for(size_t i = 0; i < str.size(); i++) {
        cout << str.at(i) << " ";
    }
    cout << endl;

// 3. 修改字符
    str[0] = 'h';       // 修改第一个字符
    str.at(6) = 'w';    // 修改第七个字符
    cout << "修改后字符串: " << str << endl;

易错点:

  • 越界访问:使用operator[]越界访问是未定义行为

  • 修改const对象:对const字符串使用非const访问方法会导致编译错误

3.1 下标运算符[ ]与at()的区别:

3.1.1 使用下标运算符[ ]访问:

char c1 = str[1];  // 获取第2个字符'e'
  • 高效:不进行边界检查,直接访问

  • 不安全:如果索引越界(如str[10])会导致未定义行为

3.1.2 使用at()成员函数访问

char c2 = str.at(1);  // 获取第2个字符'e'
  • 安全:会进行边界检查

  • 稍慢:因为多了边界检查的开销

  • 如果索引越界(如str.at(10))会抛出std::out_of_range异常


4. 赋值操作

//string& operator=(const char* s);            //char*类型字符串 赋值给当前的字符串
//string& operator=(const string& s);        //把字符串s赋给当前的字符串
//string& operator=(char c);                //字符赋值给当前的字符串
//string& assign(const char* s);            //把字符串s赋给当前的字符串
//string& assign(const char* s, int n);        //把字符串s的前n个字符赋给当前的字符串
//string& assign(const string& s);            //把字符串s赋给当前字符串
//string& assign(int n, char c);            //用n个字符c赋给当前字符串

// 1. 使用=赋值
    string str1;
    str1 = "直接赋值C字符串";  // 使用C字符串赋值
    cout << "str1: " << str1 << endl;

    string str2;
    str2 = str1;               // 使用string对象赋值
    cout << "str2: " << str2 << endl;

    string str3;
    str3 = 'A';                // 使用单个字符赋值
    cout << "str3: " << str3 << endl;

// 2. 使用assign()赋值
    string str4;
    str4.assign("使用assign赋值");  // 完整字符串赋值
    cout << "str4: " << str4 << endl;

    string str5;
    str5.assign("Hello World", 5); // 只赋值前5个字符
    cout << "str5: " << str5 << endl;  // 输出: Hello

    string str6;
    str6.assign(str5);          // 使用string对象赋值
    cout << "str6: " << str6 << endl;

    string str7;
    str7.assign(10, 'B');       // 赋值10个'B'
    cout << "str7: " << str7 << endl;

// 3. 使用assign()部分赋值
    string str8 = "ABCDEFGHIJK";
    string str9;
    str9.assign(str8, 2, 5);    // 从str8的第2个位置开始取5个字符
    cout << "str9: " << str9 << endl;  // 输出: CDEFG

易错点:

  • 自我赋值:虽然string处理了自我赋值,但在复杂操作中仍需注意

  • 链式赋值:注意赋值顺序和可能的临时对象


5. 查找和替换

5.1 find()与rfind()

        find()与rfind()在以下链接中

https://blog.csdn.net/2403_83972754/article/details/147255405?spm=1001.2014.3001.5501

5.2 replace()

5.2.1基本语法

string& replace(size_type pos, size_type count, const string& str);
  • pos:起始位置(从 0 开始)

  • count:要替换的字符数

  • str:替换的新字符串

5.2.2其他版本

// 用子字符串替换
string& replace(size_type pos, size_type count, const string& str, size_type subpos, size_type sublen);

// 用 C 风格字符串替换
string& replace(size_type pos, size_type count, const char* s);

// 用多个相同字符替换
string& replace(size_type pos, size_type count, size_type n, char c);

// 使用迭代器范围替换
string& replace(iterator first, iterator last, const string& str);

    string str = "I like Java!";
    
// 1. 简单替换
    str.replace(7, 4, "C++");  // 从位置7开始替换4个字符
    cout << "After replace: " << str << endl;
    
// 2. 替换为不同长度的字符串
    str = "C++ is great!";
    str.replace(4, 2, " programming language ");
    cout << "After long replace: " << str << endl;
    
// 3. 使用子串替换
    string insert_str = "awesome";
    str.replace(8, 7, insert_str);  // 用string对象替换
    cout << "After string replace: " << str << endl;
    
// 4. 替换为多个相同字符
    str.replace(0, 3, 5, 'X');     // 替换为5个'X'
    cout << "After char replace: " << str << endl;


6.  拼接

//string& operator+=(const char* str);                    //重载+=操作符
//string& operator+=(const char c);                        //重载+=操作符
//string& operator+=(const string& str);                //重载+=操作符
//string& append(const char* s);                        //把字符串s连接到当前字符串结尾
//string& append(const char* s, int n);                    //把字符串s的前n个字符连接到当前字符串结尾
//string& append(const string& s);                        //同operator+=(const string& str)
//string& append(const string& s, int pos, int n);        //字符串s中从pos开始的n个字符连接到字符串结尾(注意是从pos开始后的n个字符)

// 1. 使用+=操作符
    string str1 = "Hello";
    str1 += " World";      // 追加C字符串
    cout << "str1: " << str1 << endl;
    
    str1 += '!';           // 追加单个字符
    cout << "str1: " << str1 << endl;
    
    string str2 = " C++";
    str1 += str2;          // 追加string对象
    cout << "str1: " << str1 << endl;
    
// 2. 使用append()
    string str3 = "I love";
    str3.append(" programming");  // 追加完整字符串
    cout << "str3: " << str3 << endl;
    
    str3.append(" in Java", 2, 4); // 从位置2开始追加4个字符
    cout << "str3: " << str3 << endl;  // 输出: I love programming Java
    
    string str4 = " and C++";
    str3.append(str4);     // 追加string对象
    cout << "str3: " << str3 << endl;
    
// 3. 追加部分字符串
    string str5 = "Python";
    str3.append(str5.begin(), str5.begin()+3); // 追加前3个字符
    cout << "str3: " << str3 << endl;  // 输出: ... and C++Pyt
    
// 4. 追加多个相同字符
    str3.append(3, '!');
    cout << "str3: " << str3 << endl;  // 输出: ...Pyt!!!

易错点:

  • 多次拼接性能:频繁拼接小字符串会导致多次内存重分配

  • 迭代器失效:拼接操作可能使指向字符串的迭代器失效

string result;
result.reserve(1000); // 预分配足够空间
for(int i=0; i<100; i++) {
    result.append(data[i]);
}

7. 字符串比较

字符串比较方法:
 * 1. compare() - 返回int表示比较结果
 * 2. 比较运算符 - ==, !=, <, <=, >, >=
 * 比较规则:按字典序逐个字符比较(基于ASCII码)

//int compare(const string& s) const;   //与字符串s比较
//int compare(const char* s) const;    //与字符串s比较

    string str1 = "apple";
    string str2 = "banana";
    string str3 = "Apple";
    string str4 = "apple";
    
    // 1. 使用compare()比较
    cout << "apple vs banana: " << str1.compare(str2) << endl;  // 负值
    cout << "banana vs apple: " << str2.compare(str1) << endl;  // 正值
    cout << "apple vs apple: " << str1.compare(str4) << endl;   // 0
    
    // 2. 比较大小写敏感
    cout << "apple vs Apple: " << str1.compare(str3) << endl;   // 正值('a' > 'A')
    
    // 3. 比较子串
    cout << "app vs apple: " << str1.compare(0, 3, "app") << endl; // 0(前3字符相同)
    
    // 4. 使用比较运算符
    if(str1 == str4) {
        cout << "str1 equals str4" << endl;
    }
    if(str1 > str2) {
        cout << "str1 > str2" << endl;
    } else {
        cout << "str1 < str2" << endl;
    }
    
    // 5. 实用案例 - 字符串排序
    string fruits[] = {"banana", "apple", "orange", "grape"};
    sort(fruits, fruits+4);
    cout << "排序后的水果: ";
    for(const auto& fruit : fruits) {
        cout << fruit << " ";
    }
    cout << endl;

比较方法选择

  1. compare():需要知道具体差异值时使用

  2. 关系运算符:简单比较时更直观

注意事项:

  • 大小写敏感:标准比较是大小写敏感的

  • 区域设置影响:某些语言环境下字符顺序可能不同

  • 性能:长字符串的比较可能较耗时


8.获得子串

子串操作:
substr() - 提取子串
参数:
pos - 起始位置(默认为0)
len - 子串长度(默认为到字符串末尾)

    string str = "Hello World! Programming is fun!";
    
// 1. 基本用法
    string sub1 = str.substr(6, 5);  // 从位置6开始取5个字符
    cout << "sub1: " << sub1 << endl;  // 输出: World
    
// 2. 省略长度参数
    string sub2 = str.substr(13);     // 从位置13到末尾
    cout << "sub2: " << sub2 << endl;  // 输出: Programming is fun!
    
// 3. 实用案例 - 分割字符串
    string email = "user@example.com";
    size_t at_pos = email.find('@');
    if(at_pos != string::npos) {
        string username = email.substr(0, at_pos);
        string domain = email.substr(at_pos + 1);
        cout << "用户名: " << username << endl;
        cout << "域名: " << domain << endl;
    }
    
// 4. 实用案例 - 提取文件扩展名
    string filename = "document.pdf";
    size_t dot_pos = filename.rfind('.');
    if(dot_pos != string::npos) {
        string extension = filename.substr(dot_pos + 1);
        cout << "文件扩展名: " << extension << endl;
    }
    
// 5. 注意边界检查
    try {
        string sub3 = str.substr(100, 5);  // 超出范围
    } catch(const out_of_range& e) {
        cerr << "错误: " << e.what() << endl;
    }

substr() 使用技巧

  1. 参数默认值:pos=0, len=npos

  2. 边界处理:pos超出范围会抛出异常

  3. 性能:返回新字符串,大子串可能影响性能

实用模式(安全提取子串):

// 安全子串提取
string safe_substr(const string& s, size_t pos, size_t len) {
    pos = min(pos, s.size());
    len = min(len, s.size()-pos);
    return s.substr(pos, len);
}

9.  字符串的插入和删除

字符串插入和删除:
插入方法:
        insert() - 在指定位置插入字符串/字符
删除方法:
         erase() - 删除指定位置的字符
注意:所有位置都是从0开始计数 

//string& insert(int pos, const char* s);            //插入字符串(pos位置后插入)
//string& insert(int pos, const string& str);        //插入字符串
//string& insert(int pos, int n, char c);            //在指定位置插入n个字符c
//string& erase(int pos, int n = npos);                //删除从Pos开始的n个字符

    string str = "Hello Programming!";
    
// 1. 插入字符串
    str.insert(6, "C++ ");  // 在位置6插入
    cout << "插入后: " << str << endl;  // Hello C++ Programming!
    
// 2. 插入部分字符串
    string lang = "Java and Python";
    str.insert(10, lang, 0, 4);  // 插入"Java"
    cout << "插入部分后: " << str << endl;  // Hello C++ JavaProgramming!
    
// 3. 插入多个相同字符
    str.insert(5, 3, '*');  // 插入3个'*'
    cout << "插入字符后: " << str << endl;  // Hello*** C++ JavaProgramming!
    
// 4. 删除字符
    str.erase(5, 3);  // 从位置5删除3个字符
    cout << "删除后: " << str << endl;  // Hello C++ JavaProgramming!
    
// 5. 删除到末尾
    str.erase(10);  // 从位置10删除到末尾
    cout << "删除到末尾: " << str << endl;  // Hello C++ 
    
// 6. 删除单个字符
    str.erase(str.begin() + 5);  // 删除位置5的字符
    cout << "删除单个字符: " << str << endl;  // HelloC++ 
    
// 7. 实用案例 - 删除空格
    string sentence = "This   is   a   test   sentence.";
    size_t pos;
    while((pos = sentence.find("  ")) != string::npos) {
        sentence.erase(pos, 1);  // 删除多余空格
    }
    cout << "删除多余空格后: " << sentence << endl;

愿你在代码的世界里如鱼得水,bug退散,灵感如泉涌!保持热爱,奔赴下一场山海,轻松快乐永远是主旋律~ 🎉(附赠一只蹦跶的电子猫:=^・ω・^=)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值