十六、C++字符串(一)

1、原生字符串实现将两个字符串拼接
//原生字符串实现将两个字符串拼接
#include <iostream>
#include <locale>
int main()
{
    char strA[0x10] = "123";  //定义字符串
    char strB[0x10] = "456";

    setlocale(LC_ALL, "chs");
    char strC[0x20];         //定义一个临时的字符数组
    memcpy(strC,strA,strlen(strA));  //先通过memcpy将字符串A放入临时字符数组中
    memcpy(strC + strlen(strA), strB, strlen(strB)+1);  //再将字符串B拼接到临时字符数组,加1是为了将字符串结尾的0也拷贝进来
    std::cout << strC<<std::endl;
}
2、std::string

​ std::string是C++提供的字符串声明类,利用std::string可以声明一个C++的字符串,但是需要引入头文件string

1)std::string字符串的声明

//std::string字符串声明
std::string str{"吃葡萄不吐葡萄皮!"};
std::cout<<str;
std::cin>>str;
//std::string字符串声明使用
#include <iostream>
#include <string>
int main()
{
	std::string str{ "吃葡萄不吐葡萄皮!asdjki" };
	std::cout << str << std::endl;
	std::string strA;
	std::cout << "请输入下一句:";
	std::cin >> strA;
	std::cout << strA<<std::endl;
}

2)字符串的截取

//字符串的截取语法一
std::string 变量名称{"字符串",要截取的长度};

//字符串的截取语法二
std::string 变量名称{"字符串",起始位置,要截取的长度};

注:字符串的截取,对中文支持不佳
//字符串截取示例
#include <iostream>
#include <string>
int main()
{
	std::string strA{ "HelloWorld",5 };  //截取前5个字符Hello
	std::cout << strA << std::endl;

	std::string strB{ "你好我的世界",3 };  //对中文截取支持不佳
	std::cout << strB << std::endl;

	std::string strA{ "HelloWorld",0,5 }; //从第0位开始,截取5位
}

//要求输入用户的ID,但是限定用户的ID位数为6,若用户过多输入,只截取6位
#include <iostream>
#include <string>
int main()
{
	std::string strA{ };  
	std::cout << "请输入你的用户ID:";
	std::cin >> strA;
	std::string Id{ strA,0,6 };
	std::cout << "你输入的用户ID为:" << Id << std::endl;
}

5)字符的复制

//字符的复制语法
std::string 变量名称(要复制的个数,'字符');

//字符的复制用法
str::string str(6,'a');
std = 'aaaaaa'
//字符的复制用法
#include <iostream>
#include <string>
int main()
{
	std::string strA(6,'a');  //是圆括号,不是大括号
	std::cout << strA << std::endl;

	std::string strB( 6,97 );  //也可使用ascii码代替字符
	std::cout << strB << std::endl;
}

6)字符串的连接

//字符串的连接用法
std::string str(6,'a');
str = str+"123";
str = "aaa123";
//str = "sss"+"sss";   //错误用法
//字符串的连接用法示例
#include <iostream>
#include <string>
int main()
{
	std::string strA,strB;
	strA = "qwer";
	strB = strA +"  " +  "wasd" + "123";  //必须先要有一个string类型的变量进行拼接

	std::cout << strB << std::endl;
}

7)连接字符串和数字

//连接字符串和数字语法
std::string std::to_string(数字);   //即将数字转化为string类型的变量
std::string str = std::to_string(123);
str = "123";

#include <iostream>
#include <string>
int main()
{
	std::string strA, strB;
	strA = "用户的的年龄是:";
	strB = strA + std::to_string(3.14f);  //将字符串和数字进行拼接,可以支持float类型的数
	std::cout << strB;
}

2、std::string的进阶

1)字符串的连接

std::string str;
//str = "123" + "456"; //错误用法

//正确拼接方法
str=string{"123"}+"456";  //通过临时变量连接字符串
//str="456"+"123"+string{"123"};    //错误用法,运算优先级问题
str="456"+("123"+string{"123"});
//字符串拼接
#include <iostream>
#include <string>
using std::string;
int main()
{
	string strA, strB;
	strA = string{ "123" } + "abc";  //通过临时变量连接字符串
	strB = "qwer" + ("123" + string{ "www" });  //解决运算优先级问题

	std::cout << strA << std::endl;
	std::cout << strB << std::endl;
}

