【C++】学习笔记六——String类

String类

要使用string类,必须在程序中包含头文件string。string类位于名称空间std中,因此必须提供一条using编译指令,或者使用std::string。string类定义隐藏了字符串的数组性质,能够像处理普通变量那样处理字符串。

程序4.7

//strtype1.cpp  ——使用C++string类
#include<iostream>
#include<string>
int main()
{
    using namespace std;
    char charr1[20];                              //创建一个空数组
    char charr2[20] = "jaguar";                   //创建一个初始化数组
    string str1;                                  //创建一个空string对象
    string str2 = "panther";                      //创建一个初始化对象

    cout << "Enter a kind of feline: ";
    cin >> charr1;
    cout << "Enter another kind of feline: ";
    cin >> str1;                                  //使用cin进行输入
    cout << "Here are some felines:\n";
    cout << charr1 << " " << charr2 << " "
        << str1 << " " << str2                    //使用cout进行输出
        << endl;
    cout << "The third letter in " << charr2 << " is "
        << charr2[2] << endl;
    cout << "The third letter in " << str2 << " is "
        << str2[2] << endl;                       //使用数组表示法
    cin.get();
    cin.get();
    cin.get();
    return 0;
}

运行结果:
这里写图片描述

在很多方面,使用string对象的方式与使用字符数组相同。

  • 可以使用C-风格字符串来初始化string对象;
  • 可以使用cin来将键盘输入存储到string对象中;
  • 可以使用cout来显示string对象;
  • 可以使用数组表示法来访问存储在string对象中的字符。

string对象和字符数组之间的主要区别是,可以将string对象声明为简单对象,而不是数组。
类设计让程序能够自动处理string的大小,例如,str1的声明创建一个长度为0的string对象,但程序将输入读取到str1中时,将自动调整str1的长度。
这使得与使用数组相比,使用string对象更方便安全。可以将char数组视为一组用于存储一个字符串的char存储单元,而string类变量是一个表示字符串的实体。

1. C++11字符串初始化

C++11允许将列表初始化用于C-风格字符串和string对象:

char first_date[] = {"Le Chapon Dodu"};
char second_date[] {"The Blegant Plate"};
string third_date = {"The Bread Bowl"};
string fourth_date {"Hank's Fine Eats"};

2. 赋值、拼接和附加

不能将一个数组赋给另一个数组,但可以将一个string对象赋给另一个string对象:

char charr1[20];
char charr2[20] = "jaguar";
string str1;
string str2 = "panther";
charr1 = charr2;                    //invalid
str1 = str2;                        //valid

string类简化了字符串合并操作。可以使用运算符+将两个string对象合并起来,还可以使用使用运算符+=将字符串附加到string对象的末尾:

string str3;
str3 = str1+str2;                //将str1和str2合并并赋给str3
str1 += str2;                    //将str2附加到str1末尾 

程序4.8

// strtype2.cpp  赋值、附加、拼接
#include<iostream>
#include<string>
int main()
{
    using namespace std;
    string s1 = "penguin";
    string s2, s3;

    cout << "You can assign one string object to another: s2 = s1\n";
    s2 = s1;
    cout << "s1: " << s1 << ", s2: " << s2 << endl;
    cout << "You can assign a C-style string to a string object.\n";
    cout << "s2 = \"buzzard\"\n";
    s2 = "buzzard";
    cout << "s2: " << s2 << endl;
    cout << "You can concatenate strings: s3 = s1 + s2\n";
    s3 = s1 + s2;
    cout << "s3: " << s3 << endl;
    cout << "You can append strings.\n";
    s1 += s2;
    cout << "s1 += s2 yields s1 = " << s1 << endl;
    s2 += " for a day";
    cout << "s2 += \" for a day\" yields s2 = " << s2 << endl;

    cin.get();
    return 0;
}

运行结果:
这里写图片描述

3. string类的其他操作

头文件cstring(string.h)提供了一些函数:

strcpy(charr1, charr2);             //将charr2复制给charr1
strcat(charr1, charr2);             //将charr2附加到charr1末尾

在VS2015中进行编译时,使用strcpy和strcat会报错,并建议使用strcpy_s和strcat_s。
报错信息:

error C4996: ‘strcpy’: This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

报错解决办法:

  • 按alt+F7打开属性管理器
  • 配置选择所有配置
  • 在C/C++下选择预处理器
  • 在右侧预处理器定义点击编辑
  • 在打开的窗口添加_CRT_SECURE_NO_WARNINGS
    这里写图片描述

程序4.9

