C/C++字符串归纳整理

一、C风格的字符串

1.1 C字符串常用方法

C风格的字符串不是一种类型,而是为了表达和使用字符串而约定成俗的一种写法,按此写法字符串是以空字符('\0')结尾的字符数组,一般利用指针来操作这些字符串。

下面是一些C标准的String函数,位于头文件<cstring>中,传入此类函数的指针必须是以空字符作为结束的数组,且这些函数不负责验证传入的指针参数:

    char s1[] = "hello";
    char *s2 = "hello";

    // strlen(p) 返回p的长度,空字符不计算在内
    cout << strlen(s1) << endl; // 5
    cout << strlen(s2) << endl; // 5

    // strcmp(p1, p2) 比较p1、p2的相等性
    cout << strcmp(s1, s2) << endl; // s1 = s2,返回 0

    /**
     * strcat(p1, p2),将p2附加到p1之后,返回p1
     * p1一定要有足够的空间来容纳p2,不然凉凉
     */
    char s3[15] = {
    
    };
    strcat(s3, s1);
    strcat(s3, "_strcat");
    cout << s3 << endl; // hello_strcat

    /**
     * strcpy(p1, p2),将p2拷贝给p1,返回p1
     * p1必须是一个字符数组的指针
     * p1一定要有足够的空间来容纳p2,不然还是凉凉
     */
    char s4[] = "nullptr";
    strcpy(s4, "_strcpy");
    cout << s4 << endl; // _strcpy

对于字符串更深一步的理解,可以看看这篇博客:https://www.jianshu.com/p/6469fad4d5d5

1.2 混用string和C字符串

任何出现字符串字面值的地方都可以用以空字符结束的字符数组来替代:

  • 可以使用以空字符结束的字符数组来初始化string对象或为string对象赋值。
  • string对象的加法运算中允许使用以空字符结束的字符数组作为其中的一个运算对象(不能两个都是);在string对象的复合赋值运算中允许使用以空字符结束的字符数组作为右侧的运算对象。

【注】我们无法保证c_str()函数返回的数组一直有效,如果后续的操作改变了string对象的值就可能让之前返回的数组失去作用。如果执行完c_str()函数后程序想一直使用其返回的数组,最好将该数组重新拷贝一份。

    // C风格——>string
    char a[] = "hello";
    char *b = "hello";
    string sa(a);
    string sb(b);

    // string——>C风格
    const char *c = sa.c_str();

二、标准库类型string

标准类型string表示可变长的字符序列,使用string类型必须首先包含头文件<string>

2.1 定义和初始化string对象

初始化string对象的方式

    string s1;           //默认初始化,s1是一个空串
    string s2(s1);       //直接初始化,s2是s1的副本
    string s2 = s1;      //拷贝初始化,等同于s2(s1)
    string s3("hello");  // s3是"hello"的副本
    string s3 = "hello"; //等同于s3("hello")
    string s4(5, 'c');   //等同于s("ccccc")

2.2 string对象上的操作

1)string::size_type类型,是一个无符号类型的值,可以存放任何string对象的长度值,也可以使用auto和decltype来推断变量类型。

int main(int argc, char const *argv[]) {
    
    
    string s1, s2;
    cin >> s1 >> s2;
    string s3 = s1 + s2;
    auto s3_len = s3.size();
    for (string::size_type i = 0; i < s3_len; i++)
        cout << s3[i] << endl;
        
    return 0;
}

2)string对象的比较操作:两个string对象相等,意味着长度相同,且每个位置上面的字符也相同(大小写敏感)。string对象的大小关系是逐一按照字典顺序来确定,如"hello""hello world"相比,前者小于后者。

3)string对象相加:当把string对象和字符串字面值及字符字面值混在一条语句中使用时,必须确保每个加法运算符(+)的两侧的运算至少有一个是string。但是注意下面两种情况:

    //正确,s4 + " world"构成了一个新的string对象
    string s4 = "hello";
    string s5 = s4 + " world" + "!" + "\n";

    //错误
    string s4 = "!";
    string s5 = "hello" + " world" + s4 + "\n";