2)其他字符串拼接方法

//其他字符串拼接方法
string strA,strB;
strB="abc""def"  //去掉加号,但是拼接的必须是两个常量,用处很少
#include <iostream>
#include <string>
#define softName "JXQY"
#define softVersion "2.1"
using std::string;
int main()
{
	string strA;
	strA = softName softVersion;  //连接两个字符串常量,需要有一个空格
	std::cout << strA << std::endl;

}

3)通过append连接字符串

//append连接字符串
std::string str;
.append();  //append方法可以连接一个字符串
str.append("s");
//append连接字符串使用
#include <iostream>
#include <string>
using std::string;
int main()
{
	string strA{"qwer"};
	strA.append("123456").append("www"); //可以无限的使用append拼接字符串
	std::cout << strA << std::endl;
	strA.append(10, 'a');  //拼接10个a
	std::cout << strA << std::endl;
}
//append是改变原来的字符串

4)字符串的截取(substr)

//字符串截取语法
.substr(起始位置,要截取的长度);

std::string str{"123456"};
std::string strsub{str.substr(1)}; //得出strsub="23456"
std::string strsubA{str.substr(1,3)};  //strsubA="234"

//注:strsub()是将截取后的字符串放到一个新的字符串变量中
//字符串截取substr用法
#include <iostream>
#include <string>

int main()
{
	std::string strA{ "123456" };
	std::string strB;
	strB = strA.substr(3);  //从第3位开始截取,不会改变原来的字符串
	std::cout << "截取前的字符串为:" << strB << std::endl;
	std::cout << "截取后的字符串为:" << strB << std::endl;

	strB = strA.substr(2,2);  //从第2位开始截取,截取2位
	std::cout << "从指定位置截取后的字符串为:" << strB << std::endl;
}

5)字符串长度计算(length)

//字符串长度计算(length)语法
std::string.length();   //得到字符串的长度
std::string strA{"123"};
str.length(); //返回结果3
 
//注:对中文支持不良
//字符串长度计算(length)示例
#include <iostream>
#include <string>

int main()
{
	std::string strA{ "123456" };
	std::string strB{ "123456你好" };
	std::cout << "字符串A的长度为:" << strA.length() << std::endl;
	std::cout << "字符串B的长度为:" << strB.length() << std::endl;
}

3、字符串补充知识

1)访问string字符串中的字符

std::string strA{"0123456789ABC"};
strA[0] = '0';  //访问字符串的第0个字符
strA[10] = 'A';  //访问字符串的第10个字符

注:中文支持不佳
//输入一个10进制的数,将其转化为16进制
#include <iostream>
#include <string>
int main()
{
	int userIn;
	std::string strA{ "0123456789ABCDEF" };
	std::cout << "请输入一个十进制的数:";
	std::cin >> userIn;
	std::cout << "转化后的十六进制数为:" << strA[userIn] << std::endl;
}

2)string字符串的比较(法一)

​ string字符串可以用比较运算符和另外一个string字符串或者C标准的字符串(char*)来进行比较,支持的比较运算符有==、!=、>、<、>=、<= ,比较的原则为依次进行字符大小的比较

//string字符串的比较
string strA{"abcd"};
string strB{"bcde"};
结果为:strB>strA
//原生字符串,无法判断两个字符串是否相等
#include <iostream>
#include <string>

int main() 
{
	char* strA{ (char*)"123456" };
	char* strB{ (char*)"123456" };
	char* strC = new char[10];
	if (strA == strB)        //strA和strB是两个字符类型的指针,
	{
		std::cout << "strA和strB的地址相等" << std::endl;  //此处相等,因为两个指针指向的内存地址一样,为操作系统优化的结果
	}
	std::cout << "请输入字符串C的值:";
	std::cin >> strC;
	if (strA == strC)
	{
		std::cout<< "strA和strC的值相等" << std::endl;
	}
	else
	{
		std::cout << "strA和strC的值不相等" << std::endl;
	}
}

