【C++】string类用法

转载请注明来源!

 

1. 定义以及初始化

(1) 8种string类对象构造方法;

(2) copy();substr();

2. 基本用法

(1) 打印输出: cout

(2) 索引某个位置的字符:[]、at()

(3) 大小:size()、length()、max_size()、capacity()

(4) 改变大小: resize()、reserve()、

(5) 判空与清空: empty()、clear()

3. 增

(1) 末尾添加:push_back()、append()

(2) 任意位置插入: insert()

(3) 字符串拼接:+

4. 删、改

(1)  清空字符串: clear()

(2) 清空字符串并重新赋值:assign()

(3) 字符串替换:replace()

(4) 字符串交换: swap()

(5) 删除:erase()

(6) 顺序反转:revers()   [该函数在头文件algorithm中]

5. 查

(1) 查找:find()、rfind()、find_first_of()、find_last_of()、find_first_not_of()、find_last_not_of()

(2) 比较:compare(); <=、>=、==、>、<

6. C风格字符串与string字符串之间转换

C风格字符串与string字符串异同:

相同:都是以'\0'字符结尾;计算长度时都不计算字符'\0';

#include <iostream>
#include <string>
#include <typeinfo>
#include <algorithm>
// 参考博客:
// https://blog.csdn.net/qq_42659468/article/details/90381985?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2
//