//strtype3.cpp 
#include<iostream>
#include<string>
#include<cstring>
int main()
{
    using namespace std;
    char charr1[20];                              //创建一个空数组
    char charr2[20] = "jaguar";                   //创建一个初始化数组
    string str1;                                  //创建一个空string对象
    string str2 = "panther";                      //创建一个初始化对象

    //string对象和字符数组的赋值
    str1 = str2;
    strcpy(charr1, charr2);                     //这里在使用strcpy时发出警告,无法生成,使用上述解决方法

    //string对象和字符数组的附加
    str1 += " paste";
    strcat(charr1, " juice");                   //这里在使用strcat时发出警告,无法生成

    //获取string对象和C-风格字符串的长度
    int len1 = str1.size();
    int len2 = strlen(charr1);

    cout << "The string " << str1 << " contains "
        << len1 << " characters.\n";
    cout << "The string " << charr1 << " contains "
        << len2 << " characters.\n";

    cin.get();
    return 0;
}

运行结果:
这里写图片描述

处理string对象的语法通常比使用C字符串函数简单,尤其是进行较为复杂的操作时,比如:

str3 = str1 +str2;

使用C-风格字符串则需:

strcpy(charr3,charr1);
strcat(charr3,charr2);

另外,在使用字符数组时,总是存在目标数组过小,无法存储指定信息的危险,如:

char site[10] = "house";
strcat(site, " of pancakes");       //memory problem

4. string类I/O

使用cin>>来将输入存储到string对象中和使用cout<<来显示string对象的用法,与C-风格字符串相同。但在读取一行时,二者有所不同。

程序4.10

//strtype4.cpp
#include<iostream>
#include<string>
#include<cstring>
int main()
{
    using namespace std;
    char charr[20];
    string str;

    cout << "Length of string in charr before input: "
        << strlen(charr) << endl;
    cout << "Length of string in str before input: "
        << str.size() << endl;
    cout << "Enter a line of text: \n";
    cin.getline(charr, 20);                          //指出最大长度
    cout << "You entered: " << charr << endl;
    cout << "Enter another line of text:\n";
    getline(cin, str);                      //此时cin是一个参数,不需指定长度
    cout << "You entered: " << str << endl;
    cout<< "Length of string in charr after input: "
        << strlen(charr) << endl;
    cout << "Length of string in str after input: "
        << str.size() << endl;

    cin.get();
    cin.get();
    cin.get();
    return 0;
}

运行结果:
这里写图片描述

在用户输入之前,该程序指出数组charr的长度为31,这比该数组的长度要大:首先,未初始化的数组的内容是未定义的;其次,函数strlen()从数组的第一个元素开始计算字节数,直到遇到空字符。对未初始化的数据,第一个空字符出现的位置是随机的,因此运行该程序时,得到的数组长度很可能不同。

在用户输入之前,str的字符串长度为0,这是因为未初始化的string对象长度被自动设置为0。

程序4.10也指出了在输入一行时,数组和string类对象的不同。

cin.getline(charr,20);
getline(cin, str);

5. 其他形式的字符串字面值

对类型wchar_t、char16_t、char32_t,C++分别使用前缀L、u和U表示:

wchar_t title[] = L"Chief Astrogator";    //wchar_t字符串
char16_t name[] = u"Felonia Ripova";      //char16_t字符串
char32_t car[] = U"Humber Super Snipe";   //char32_t字符串

对UTF-8编码方案,使用前缀u8。

C++11新增了原始字符串(raw)。在原始字符串中,字符表示的就是自己。比如\n表示反斜杠\和n两个字符,而不是换行符。在原始字符串中,可以直接使用双引号(”),而不必繁琐的使用\。
原始字符串使用”( )”来作为界定符,而不是” “。并使用前缀R:

cout<< R"(Jim "King" Tutt uses "\n" instead of endl.)"<<'\n';

上述代码将输出:Jim “King” Tutt uses “\n” instead of endl.
如果不使用原始字符串,将需要输入以下代码:

cout << "Jim \"King\" Tutt uses \"\\n\" instead of endl."<<'\n';

在输入原始字符串时,按回车键不仅会移到下一行,还会在原始字符串中添加回车字符。

如果要在原始字符串中包含)”,便一起在见到第一个)”时,将会认为字符串到此结束。但原始字符串允许在表示字符串开头的”(之间添加其他字符,同时在表示字符串结尾的)”之间也添加相同的字符,比如使用 “+* ( )+*”

cout << R"+*("(Who wouldn't?)", she whispered.)+*"<<endl;

将输出”(Who wouldn’t?)”, she whispered.
注意两边添加的字符不是对称关系,而是顺序相同。

自定义界定符是,可在默认界定符之间添加任意数量的基本字符,但空格、左括号、右括号、斜杠和控制字符(制表符和换行符)除外。

可将前缀R和其他字符串前缀结合使用,以标识wchar_t等其他类型的原始字符串。可将R放在前面,也可放在后面,如Ru或uR。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值