c++string中操作函数

目录

1.容器操作

1.1 size() 和 length()

1.2 capacity()

1.3 reserve(n)

1.4 resize()

1.4.1 resize(n , c)

1.4.2 resize(n)

1.5 clear()

1.6 empty()

2.基本迭代器访问

2.1 begin()与end()

2.2 rbegin()与rend()

2.3修改内容

2.4使用函数

2.5查找字符

3.转换函数

3.1 c_str()

3.2 data()

3.3 copy(char* arr,len,pos)

4.输入输出

4.1 getline(istream,string)

5.比较运算符

5.1默认比较规则(字典序)

5.2特殊情况

5.2.1大小写敏感

5.2.2数组字符串比较

5.2.3空字符串

6.其他查找函数

6.1 find_last_of - 查找字符集中任意字符首次出现

6.2 find_last_of - 查找字符集中任意字符最后一次出现

6.3 find_first_not_of - 查找不在字符集中的首个字符

7.数值转换(C++11)

7.1字符串转数值的函数

7.2数值转字符串的函数

8.swap函数

9.移动语义(C++11)

10.其他函数

10.1 shrink_to_fit()

10.2 substr(pos,len)


1.容器操作

1.1 size() 和 length()

  • 功能:返回字符串当前的字符数(长度)

  • 区别:二者功能完全相同,size() 是STL容器的通用接口,length() 更直观表示字符串长度。

  • 示例:

string s = "hello";
cout << s.size() <<endl;   // 输出 5
cout << s.length(); // 输出 5

注意:length() 只能用于string类,其余的容器使用 size() 表示长度

1.2 capacity()

  • 功能:返回字符串当前分配的内存容量(以字节为单位),可能大于实际长度

  • 示例:

string s;
s.reserve(100);
cout << s.capacity(); // 输出至少 100

1.3 reserve(n)

  • 功能:预分配至少n字节的内存,避免后续操作频繁扩容

  • 注意:若n小于当前容量吗,可能无效果(不缩减内存,即:不会主动释放或者减少已分配的内存)

  • 示例:

string s;
s.reserve(100); // 预分配内存

1.4 resize()

        resize()是成员函数,直接修改原字符串,不返回值

1.4.1 resize(n , c)

  • 功能:调整字符串长度为n

                若 n > 当前长度,多出部分用字符 c 填充(默认为空字符 \0 )

                若 n < 当前长度,截断字符串至前 n 个字符

  • 示例:

string s = "hi";
s.resize(5, 'x');   // 变为 "hixxx"
cout << s << endl;

注意:resize()是成员函数,直接修改原字符串,不返回值

string s = "hi";
cout << s.resize(5, 'x') << endl;   // error

1.4.2 resize(n)

  • 功能:将字符串长度改为 n,如果 n 小于当前长度,会截断字符串

  • 示例:

string s = "hello";
s.resize(3);        // 变为 "hel"
cout << s << endl;

1.5 clear()

  • 功能:清空字符串内容,长度置零,但不释放内存(容量不变)

  • 示例:

string s = "hello";
cout << "原长度:" << s.size() << endl;      // 输出 0
cout << "原容量:" << s.capacity() << endl;
s.clear();
cout << "现长度:" << s.size() << endl;      // 输出 0
cout << "现容量:" <<s.capacity();  // 容量不变

1.6 empty()

  • 功能:判断字符串是否为空(等价于 size() == 0 )

  • 示例:

string s;
cout << s.empty() << endl; // 输出 true
s = "test";
cout << s.empty(); // 输出 false

2.基本迭代器访问

2.1 begin()与end()

string str = "Hello World";
// ===== 1. 正向遍历(begin/end)=====
cout << "正向遍历: ";
for (auto it = str.begin(); it != str.end(); ++it) {
    cout << *it;
}
cout << "\n";
// 输出: Hello World

注意:begin()是第一个字符,而end()则是最后一个字符的后一位  [begin(),end())

2.2 rbegin()与rend()

// ===== 2. 反向遍历(rbegin/rend)=====
cout << "反向遍历: ";
for (auto rit = str.rbegin(); rit != str.rend(); ++rit) {
     cout << *rit;
}
cout << "\n";
// 输出: dlroW olleH