std::string declare_string(){
    // string::size_type 
    // string::npos string类型变量成员函数失败的返回值
    int strlen = 3;
    int stridx = 2;
// string类是一种顺序表的结构,元素是char类型的字符,常用构造方法如下:
    // 1. 构造空的string类的对象,即空字符串。
    std::string str1;
    // 2. 注意:"This is str2"的类型是 const char[]
    std::string str2 = "This is str2";
    // 3. 等价于 string str3 = "This is str3";
    std::string str3("This is str3");
    // 4. 字符串str2拷贝构造str3
    std::string str4(str2);
    // 5. 将字符数组"This is str5"的前strlen个字符用来构造str5
    std::string str5("This is str5", strlen);
    // 6. 与5的区别是第一个参数str2是string类型,表示从字符串str2的stridx处开始,并将其用来拷贝构造str6(索引从0开始)
    std::string str6(str2, stridx);
    // 7.将字符数组"This is str7"从第stridx开始,长为strlen的子字符串用来构造str7(索引从0开始)
    std::string str7("This is str7", stridx, strlen+1);
    // 8. 表示将strlen个'A'字符初始化str8,此时第二个参数必须是char型字符
    std::string str8(strlen, 'A');
    // 9. copy  从str8中位置0开始赋值3个字符到char*变量中,返回复制的字符个数, 注意这是深拷贝
    char str9[4];
    std::size_t n = str8.copy(str9, 3, 0);
    // 10. substr   返回从位置0开始,共2个字符的新字符串,注意这是深拷贝
    std::string str10 = str8.substr(0, 2);
    

    std::cout << "str1: " << str1 << std::endl;
    std::cout << "str2: " << str2 << std::endl;
    std::cout << "str3: " << str3 << std::endl;
    std::cout << "str4: " << str4 << std::endl;
    std::cout << "str5: " << str5 << std::endl;
    std::cout << "str6: " << str6 << std::endl;
    std::cout << "str7: " << str7 << std::endl;
    std::cout << "str8: " << str8 << std::endl;
    std::cout << "9.copy(): " << "n:" << n << "; str9: " << str9 << std::endl;
    str9[2] = 'b';
    std::cout << "str9: " << str9 << "; str8: " << str8 << std::endl;
    std::cout << "str10: " << str10 << "; str8: " << str8 << std::endl;
    str10[0] = 'c';
    std::cout << "str10: " << str10 << "; str8: " << str8 << std::endl; 

    // 结果:
    // str1: 
    // str2: This is str2
    // str3: This is str3
    // str4: This is str2
    // str5: Thi
    // str6: is is str2
    // str7: is i
    // str8: AAA
    // 9.copy(): n:3; str9: AAA
    // str9: AAb; str8: AAA
    // str10: AA; str8: AAA
    // str10: cA; str8: AAA

    return str1,str2,str3,str4,str5,str6,str7,str8;
}
void basic_operation(){
    // 0. 将字符数组赋值给string类型变量str
    std::string str = "I am a string";
    std::string str2 = "wo shi zi fu chuan";
    // 1. cout可以直接一次性打印str,而不像容器vector需要遍历才能打印;
    std::cout << "1.str: " << str << std::endl;
    // 2. 通过下标索引string类型某个字符; 或者通过string::at()成员函数函数,推荐使用后者;
    std::cout<< "2.第3个字符:" << str[2] << ";每个字符类型:" << typeid(str[2]).name() << std::endl;
    std::cout<< "2.第4个字符:" << str.at(3) << ";每个字符类型:" << typeid(str.at(3)).name() << std::endl;
    // 3. string类型变量的大小:string::size(); string::length();string::max_size;string::capacity();
    std::cout<< "3.str.size(): " << str.size() << std::endl;            // size()与length()函数功能一样,返回当前string类型变量的长度;
    std::cout<< "3.str.length(): " << str.length() << std::endl;
    std::cout<< "3.str.max_size(): " << str.max_size() << std::endl;    // 返回string类型最多字符数,超出会抛出length_error异常
    std::cout<< "3.str.capacity(): " << str.capacity() << std::endl;    // 已经分配的内存中,string对象能包含的最大字符数,即不用增加内存就能使用的字符数;
    // 4. 改变string类型变量指定长度,如果该长度小于字符串长度,则截取,否则,使用\0 补充;
    str.resize(3);
    std::cout << "4.str.resize(3)" << str << std::endl;
    str.resize(5, 'n');    // 改变字符串长度,如果指定长度大于当前字符串长度,用指定字符填充;
    std::cout << str << ";str最大容量:" << str.capacity() << std::endl; 
    // reserve重新分配string类型变量的容量,不会填充数据;如果指定容量为n,原来容量为c,当n>c时则重新分配后容量为max(n,2c);当n<c时则重新分配后容量为min(n,c);
    // 分配过程:http://blog.sina.com.cn/s/blog_4a0824490102vvqj.html
    // (1) 分配新的内存块,它有容器目前容量的倍数。在大部分实现中,vector和string的容量每次以2为因数增长。也就是说,当容器必须扩展时,它们的容量每次翻倍。
    // (2) 把所有元素从容器的旧内存拷贝到它的新内存。
    // (3) 销毁旧内存中的对象。
    // (1) 回收旧内存。
    str.reserve(20);        
    std::cout << str << ";str 长度:" << str.length() << ";str最大容量:" << str.capacity() << std::endl;
    str.reserve(31);        
    std::cout << str << ";str 长度:" << str.length() << ";str最大容量:" << str.capacity() << std::endl;
    str.reserve(41);        
    std::cout << str << ";str 长度:" << str.length() << ";str最大容量:" << str.capacity() << std::endl;
    char a[] = "I am a const char array";
    std::cout << typeid(a).name() << std::endl;
    // 5. 判空与清空
    std::cout << "5.str.empty(): " << str.empty() << std::endl;
    str.clear();
    std::cout << "5.str.clear(): " << str.empty() << std::endl;
    
    // 结果:
    // 1.str: I am a string
    // 2.第3个字符:a;每个字符类型:c
    // 2.第4个字符:m;每个字符类型:c
    // 3.str.size(): 13
    // 3.str.length(): 13
    // 3.str.max_size(): 2147483647
    // 3.str.capacity(): 15
    // 4.str.resize(3)I a
    // I ann;str最大容量:15
    // I ann;str 长度:5;str最大容量:30
    // I ann;str 长度:5;str最大容量:60
    // I ann;str 长度:5;str最大容量:41
    // A24_c
    // 5.str.empty(): 0
    // 5.str.clear(): 1
}
void zeng(){
    std::string str("I am a handsome string in my mom's heart!");
    // 1. 在str末尾添加
    str.append("also in my heart.");     // 末位添加字符数组(const char*型, const char[]的数组名即为const char*)
    std::cout << "1.str.append( ):" << str << std::endl;
    str.push_back('~');                  // 末位添加单个字符(char型)
    std::cout << "1.str.push_back( ):" << str << std::endl;
    // 2. insert函数,C++中insert函数有10中重载(不同的C++会引入新的的重载形式);  https://www.cnblogs.com/meihao1203/p/9670680.html
    std::string str2("string");
    str2.insert(1,2,'S');                // 在索引为1的位置添加2个字符s
    std::cout << "2.1 insert():" << str2 << std::endl;

    str2.insert(3, "Tt");                // 在索引为3的位置插入Tt
    std::cout << "2.2 insert():" << str2 << std::endl;

    str2.insert(6, "str", 1);            // 在索引为6的位置插入str索引为1的字符
    std::cout << "2.3 insert():" << str2 << std::endl;

    str2.insert(6, "str", 1, 2);         // 在索引为6的位置插入str索引为1开始的2个字符,即插入tr
    std::cout << "2.4 insert():" << str2 << std::endl;

    str2.insert(6, "str", 1, std::string::npos); // 在索引为6的位置插入str索引1开始到结束的字符,即插入tr
    std::cout << "2.4 insert():" << str2 << std::endl;

    std::string::iterator it = str2.insert(str2.begin(), 'a');         // 第一个参数为const_iterator,第二个字符'a';
    std::cout << "2.5 *it:" << *it << "; str2:" << str2 << std::endl;  // str.begin()返回可读可写指向字符串第一个元素的迭代器
    std::string::iterator it2 = str2.insert(str2.cbegin(), 'a');       // str.cbegin()返回只读(const iterator)的只想字符串第一个元素的迭代器
    std::cout << "2.5 *it2:" << *it2 << "; str2:" << str2 << std::endl;
    
    str2.insert(++str2.begin(), 2, 'b');   // 在str索引为1的位置插入2个字符'b'
    std::cout << "2.6 insert(): " << str2 << std::endl;
    std::string::iterator it3 = str2.insert(++str2.cbegin(), 2, 'b');
    std::cout << "2.6 insert(): " << str2 << std::endl;
    std::cout << "2.6 *it3: " << *it3 << std::endl;

    std::string::iterator it4 = str2.insert(str2.end(), str2.begin(), str2.end());
    std::cout << "2.7 str: " << str2 << std::endl;
    std::string::iterator it5 = str2.insert(std::end(str2), std::begin(str2), std::end(str2));
    std::cout << "2.7 str: " << str2 << std::endl;
     
    // 3. 字符串拼接
    std::string str3 = "str3";
    std::string str4("this is str4", 8, 4);
    std::string str5 = str3 + str4;
    std::cout << "3. str5: " << str5 << std::endl;

    // 结果:
    // 1.str.append( ):I am a handsome string in my mom's heart!also in my heart.
    // 1.str.push_back( ):I am a handsome string in my mom's heart!also in my heart.~
    // 2.1 insert():sSString
    // 2.2 insert():sSSTttring
    // 2.3 insert():sSSTttsring
    // 2.4 insert():sSSTtttrsring
    // 2.4 insert():sSSTtttrtrsring
    // 2.5 *it:a; str2:asSSTtttrtrsring
    // 2.5 *it2:a; str2:aasSSTtttrtrsring
    // 2.6 insert(): abbasSSTtttrtrsring
    // 2.6 insert(): abbbbasSSTtttrtrsring
    // 2.6 *it3: b
    // 2.7 str: abbbbasSSTtttrtrsringabbbbasSSTtttrtrsring
    // 2.7 str: abbbbasSSTtttrtrsringabbbbasSSTtttrtrsringabbbbasSSTtttrtrsringabbbbasSSTtttrtrsring
    // 3. str5: str3str4
}

