zoukankan      html  css  js  c++  java
  • 我不熟悉的string类

    我不常用的string函数

    多的不说,直接上:

    assign函数

    string& assign(const char *s);       //把字符串s赋给当前的字符串
    string& assign(const string &s);     //把字符串s赋给当前字符串
    string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
    string& assign(int n, char c);       //用n个字符c赋给当前字符串
    string& assign(const string &s, int start, int n);//将s从start开始n个字符赋值给字符串
    

    assign函数很好用的。在我实习期间,将数据包转成字符串arr的时候,我直接用:

    string str = arr;
    

    最后出现了数据缺失的现象。这就是因为转成的字符串arr中间含有结束符,而如果我用赋值运算符的话,赋值到这个结束符就会停止,后面的数据都会被抛弃。

    这个时候assign函数就派上了用场,我指定字符串的大小,就可以全部赋值进去。下面用一个简单例子来说明:

    int main()
    {
        string str;
    	char arr[5] = { 'a', 'c', 's', '', 'e' };
    	str = arr;
    	cout << "使用str = arr的结果:" << endl;
    	cout << "str = " << str << endl;
    	cout << "str.size() = " << str.size() << endl;
    	cout << "str.capacity() = " << str.capacity() << endl;
    	cout << endl << "使用str.assign的结果:" << endl;
    	string ss = str.assign(arr, 5);
    	cout << "str = " << ss << endl;
    	cout << "str.size() = " << ss.size() << endl;
    	cout << "str.capacity() = " << ss.capacity() << endl;
        return 0;
    }
    

    执行结果:

    可以看到,无论是打印结果还是size,都不一样。足以说明assign并不是以结束符为界。

    assign函数可以重新赋值,可以从一个char * 或string的变量中读取指定字节数去赋值。

    at函数

    at函数和普通的重载运算符[]都是取元素的操作,但是at函数提供边界检查,当数组越界的时候会抛出异常,如果我们捕捉异常程序就可以正常进行下去。

    int main()
    {
        string str = "abcdefg";
    	try{
    		str.at(10);
    		//str[10];
    	}
    	catch (exception &e)
    	{
    		cout << e.what() << endl;
    	}
        return 0;
    }
    

    当我们用at执行,结果为:

    我们可以捕捉到这个异常:无效的字符串位置。

    而如果我们使用str[10]则会直接崩溃。

    append函数

    关于append函数,顾名思义就是在末尾添加。这就没什么好说的了,平常我用的不多,所以记录下来append函数各种重载版本。

    string& append(const char *s);        //把字符串s连接到当前字符串结尾
    string& append(const char *s, int n); //把字符串s的前n个字符连接到当前字符串结尾
    string& append(const string &s);      //同operator+=()
    string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
    string& append(int n, char c);                  //在当前字符串结尾添加n个字符c
    

    综上,append函数可以连接一个char,char * ,string,以及string和char * 中指定字节数。

    查找和替换函数

    即find, rfind, replace 函数。

    int find(const string& str, int pos = 0) const;     //查找str第一次出现位置,从pos开始查找
    int find(const char* s, int pos = 0) const;         //查找s第一次出现位置,从pos开始查找
    int find(const char* s, int pos, int n) const;      //从pos位置查找s的前n个字符第一次位置
    int find(const char c, int pos = 0) const;          //查找字符c第一次出现位置
    int rfind(const string& str, int pos = npos) const; //查找str最后一次位置,从pos开始查找
    int rfind(const char* s, int pos = npos) const;     //查找s最后一次出现位置,从pos开始查找
    int rfind(const char* s, int pos, int n) const;     //从pos查找s的前n个字符最后一次位置
    int rfind(const char c, int pos = npos) const;         //查找字符c最后一次出现位置
    string& replace(int pos, int n, const string& str); //替换从pos开始n个字符为字符串str
    string& replace(int pos, int n, const char* s);     //替换从pos开始的n个字符为字符串s
    

    先来说一下查找功能:

    find

    find就是从0位置找到最后一个位置为止,第一次出现返回其位置。

    注意其参数,无论是string还是char或者是char * ,我们都可以查找。

    另外,如果要查找一串字符的前n个字符是否出现过,find的第一个参数是const char * ,而不是string. 所以我们要传入一个C-style的字符串才可以。

    rfind

    rfind就是find的反过来,从末尾位置查找到0位置,出现的第一次返回其位置。也就是在原本字符串中最后一次出现的位置。

    和find一样,倘若要查找一个字符串前n个字符,需要转成C-style风格字符串(使用c_str()函数即可)。

    另外我们注意到,find是从0位置开始查找,而rfind的默认参数值是npos,npos是什么呢?

    std::string::npos

    这边先引入C++官方的解释:

    static const size_t npos = -1;
    Maximum value for size_t
    npos is a static member constant value with the greatest possible value for an element of type size_t.

    This value, when used as the value for a len (or sublen) parameter in string's member functions, means "until the end of the string".

    As a return value, it is usually used to indicate no matches.

    This constant is defined with a value of -1, which because size_t is an unsigned integral type, it is the largest possible representable value for this type.

    好的现在来归纳这四个段落写了什么。

    1. std::string::npos是一个static const size_t类型的,定义为-1,也就是无符号数的最大值。
    2. 当在string类函数中被用作一个作为长度的参数时, 以为着字符串的末尾。
    3. 如果是作为一个返回值,通常表示为找到合适匹配(匹配失败)。
    4. 由于size_t是一个无符号的整型,所以,npos是表示size_t的最大值。

    综上,讲得很清楚了吧。添加一点,size_t是四个字节的,所以npos为4294967295.

    以下简单验证了find和rfind的函数:

    int main()
    {
        string str = "abcdefghabcdefgh";
    	char *p = "de";
    	string s = "efg";
    	// 输出find函数返回的位置
    	cout << str.find(p) << endl;
    	cout << str.find(s.c_str(), 0, 2) << endl;
        // 输出rfind函数返回的位置
    	cout << str.rfind(p) << endl;
    	cout << str.rfind(s.c_str(), 16, 2) << endl;
    	cout << str.rfind('c') << endl;
        // 查找一个不存在字符串的返回值
    	cout << str.find("gfdg") << endl;
        return 0;
    }
    

    输出结果:

    replace 函数

    如上述函数原型,就是源字符串从pos位置开始的n个长度替换成指定的字符串,可以是string类型也可以是char * 类型。

    注意是单纯的替换,不会因为要替换的字符串长度大于n的值而覆盖原来的。且返回一个引用,也就是说,调用之后会原字符串会得到改变。如下代码显示:

    int main()
    {
        string str = "fuck off";
    	cout << str.replace(0, 3, "我不giao了") << endl;  // 现在的str就改变了。所以下面重新赋值。
    	str = "fuck off";
    	cout << str.replace(4, 1, "黑猫警长giao哥") << endl;
        return 0;
    }
    

    运行结果:

    substr

    这个其实我自己还是常用的,就是截取子串。

    //返回由pos开始的n个字符组成的字符串
    string substr(int pos = 0, int lenth = npos) const;
    

    就是从pos位置开始,截取lenth长度的字符串。

    插入和删除函数

    一样,上函数原型:

    string& insert(int pos, const char* s);     //插入字符串
    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个字符 
    

    插入、删除都会直接改变原字符串。返回一个引用。

    字面上意思如此,注意一点,插入是在pos位置的前面插入。而删除是从pos位置开始删除。

    如代码所示:

    int main()
    {
    	string str = "黑猫警长giao哥";
    	// 在0位置之前插入
    	cout << str.insert(0, "I am ") << endl;
    	// 从0位置开始删除
    	cout << str.erase(0, 5) << endl;
    	// 在结尾位置插入
    	cout << str.insert(str.size(), "是我") << endl;
        return 0;
    }
    

    运行结果如下:

    C-style和string的隐式转换关系

    C-style字符串可以直接赋值给string , 也就是说可以隐式转换成string。

    但是string类型不能直接隐式转换成C-style。 但是提供了c_str函数。

  • 相关阅读:
    LeetCode 120:三角形最小路径和
    守护进程
    G711时间戳增量和数据包大小的关系
    H264防止竞争机制
    硬编码帧率错误导致的浏览器不能播放的问题
    GCC inline
    单例模式的双检锁的隐患和优化
    Java中异常捕获子类异常捕获在父类异常前面,即小范围先被捕获
    线程运行流程图
    将二维数组转为稀疏数组
  • 原文地址:https://www.cnblogs.com/love-jelly-pig/p/9981287.html
Copyright © 2011-2022 走看看