//string字符串的比较用法
#include <iostream>
#include <string>

int main()
{
	std::string strA{ "abcdef" };
	std::string strB;
	std::string strC{ "bcdefg" };
	std::cout << "请输入strB字符串的值:";
	std::cin >> strB;
	if (strA == strB)        
	{
		std::cout << "strA和strB的值相等" << std::endl;
	} else std::cout << "strA和strB的值不相等" << std::endl;
	if (strA > strC)
	{
		std::cout << "strA>strC" << std::endl;
	}else  std::cout << "strA<strC" << std::endl;
}

3)string字符串的比较(法二)

​ .compare()是string类型自带的一个方法,可以用来比较与另一个string字符串或C标准字符串的大小,比较完成后返回的是一个int类型的值。若两个字符串相等返回0,若大于返回负数,小于返回负数

//compare()字符串比较函数用法
string strA{"abcd"};
strA.compare("abcd"); //相等返回0
strA.compare("bcdef"); //小于返回负数
strA.compare("ABCD");  //大于返回正数

//如下用法无法得到正确结果
if(strA.compare("abcd")) //错误用法
//compare()字符串比较函数示例
#include <iostream>
#include <string>

int main()
{
	std::string strA{ "abcd" }; 
	std::cout << strA.compare("abcd") << std::endl;   //等于返回0
	std::cout << strA.compare("bcde") << std::endl;;  //小于返回-1
	std::cout << strA.compare("ABCD") << std::endl;;  //大于返回1
}

4)compare()函数的扩展用法一

//语法
.compare(起始位置,参与比较的长度,被比较的字符串);  //将截取的字符串与被比较的字符串进行比较

//示例
string strA{"abcd cdef"};
strA.compare(5,4,"cder"); //从第5个位置开始,截取4个字符进行比较,返回0
//compare()扩展用法
#include <iostream>
#include <string>

int main()
{
	std::string strA{ "abc def xyz" };
	std::cout << strA.compare(4,3,"def") << std::endl;   //返回0
	std::cout << strA.compare(4, 3, "defa") << std::endl;   //返回-1
	std::cout << strA.compare(4, 3, "ABC") << std::endl;   //返回1
}

5)compare()函数的扩展用法二

//compare()函数的扩展用法二
.compare(起始位置,参与比较的长度,被比较的字符串,被比较的字符串起始长度,被比较的字符串起始长度);

//简单示例
string strA{"abcd cdef ghijk"};
strA.compare(5,4,"cdef ghijklm",0,4); //返回0

6)字符串的搜索

​ find()函数是string类型自带的一个方法,用来搜索字符串中的内容,并且返回内容所在的位置,当返回值为std::string::npos时,表示未找到

//字符串搜索find()语法
.find(要搜索的内容,开始搜索的位置);
.find(要搜索的内容,开始搜索的位置,要纳入搜索的长度);

//字符串搜索示例
string strA{"abcd cdef ghijk"};
strA.find("cdef");  //返回值为5
strA.find("cdef",6); //从第6个位置开始查找,返回值为std::string::npos
strA.find("cdef",0,2) //返回值为2,等同于从位置0开始搜索cd
//输出学生的学号
#include <iostream>
#include <string>

int main()
{
	std::string strA{ "username:50001,studentId:10010" };
	std::string studentId;
	std::cout << strA.find("studentId:") << std::endl;  //studentId在字符串中的起始位置
	studentId = strA.substr(strA.find("studentId:")+9);
	std::cout << "学生学号为:" << studentId << std::endl;
}

7)字符串的搜索(逆向搜索)

​ ·rfind()是string类型自带的一个方法,用来搜索字符串中的内容,并且返回内容所在的位置,当返回值为std::string::npos时,表示未找到,与find不同的是,rfind是从字符串末端开始查找的。

//rfind()语法
.rfind(要搜索的内容);
string strA{"abcd cdjk ghijk"};
strA.rfind("jk")  //返回值为13