2.3修改内容

// ===== 3. 修改内容 =====
// 将所有字母转为大写
for (auto it = str.begin(); it != str.end(); ++it) {
    if (islower(*it)) {
        *it = toupper(*it);//toupper需调用<cctype>,作用是将用于将小写字母转换为大写字母
    }
}
cout << "转为大写: " << str << "\n";
// 输出: HELLO WORLD

2.4使用函数

// ===== 4. 使用算法(reverse)=====
reverse(str.begin(), str.end());
cout << "反转字符串: " << str << "\n";
// 输出: DLROW OLLEH

注意:reverse()(反转字符串,需要algorithm的库)与之前的reserve()(预留内存)的拼写

2.5查找字符

// ===== 5. 查找字符 =====
auto found = find(str.begin(), str.end(), 'O');
if (found != str.end()) {
    cout << "找到'O',位置: " << (found - str.begin()) << "\n";
} else {
    cout << "未找到'O'\n";
}
// 输出: 找到'O',位置: 5

3.转换函数

        转换函数主要的作用就是使c++有更好的兼容性,更好的对接传统C语言库

3.1 c_str()

  • 功能:返回一个指向以\0结尾的C风格字符串(const char*)的指针

  • 特点

    • 保证返回的指针指向的字符串以\0结尾

    • 返回的指在std::string修改或销毁后失效(悬空指针)

  • 用途:需要与C语言接口交互时(如调用printf,strcpy等)。

  • 实例

string s = "Hello";
const char* ptr = s.c_str();
cout << ptr << std::endl; // 输出: Hello

// 注意:修改s会导致ptr失效
s += " World";
// 以下行为未定义(可能崩溃或输出错误)
// cout << ptr << endl;

为什么会出现错误,并且时未被定义???

        回答:是因为std::string是一个动态储存,c_str()是通过返回的指针来储存C语言字符串的,所以若是在使用c_str()后改变字符串可能会由于std::string导致内存地址改变,而使得从c_str()的指针无法正确指向,从而出现错误

3.2 data()

  • C++11及之前:返回const char*,但不保证以\0结尾(尽管大多数实现会结尾)

  • C++17及之后:与c_str()完全一致,保证以\0结尾

  • 用途:需要直接访问底层字符数组(C++17后可以安全替代c_str())

  • 示例:

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main() {
    string s = "Hello";
    const char* ptr = s.data();
    cout << ptr << endl; // 输出: Hello

    // C++17后可以安全使用
    cout << strlen(ptr) << endl; // 输出: 5
}

3.3 copy(char* arr,len,pos)

  • 功能:将std::string中从位置pos开始的len个字符复制到用户提供的字符数组arr中。

  • 特点

    • 不自动添加\0,需手动处理。

    • 返回实际复制的字符数(可能小于len,如果字符串不够长)

  • 用途:需要将字符串内容复制到预分配的缓冲区(如网络传输、文件操作)

  • 示例

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

int main() {
    string s = "Hello World";
    char arr[20] = {0}; // 初始化为全0

    // 复制前5个字符(不包括\0)
    size_t copied = s.copy(arr, 5, 0);
    arr[copied] = '\0'; // 手动添加结尾

    cout << arr << endl; // 输出: Hello
    return 0;
}

4.输入输出

4.1 getline(istream,string)

string line;
cout << "Enter a line with spaces: ";
getline(cin, line);  // 读取整行,包括空格
cout << "You entered: " << line << endl;

        将输入的值赋给string处定义的变量


5.比较运算符

5.1默认比较规则(字典序)

std::string 的比较是基于 逐个字符ASCII 值,类似于字典排序:

  • 从第一个字符开始比较,如果不同,直接返回结果

  • 如果所有字符都相同,但长度不同,较短的字符串更小

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

int main() {
    string s1 = "apple";
    string s2 = "banana";
    string s3 = "app";
    string s4 = "apple";

    cout << std::boolalpha;
    cout << (s1 < s2) << "\n";   // true,因为 'a' < 'b'
    cout << (s1 > s3) << "\n";   // true,因为 "apple" 比 "app" 长
    cout << (s1 == s4) << "\n";  // true,完全相同
    cout << (s1 != s2) << "\n";  // true,不同
}