void shan_gai(){
    std::string str1 = "This is str1";
    std::cout << "str1: " << str1 << std::endl;             // str1: This is str1
    // 1. assign共有9种重载形式(不同的C++会引入新的的重载形式)
    str1.assign("ABC");             // 清空字符串,并将”ABC“赋值给str1
    std::cout << "1.1 str1: " << str1 << std::endl;         // 1.1 str1: ABC
    str1.assign("ABC", 2);          // 清空字符串,并将”ABC“前两个字符赋值给str1
    std::cout << "1.2 str1: " << str1 << std::endl;         // 1.2 str1: AB
    str1.assign("ABC", 1, 1);       // 清空字符串,并将”ABC“索引1开始的1个字符赋值给str1
    std::cout << "1.3 str1: " << str1 << std::endl;         // 1.3 str1: B
    str1.assign(5, 'B');            // 清空字符串,并将”ABC“索引1开始的1个字符赋值给str1
    std::cout << "1.4 str1: " << str1 << std::endl;         // 1.4 str1: BBBBB
    // 2. replace共有17种重载形式(不同的C++会引入新的的重载形式)
    std::string str2("This is str2");
    str2.replace(1,2,"abc");        // str2从索引1开始,共2个字符被“abc”替换
    std::cout << "2.1 replace(): " << str2 << std::endl;    // 2.1 replace(): Tabcs is str2
    str2.replace(1,3,"hi",0, -1);      // str2从索引1开始,共2个字符被“th”的全部字符替换
    // 等效于 str2.replace(1,3,"hi",0, std::string::npos);
    std::cout << "2.2 replace(): " << str2 << std::endl;    // 2.2 replace(): This is str2
    str2.replace(1,2,str1.c_str(), 3);        // str2从索引1开始,共2个字符被c语言字符串的前3个字符替换
    std::cout << "2.3 replace(): " << str2 << std::endl;    // 2.3 replace(): TBBBs is str2
    str2.replace(1,3,str1.c_str());        // str2从索引1开始,共3个字符被c语言字符串的替换
    std::cout << "2.4 replace(): " << str2 << std::endl;    // 2.4 replace(): TBBBBBs is str2
    str2.replace(1,5,2,'H');        // str2从索引1开始,共5个字符被2个字符H的替换
    std::cout << "2.5 replace(): " << str2 << std::endl;    // 2.5 replace(): THHs is str2
    std::string::iterator it1 = ++str2.begin(), it2 = str2.begin() + 3;
    str2.replace(it1, it2, "hi");     // hi字符串替换str2的it1到it2范围的字符串,[it1, it2)
    std::cout << "2.6 replace(): " << str2 << std::endl;    // 2.6 replace(): This is str2
    // 3. erase
    str2.erase(7, 2);                // 从索引7开始共删除2个字符,包括索引7,即删除索引7、8
    std::cout << "3.1 erase(): " << str2 << std::endl;    // 3.1 erase(): This istr2
    str2.erase(it1);                // 删除迭代器it1指向的单个字符
    std::cout << "3.2 erase(): " << str2 << std::endl;    // 3.2 erase(): Tis istr2
    str2.erase(it1, it2);                // 删除迭代器it1和it2范围内的字符,[it1, it2)
    std::cout << "3.3 erase(): " << str2 << std::endl;    // 3.3 erase(): T istr2
    // 4. clear
    std::cout << "4 str2.capacity(): "<< str2.capacity() << "; str2.length(): " << str2.length() << "; str2.max_size(): " << str2.max_size()<< "; str2: " << str2 << std::endl;  // 4 str2.capacity(): 15; str2.length(): 7; str2.max_size(): 2147483647; str2: T istr2
    str2.clear();    // clear()不会影响capacity(),max_size();但会影响length();
    std::cout << "4 str2.capacity(): "<< str2.capacity() << "; str2.length(): " << str2.length() << "; str2.max_size(): " << str2.max_size() << "; str2: " << str2 << std::endl;  // 4 str2.capacity(): 15; str2.length(): 0; str2.max_size(): 2147483647; str2:
    // 5. reverse() 在头文件algorithm中
    std::string str3("ABC",2);
    std::reverse(str3.begin(), str3.end());     // [begin,end)
    std::cout << "5. reverse(): " << str3 << std::endl;
    // 6. swap
    std::string str4 = "abc";
    str4.swap(str3);
    std::cout << "str3: " << str3 << "; str4:" << str4 << std::endl;    // str3: abc; str4:BA
}

