十七、C++字符串(二)1、字符串的应用

需求:设计一个程序,用户输入属性id或者pass或者role可以把对应的内容显示出来,给定字符串如下:

string str{“id=user;pass=632105;role=郝英俊;”};

//设计一个程序,用户输入属性id或者pass或者role可以把对应的内容显示出来#include #include using std::string;int main(){    string str{ "id=user;pass=632105;role=郝英俊;" };    string strIn;    string outPut;    while (true)    {        std::cout <> strIn;        int lfind;    //find()函数查找的值是一个整数,不是字符串        lfind = str.find(strIn + "=");        if (lfind == std::string::npos)std::cout << "你查找的属性不存在";        else        {            int lend = str.find(";",lfind);           outPut = str.substr(lfind + strIn.length() + 1, lend - lfind - strIn.length() - 1);            std::cout << "你查找的" << strIn << "属性的值为:" << outPut << std::endl;        }    }}

2、string函数补充

1)string插入字符串

.insert()是string类型的一个方法,可以在string字符串的指定位置插入另一个字符串,基本语法如下:

//插入字符串基本语法.insert(要插入的位置,要插入的字符串);string id{"id=;"}id.insert(3,"testid");    //在第3个字符的位置插入字符串testid,最后id的值为id=testid//插入字符串的高级用法.insert(要插入的位置,要插入的字符个数,要插入的字符);string id{"id=;"}id.insert(3,6,'*');   //在第3个位置插入6个*号,最后id的值为id=******
//insert()字符串插入函数基本用法#include #include using std::string;int main(){string strA { "id=;" };strA.insert(3, "user");std::cout << "字符串strA插入后的字符串为:" << strA << std::endl;string strB{ "id=;" };strB.insert(3,6,'*');  //此处插入的是字符,不是字符串,所以要使用单引号std::cout << "字符串strB插入后的字符串为:" << strB << std::endl;}

2)insert插入字符串的扩展用法

//insert()扩展用法语法.insert(要插入的位置,要插入的字符串,要插入的字符串的起始位置,要插入的大小);string id{"id=;"};id.insert(3,"killertestid123456",6,6);  //id=testis.insert(要插入的位置,要插入的字符串,要插入的大小);string id{"id=;"};id.insert(3,"killertestid123456",6);  //id的值为id=killer  从开始位置截取6个字符
//insert()扩展用法示例#include #include using std::string;int main(){string strA{ "id=;" };    //在原字符串的第三个位置开始插入,插入的内容为此处字符串的第6个位置开始截取,截取6个strA.insert(3, "killertestid123456", 6, 6);std::cout << "字符串strA插入后的字符串为:" << strA << std::endl;string strB{ "id=;" };     //在原字符串的第三个位置开始插入,插入的内容为此处字符串的第0个位置开始截取,截取6个strB.insert(3, "killertestid123456", 6);  //此处插入的是字符,不是字符串,所以要使用单引号std::cout << "字符串strB插入后的字符串为:" << strB << std::endl;}

3、指针数组字符串

1)string字符串不是一个单纯的指针或者数组

#include #include using std::string;int main(){string str{ "12345" };std::cout << "字符串中第1个字符的值为:" << str[0] << std::endl;std::cout << "字符串中第2个字符的值为:" << str[1] << std::endl;std::cout << "字符串中第3个字符的值为:" << str[2] << std::endl;std::cout << "字符串的地址为:" << (int)&str << std::endl;std::cout << "str[0]的地址为:" << (int)&str[0] << std::endl;std::cout << "str[0]的地址为:" << (int)&str[1] << std::endl;str = str + "abcdesdajhdhjakd";std::cout << "字符串长度增加后的地址为:" << (int)&str << std::endl;std::cout << "字符串长度增加后str[0]的地址为:" << (int)&str[0] << std::endl;std::cout << "字符串长度增加后str[0]的地址为:" << (int)&str[1] << std::endl;}/*结果显示:如果str的地址和str[0]的地址一致,说明str相当于一个数组但是str的地址和str[0]的地址不一样,说明str不是一个简单的数组,从str[0]的地址开始,地址才是连续的当字符串长度增加后,str的地址不变,但是str[0]开始,后面的每个字符的地址都会变化*/