5.2特殊情况

5.2.1大小写敏感

由于比较基于 ASCII 码,大写字母('A'=65)比小写字母('a'=97)小:

"Apple" < "apple"  // true,因为 'A' < 'a'

5.2.2数组字符串比较

"100" < "99"  // true,因为 '1' < '9'(逐字符比较,不是数值比较)

5.2.3空字符串

空字符串 "" 比任何非空字符串小:

"" < "a"  // true

6.其他查找函数

6.1 find_last_of - 查找字符集中任意字符首次出现

size_t find_first_of(const string& str, size_t pos = 0) const;
size_t find_first_of(const char* s, size_t pos = 0) const;
size_t find_first_of(const char* s, size_t pos, size_t n) const;
size_t find_first_of(char c, size_t pos = 0) const;

#include <iostream>
#include <string>

int main() {
    std::string str = "Hello, World! 123";
    
    // 查找第一个数字
    size_t found = str.find_first_of("0123456789");
    if (found != std::string::npos) {
        std::cout << "First digit at position " << found 
                  << ": " << str[found] << std::endl;
    }
    
    // 查找第一个标点符号
    found = str.find_first_of(",.!?");
    if (found != std::string::npos) {
        std::cout << "First punctuation at position " << found 
                  << ": " << str[found] << std::endl;
    }
    
    return 0;
}

输出是

  • find_first_of("0123456789") 会查找字符串中第一个出现在 "0123456789"(即任意数字)中的字符

  • 在 "Hello, World! 123" 中,第一个数字是 '1',位于索引 14('H' 是 0,以此类推)

  • 如果找到,found 存储该位置;否则返回 std::string::npos

第二段同理。。。。。。。

6.2 find_last_of - 查找字符集中任意字符最后一次出现

size_t find_last_of(const string& str, size_t pos = npos) const;
size_t find_last_of(const char* s, size_t pos = npos) const;
size_t find_last_of(const char* s, size_t pos, size_t n) const;
size_t find_last_of(char c, size_t pos = npos) const;

#include <iostream>
#include <string>

int main() {
    std::string filename = "example.txt";
    
    // 查找最后一个点号(文件扩展名分隔符)
    size_t dot_pos = filename.find_last_of(".");
    if (dot_pos != std::string::npos) {
        std::string ext = filename.substr(dot_pos + 1);
        std::cout << "File extension: " << ext << std::endl;
    }
    
    // 查找最后一个路径分隔符
    std::string path = "/usr/local/bin/program";
    size_t slash_pos = path.find_last_of("/\\");
    if (slash_pos != std::string::npos) {
        std::string program_name = path.substr(slash_pos + 1);
        std::cout << "Program name: " << program_name << std::endl;
    }
    
    return 0;
}

  • find_last_of(".") 从字符串末尾向前查找最后一个 '.' 的位置

  • 在 "example.txt" 中,'.' 位于索引 7('e' 是 0,'x' 是 1,...,'.' 是 7)

  • filename.substr(dot_pos + 1) 提取 '.' 之后的部分,即 "txt"

第二段同理。。。。。。。

6.3 find_first_not_of - 查找不在字符集中的首个字符

size_t find_first_not_of(const string& str, size_t pos = 0) const;
size_t find_first_not_of(const char* s, size_t pos = 0) const;
size_t find_first_not_of(const char* s, size_t pos, size_t n) const;
size_t find_first_not_of(char c, size_t pos = 0) const;

#include <iostream>
#include <string>

int main() {
    std::string str = "    Hello, World!";
    
    // 查找第一个非空白字符
    size_t first_non_space = str.find_first_not_of(" \t\n\r");
    if (first_non_space != std::string::npos) {
        std::cout << "First non-space at position " << first_non_space
                  << ": " << str[first_non_space] << std::endl;
    }
    
    // 验证字符串是否全是数字
    std::string number = "12345a";
    size_t non_digit = number.find_first_not_of("0123456789");
    if (non_digit != std::string::npos) {
        std::cout << "Non-digit character found at position " << non_digit
                  << ": " << number[non_digit] << std::endl;
    }
    
    return 0;
}

  • find_first_not_of(" \t\n\r") 查找第一个不在 " \t\n\r"(空格、制表符、换行符、回车符)中的字符

  • 在 " Hello, World!" 中,前 4 个字符是空格,第 5 个字符 'H' 是第一个非空白字符