void cha(){
    std::string str1 = "This is str1 and str2";
    std::string str2(str1, 0, str1.length());
    std::cout << "str2: " << str2 << std::endl;          // str2: This is str1 and str2
    // 1. find      从头到尾开始查找
    std::size_t start = 0, n = 11;                       // size_t = long unsigned int
    std::size_t pos = str2.find("str", 0);               // 在str2中按头到尾的顺序查找c风格字符串"str"首次出现的位置,第二个参数默认为0
    // 源码中定义:static const size_type    npos = static_cast<size_type>(-1);    Value returned by various member functions when they fail.
    if(pos != str2.npos)                                 // str2.npos 与 std::string::npos的类型和数值大小(4294967295)一样
        std::cout << "1.1 find: " << pos << std::endl;   // 1.1 find: 8
    std::string str3 = "is";
    pos = str2.find(str3, 0);                            // 在str2中按头到尾的顺序查找"is"首次出现的位置,第二个参数默认为0
    if(pos != std::string::npos)
        std::cout << "1.2 find: " << pos << std::endl;   // 1.2 find: 2
    pos = str2.find("str", 0, 2);                        // 在str2中按头到尾的顺序从位置索引0开始查找c风格字符串"str"前2个字符首次出现的位置
    std::cout << "1.3 find: " << pos << std::endl;       // 1.3 find: 8
    // 2. rfind
    str2.rfind("s", 3);                                  // 从位置3开始倒叙查找c风格字符串
    str2.rfind("str1", 3, 2);                            // 从位置3开始倒序查找c风格字符串"str1"中前2个字符 
    str2.rfind(str3, 3);                                  //    从位置3开始倒序查找字符串
    // 3. find_first_of        从头到尾的顺序查找
    std::string str4 = "str4";
    std::size_t pos2 = str1.find_first_of(str4, 0);      // 向后查找str1中与str4相等的任何字符,查找到首次相等字符并返回在str1的位置,否则返回npos;第二个参数可省略,默认0
    std::cout << "3.1 find_first_of(): " << pos2 << std::endl;   //3.1 find_first_of(): 3
    pos2 = str1.find_first_of("str4", 0);                // 向后查找str1中与c风格字符串str4相等的任何字符,查找到首次相等字符并返回在str1的位置,否则返回npos;第二个参数可省略,默认0
    std::cout << "3.2 find_first_of(): " << pos2 << std::endl;   //3.2 find_first_of(): 3
    pos2 = str1.find_first_of("str4", 3, 4);             // 向后查找str1中与c风格字符串str4相等的任何字符,从位置3开始,共查找4个字符,查找到首次相等字符并返回在str1的位置,否则返回npos;第二个参数可省略,默认0
    std::cout << "3.3 find_first_of(): " << pos2 << std::endl;   //3.3 find_first_of(): 3
    // 4. find_last_of   从尾到头的顺序查找
    std::size_t pos3 = str1.find_last_of(str4, str1.length()-1);   // 从最后一个元素向前查找
    pos3 = str1.find_last_of("str4", str1.length()-1);   // 从最后一个元素向前查找
    pos3 = str1.find_last_of("str4", str1.length()-1, 3);          // 从最后一个元素向前查找,共向前查找3个字符
    // 5. find_first_not_of  // 从头到尾
    str1.find_first_not_of(str4, 0);   //
    str1.find_first_not_of("str4", 0);
    str1.find_first_not_of("str4", 3, 4);
    // 6. find_last_not_of
    str1.find_last_not_of(str4, 0);   //
    str1.find_last_not_of("str4", 0);
    str1.find_last_not_of("str4", 3, 4);
    // 7. compare
    std::string str6 = "str6";
    std::string str7("str7");
    std::string str8("This is str8", 0, 12);
    int tmp1 = str6.compare(str7);
    std::cout << "7.1 str6.compare(str5): " << tmp1 << std::endl;    // 7.1 str6.compare(str5): -1
    int tmp2 = str6.compare(0, 4, str8);                             // 从str8的位置0开始共比较4个字符
    std::cout << "7.2 str6.compare(str5): " << tmp2 << std::endl;    // 7.2 str6.compare(str5): 1
    int tmp3 = str6.compare(0, str6.length()-1, str8, 8, 3);         // 从str8的位置8开始共3个字符形成的字符串,与str6从位置0开始共str6.length()-1个字符比较
    std::cout << "7.3 str6.compare(0, str6.length()-1, str8, 8, 3): " << tmp3 << std::endl; 
    int tmp4 = str6.compare("str9");
    int tmp5 = str6.compare(0, 4, "str10");
    // 8. <=  >=   ==
    if("str8" >= "str4"){
        std::cout << "str8 >= str4" << std::endl;    // str8 >= str4
    }
    if("str7" <= "str8"){ 
        std::cout << "str7 <= str8" << std::endl;    // str7 <= str8
    } 
    if("str8" == "str8"){
        std::cout << "str8 == str8" << std::endl;    // str8 == str8
    } 

}

