zoukankan      html  css  js  c++  java
  • 【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字符串异同:

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

    #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类型变量指定长度,如果该长度小于字符串长度,则截取,否则,使用 补充;
        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

  • 相关阅读:
    Helpers Overview
    Validation
    Support Facades
    Session Store
    位运算(参考百科)
    开源项目_可能使用到的开源项目集合
    秒杀系统架构分析与实战(转)
    shell命令之根据字符串查询文件对应行记录
    MySQL做为手动开启事务用法
    spring 加载bean过程源码简易解剖(转载)
  • 原文地址:https://www.cnblogs.com/chen-hw/p/12907098.html
Copyright © 2011-2022 走看看