7.数值转换(C++11)

7.1字符串转数值的函数

stoi() - 将字符串转换为 int

stol() - 将字符串转换为 long

stoll() - 将字符串转换为 long long

stof() - 将字符串转换为 float

stod() - 将字符串转换为 double

stold() - 将字符串转换为 long double

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

int main() {
    string numStr = "123";
    
    // 字符串转整数
    int n1 = std::stoi(numStr);       // 123
    long n2 = std::stol(numStr);      // 123L
    float f = std::stof("3.14");      // 3.14f
    double d = std::stod("3.14159");  // 3.14159
    
    // 可以指定转换的基数(如16进制)
    int hex = std::stoi("FF", nullptr, 16);  // 255
    
    cout << n1 << ", " << n2 << ", " << f << ", " << d << ", " << hex << endl;
}

7.2数值转字符串的函数

to_string - 将数值转化为字符串

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

int main() {
    // 数值转字符串
    string s1 = to_string(42);      // "42"
    string s2 = to_string(3.14);    // "3.140000"
    string s3 = to_string(2.718f);  // "2.718000"
    
    cout << s1 << ", " << s2 << ", " << s3 << endl;
}


8.swap函数

作用:高效的交换两个字符串内容

string a = "apple", b = "banana";
a.swap(b);  // a变为"banana",b变为"apple"
cout << "a是 " << a << endl;
cout << "b是 " << b ;


9.移动语义(C++11)

        移动构造函数与移动赋值运算符

string s1 = "Hello";
string s2 = move(s1);  // 调用移动构造函数
string s3;
s3 = move(s2);         // 调用移动赋值运算符

        以上不管是移动构造函数还是移动赋值运算符都是用到了std::move,(所以就我来说,我的第一映像就是move即是移动构造函数又是移动赋值运算符但,这种理解是错误的!!!)实际上,std::move是一个类型转换工具,只是将左值转换为右值引用(std::move的作用可以理解为:它不移动任何数据,只是告诉编译器:"这个对象可以被移动"),实际上,移动赋值运算符就是一个经过重载的“=”(operator=)

        两者之间的区别

  • 移动构造函数用于初始化新对象时直接“窃取”资源(如 string s2 = std::move(s1);)

  • 移动赋值运算符用于已存在对象赋值时先释放旧资源再“窃取”新资源(如 s3 = std::move(s2);)


10.其他函数

10.1 shrink_to_fit()

        因为std::string在储存中内存会随着字符串的而增长,而自动分配更大的内存(通常是按指数级增长策略),以容纳新字符;但是在字符串缩短时,size()会减少,但capacity()通常会保持不变,所以需要有一种显式的方式释放内存----------shrink_to_fit()

#include <iostream>
#include <string>

int main() {
    std::string str = "This is a long string that will be erased later.";
    std::cout << "Before erase - Size: " << str.size() 
              << ", Capacity: " << str.capacity() << std::endl;

    str.erase(10); // 删除第10个字符之后的所有内容
    std::cout << "After erase - Size: " << str.size() 
              << ", Capacity: " << str.capacity() << std::endl;

    str.shrink_to_fit(); // 请求释放多余内存
    std::cout << "After shrink - Size: " << str.size() 
              << ", Capacity: " << str.capacity() << std::endl;
}

10.2 substr(pos,len)

  • 作用:返回从 pos 开始长度为 len 的子串(新 std::string 对象)

  • 参数

    • pos:起始位置(默认 0)

    • len:子串长度(默认到末尾)

  • 注意

    • 不修改原字符串,返回独立拷贝

    • 越界检查:若 pos > size() 抛出 std::out_of_range

  • 示例

std::string s = "Hello World";
std::string sub1 = s.substr(6);    // "World"(从第6字符到末尾)
std::string sub2 = s.substr(0, 5); // "Hello"(前5字符)

                在以下链接中的“获得子串”部分有substr()更详细的示例

(c++)string字符串操作函数-CSDN博客

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

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值