2)获取string字符串的指针

​在内存里的布局,与C字符串(char*)不同的是,C字符串以0结尾,而string字符串由于专门记录其长度的属性,在实现的时候,并没有严格要求是否以0结尾。但是在C++11标准推出后,要求string字符串也以0结尾

​通过.c_str()方法可以得到一个const char*的指针指向str储存字符数据的内存空间(返回的是一个常量指针,只能写不能读)

​通过.data()方法可以得到一个const char*的指针指向str储存字符数据的内存空间

​在c++17标准下,.data()方法得到的是一个char*的指针

#include #include using std::string;int main(){string str{ "12345" };const char* baseStrA = str.c_str();const char* baseStrB = str.data();std::cout << "字符串的地址为:" << (int)&str << std::endl;std::cout << "通过c_str获取的字符串地址为为:" << (int)baseStrA << std::endl;std::cout << "通过c_str获取的字符串地址为为:" << (int)baseStrB << std::endl;}

3)string替换字符串的内容

​.replace是string类型提供的一种方法,可以替换string字符串中的内容。语法如下

//replace()字符串替换语法.replace(要替换的内容起始位置,要替换的程度,"替换后的内容");string str{"id=user;"};str.replace{3,4,"zhangsan"}; //从原字符串的第三个位置开始,替换四个字符,替换内容为新的字符串//replace()其他语法.replace(要替换的内容起始位置,要替换的长度,替换后的字符长度,'字符');str.replace(3,4,6,'*'); //str的内容为:id=******
//replace()字符串替换函数基本用法#include #include using std::string;int main(){string strA{ "id=user;" };//在原字符串的第3个位置开始替换,替换后面的4个字符strA.replace(3, 4, "zhangsan");std::cout << "字符串strA替换后的字符串为:" << strA << std::endl;string strB{ "id=user;" };//在原字符串的第3个位置开始替换,替换后面的4个字符,并替换为6个*号strB.replace(3, 4, 6, '*');  //此处插入的是字符,不是字符串,所以要使用单引号std::cout << "字符串strB替换后的字符串为:" << strB << std::endl;}

4)replace()函数的扩展用法

//replace()函数的扩展语法.replace(要替换的内容起始位置,要替换的长度,"替换后的内容",替换后内容的节选长度);string str{"id=user;"};str.replace(3,4,"zhangsan;pass=255;",8); //str=zhangsan//replace()函数的扩展语法.replace(要替换的内容起始位置,要替换的长度,"替换后的内容",替换后内容的起始位置,替换后内容的节选长度);string str{"id=user;"};str.replace(3,4,"zhangsan;pass=255;",5,3); //str=san;
#include #include using std::string;int main(){string strA{ "id=user;" };//在原字符串的第3个位置开始替换,替换后面的4个字符strA.replace(3, 4, "zhangsan;pass=255;", 8); std::cout << "字符串strA替换后的字符串为:" << strA << std::endl;string strB{ "id=user;" };strB.replace(3, 4, "zhangsan;pass=255;", 5, 3);  std::cout << "字符串strB替换后的字符串为:" << strB << std::endl;}

5)字符串的删除

​erase()是string类型提供的一种方法,可以删除string字符串中的内容,语法如下:

//字符串的删除erase()函数语法一.erase(要删除的起始位置,要删除的起始长度);string str{"id=user;"};str.erase(3,4);   //std为id=;//从起始位置开始删除所有内容.erase(要删除的起始位置);string str{"id=user;"};str.erase(3);   //std为id=.earse();删除字符串所有内容.clear();删除字符串所有内容

4、字符串补充

1)字符的存储及读取

​字符串再C/C++的学习中一直是一个比较麻烦的点,但是只要知道”计算机中万物皆数字”,则所有的问题都可以迎刃而解。

​字符的存储:先通过编码表转化为数子,再把数字转化为二进制进行存储(字符->编码表->二进制数字)

​字符的读取:先把二进制数字读取出来,再根据编码表转化为字符(二进制数字->编码表->字符)

​字符编码表:ASCII、GBK、UNICODE