void convert(){
    // std::string 与c风格字符串之间转换
    // 1. c风格字符串转换为string : 可直接把char []、const char[]、char*、const char*赋值给string类型变量; char [] 的数组名为char*
    char c_string1[] = "c_string1";
    std::string str1 = c_string1;
    const char c_string2[] = "c_string2";
    std::string str2 = c_string2;
    char* c_string3 = c_string1;
    std::string str3 = c_string3;
    const char* c_string4 = "c_string4";
    std::string str4 = c_string4;
    
    std::cout << "str1: " << str1 << std::endl;
    std::cout << "str2: " << str2 << std::endl;
    std::cout << "str3: " << str3 << std::endl;
    std::cout << "str4: " << str4 << std::endl;



    // 2. string转换为c风格字符串
    const char* c_string5 = str1.c_str();   // c_string5: 常量指针
    const char* c_string6 = str1.data();
    std::cout << "c_string5: " << c_string5 << std::endl;
    std::cout << "c_sting6: " << c_string6 << std::endl;
    
    // 结果:
    // str1: c_string1
    // str2: c_string2
    // str3: c_string1
    // str4: c_string4
    // c_string5: c_string1
    // c_sting6: c_string1
     
    
}
int main(){
    std::string str1,str2,str3,str4,str5,str6,str7,str8;
    // str1,str2,str3,str4,str5,str6,str7,str8 = declare_string();
    // basic_operation();
    // zeng();
    shan_gai();
    // cha();
    // convert();
    return 0;
}

 

参考

1. https://blog.csdn.net/liitdar/article/details/80498634

 

posted @ 2020-06-10 08:52  ya花间持酒  阅读(564)  评论(0编辑  收藏  举报