4)string操作常用的方法:

os<<s           //s写到输出流os中,返回os
is>>s           //is中读字符串赋给s,字符串以空白分隔,返回is
getline(is,s)   //从is中读取一行到s,返回is
s.empty()       //s为空返回true,否则返回false
s.size()        //返回s中字符的个数
s[n]            //返回s中第n个字符的引用,位置n从0开始计算
s1+s2           //返回s1和s2连接后的结果
s1=s2           //s2赋值给s1
s1==s2          //如果s1和s2中所含字符完全一样,则相等
s1!=s2          //否则不等(对字母大小写敏感)
<,<=,>,>=       //按照字符在字典中的顺序比较大小(对字母大小写敏感)

2.3 处理string对象中的字符

<cctype>头文件中的函数:

isalnum(c)  //当c是字母或数字时为真
isalpha(c)  //当c是字母时为真
iscntrl(c)  //当c是控制字符时为真
isdigit(c)  //当c是数字时为真
isgraph(c)  //当c不是空格但可以打印时为真
islower(c)  //当c是小写字母时为真
isprint(c)  //当c是可以打印的字符时为真(即c是空格或c具有可视形式)
ispunct(c)  //当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)
isspace(c)  //当c是空白时为真(即c是空格、横向制表符、纵向制表符、回车符、换行符、进纸符中的一种)
isupper(c)  //当c是大写字母时为真
isxdigit(c) //当c是十六进制数字时为真
tolower(c)  //如果c是大写字母,输出对应的小写字母;否则原样输出c
toupper(c)  //如果c是小写字母,输出对应的大写字母;否则原样输出c

1)可以使用范围for语句对string对象遍历访问:如果只是访问string对象而不改变对象的值,可以采用for (auto c : str),此时cstr中的某个字符的副本;如果是要改变string对象的值,则就必须采用for (auto &c : str)引用的方式,此时c不再是副本,而是str中某个字符的引用。

2)也可以使用下标指定或随机访问:如同使用下标访问数组一样,不过需要注意下标越界的情况。

    string str1("Hello World!!!");
    decltype(str1.size()) punct_cnt = 0;
    for (auto c : str1) //这里不是引用,c只是一个临时变量,改变c不会改变str
        if (ispunct(c))
            punct_cnt++;
    cout << punct_cnt << endl; // 3

    string str2("hello world!!!");
    for (auto &c : str2) //这里是引用
        c = toupper(c);
    cout << str2 << endl; // HELLO WORLD!!!

    string str3("hello world!!!");
    for (string::size_type index = 0;
         index < str3.size() && !isspace(str3[index]); index++)
        str3[index] = toupper(str3[index]);
    cout << str3 << endl; // HELLO world!!!

三、额外的string操作

3.1 构造string的额外方法

    const char *cp = "Hello World!!!";         //以空字符结束
    char noNull[] = {
    
    'H', 'e', 'l', 'l', 'o'}; //不是以空字符结束
    string s1(cp);                             // Hello World!!!
    string s2(noNull);    //未定义:noNull不是以空字符结束
    string s3(noNull, 3); // Hel
    string s4(cp + 6, 5); // World
    string s5(s1, 6, 5);  // World
    string s6(s1, 6);     // World!!!
    string s7(s1, 6, 20); // World!!!
    string s8(s1, 16);    //抛出out_of_range异常

    string s9 = s1.substr(6, 5); // World
    string s10 = s1.substr(6);   // World!!!

3.2 数值转换

    int i = 434;
    string s = to_string(i);
    double d = stod(s);
    long l = stol(s);

    string s2 = "pi = 3.14";
    auto index = s2.find_first_of("+-.0123456789");
    double sd = stod(s2.substr(index));

猜你喜欢

转载自blog.csdn.net/qq_42570601/article/details/114947206