2)练习

​需求:设计一个程序,要求用户输入中英文混合内容,正确的计算出长度并显示出来。比如用户输入:你好,我的世界。结果输出为7。

​思路:因为字符的ASCII码范围为0-127,只要超过127就表明是一个中文字符

#include #include using std::string;int main(){string strIn{};std::cout <> strIn;int length{};for (int i = 0; strIn[i]; i++){if (strIn[i] < 0)i++;length++;}std::cout << "你输入的字符串长度为:" << length << std::endl;}

2)string字符串转化为数字

通过std::to_string(数字)可以将数字转化为字符串。通过一下函数可以将字符串转化为数字

作用语法用法
将字符串转化为intstd::stoi(字符串)int a=stoi(“123”)
将字符串转化为longstd::stol(字符串)long a=stol(“123”)
将字符串转化为long longstd::stoll(字符串)long long a=stoll(“123”);
将字符串转化为unsigned longstd::stoul(字符串)unsigned long a=stoul(“123”)
将字符串转化为unsigned long longstd::stoull(字符串)unsigned long long a=stoull(“123”)
将字符串转化为floatstd::stof(字符串)float a=stof(“123”)
将字符串转化为doublestd::stod(字符串)double a=stod(“123”)
将字符串转化为long doublestd::stold(字符串)long double a=stold(“123”)

将字符串转化为数字后,可以进行计算

#include #include using std::string;int main(){string strIn{};std::cout <> strIn;int length{};for (int i = 0; strIn[i]; i++){if (strIn[i] < 0)i++;length++;}std::cout << "你输入的字符串长度为:" << length << std::endl;}

3)stringstream流

​std::stringstream流定义在头文件中,std::cout组织数据的形式有时候要比string字符串要方便。std::stringstream可以像std::cout一样组织数据。std::stringstream.str()方法将会返回一个string,里面是std::stringstream的内容,即将流中的内容提取出来

//stringstream流语法std::stringstream str;str<<"你好"<<123;std::string _str=str.str();  //_str的内容为"你好123"
//stringstream流简单使用#include #include #include using std::string;int main(){std::stringstream strA;strA << "你好 [" << std::hex << 500 << "]   "<<std::dec<<123;string strB = strA.str();std::cout << strB;}

5、游戏麟江湖排行榜设计

​需求:我们通过网络获得了麟江湖游戏玩家的数据,现在我们要为我们的游戏设计一个战力(exp)排行榜系统,排序贵u则为战力由高到低,当战力相同时,根据ID的字母顺序进行排序(如A要排在B的前面)数据如下:

“id=TomyClare;exp=9523;id=Sunny;exp=9523;id=DyBaby;exp=25301;id=Simple;exp=25301;id=Bkacs11;exp=2100;id=DumpX;exp=36520;”

​根据这个数据生成玩家排行榜!

#include #include using std::string;typedef struct Role {string Id;int Exp;}*PROLE;int main(){string strData{ "id=TomyClare;exp=9523;id=Sunny;exp=9523;id=DyBaby;exp=25301;id=Simple;exp=25301;id=Bkacs11;exp=2100;id=DumpX;exp=36520;" };int istart{}, iend{}, icount{};for (int i = 0; i < strData.length(); i++){if (strData[i] == ';'){icount++;i += 3;}}PROLE pRole = new Role[icount / 2];icount = 0;do {istart = strData.find("id=", istart);if (istart == std::string::npos) break;iend = strData.find(";", istart + 3);pRole[icount].Id = strData.substr(istart + 3, iend - istart - 3);istart = iend + 1;istart = strData.find("exp=", istart);iend = strData.find(";", istart + 4);pRole[icount++].Exp = std::stoi(strData.substr(istart + 4, iend - istart - 4));istart = iend + 1;} while (true);//冒泡排序for (int i = 1; i < icount; i++){for (int j = 1; j  pRole[j - 1].Exp){Role tmp = pRole[j - 1];pRole[j- 1] = pRole[j];pRole[j] = tmp;}}}for (int i = 1; i < icount; i++){std::cout << pRole[i].Id << "  " << pRole[i].Exp << std::endl;}}