3.12 C++字符串
C++ 提供了两种类型的字符串表示形式:C风格字符串和C++引入的 string 类类型。
C风格的字符串起源于C语言,并在 C++ 中继续得到支持。
字符串实际上是使用 null 字符 '\0' 终止的一维字符数组。
3.12.1 C语言风格字符串
示例代码:C语言风格字符串定义使用
using namespace std;
int main()
{
char str1[]={'h','e','l','l','o','\0'};
char str2[]="hello";
//srr1等价于str2
cout<<"str1="<<str1<<" 长度="<<strlen(str1)<<endl;
cout<<"str2="<<str2<<" 长度="<<strlen(str2)<<endl;
return 0;
}
C++代码里照常可以使用C语言处理字符串的一些常规函数。
序号 |
函数 & 目的 |
1 |
strcpy(s1, s2);复制字符串 s2 到字符串 s1。 |
2 |
strcat(s1, s2);连接字符串 s2 到字符串 s1 的末尾。 |
3 |
strlen(s1);返回字符串 s1 的长度。 |
4 |
strcmp(s1, s2);如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。 |
5 |
strchr(s1, ch);返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。 |
6 |
strstr(s1, s2);返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。 |
(1)、示例代码:拷贝字符串
using namespace std;
int main()
{
char str1[10]="hello ";
char str2[10]="world!";
strcpy(str1,str2); //拼接字符串
cout<<"str1="<<str1<<" 长度="<<strlen(str1)<<endl;
cout<<"str2="<<str2<<" 长度="<<strlen(str2)<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
str1=world! 长度=6
str2=world! 长度=6
(2)、示例代码:拼接字符串
using namespace std;
int main()
{
char str1[100]="hello ";
char str2[]="world!";
strcat(str1,str2); //拼接字符串
cout<<"str1="<<str1<<" 长度="<<strlen(str1)<<endl;
cout<<"str2="<<str2<<" 长度="<<strlen(str2)<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
str1=hello world! 长度=12
str2=world! 长度=6
3.12.2 C++风格字符串
C++ 大大增强了对字符串的支持,除了可以使用C风格的字符串,还可以使用内置的 string 类。
string 类处理起字符串来会方便很多,完全可以代替C语言中的字符数组或字符串指针,使用 string 类需要包含头文件<string>。
(1)、示例代码: 创建C++风格字符串
using namespace std;
int main()
{
string str1="hello world"; //创建字符串
string str2("hello world");//创建字符串
cout<<"str1="<<str1<<" 长度:"<<str1.length()<<endl;
cout<<"str2="<<str2<<" 长度:"<<str2.length()<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
str1=hello world 长度:11
str2=hello world 长度:11
在实际编程中,有时候必须要使用C风格的字符串,string 类提供了一个转换函数 c_str(),该函数能够将 string 字符串转换为C风格的字符串,并返回该字符串的 const 指针(const char*)。
(2)、示例代码: 转为C风格字符串
using namespace std;
int main()
{
string str1="hello world"; //C++ string类定义字符串
const char *p=str1.c_str(); //转为C语言风格的字符串
cout<<"str1="<<str1<<endl;
cout<<"p="<<p<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
str1=hello world
p=hello world
3.12.3 C++字符串常见的操作演示
更多的字符串操作方法可以参考网址:
http://www.cplusplus.com/reference/string/string/capacity/
String类型常见的操作:
s.empty(); 如果s为空串,则返回true,否则返回false
s.size(); 返回s中字符的个数
s[n]; 返回s中位置为n的字符,从0开始计数
s1+s2; 把s1和s2拼接成一个新的字符串,返回新生成的字符串
s1=s2; 把s1的内容替换为s2的一个副本
s1==s2; 比较s1和s2的内容,相等则返回true,否则返回false
!=,<,<=,>和>= 保持这些操作符惯有的含义
示例代码:
using namespace std;
int main()
{
//字符串的常见拼接操作
string str1="hello "; //C++ string类定义字符串
string str2="world";
string str3=str1+str2; //两个string类拼接
cout<<"str3="<<str3<<endl;
str3+=" 欢迎学习C++字符串操作"; //拼接字符串,+号两边必须有一个是string类型
cout<<"str3="<<str3<<endl;
//字符串使用关系运算符比较
if(str2=="world")
{
cout<<str2<<"==world"<<endl;
}
else
{
cout<<str2<<"!=world"<<endl;
}
//字符串使用关系运算符比较
if(str1==str2)
{
cout<<str1<<"=="<<str2<<endl;
}
else
{
cout<<str1<<"!="<<str2<<endl;
}
//遍历字符串
for(int i=0;i<str1.size();i++)
{
cout<<str1[i];
}
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
str3=hello world
str3=hello world 欢迎学习C++字符串操作
world==world
hello !=world
hello
string对象的加法被定义为拼接,如把s2追加到s1的末尾可直接用s1+=s2表达式即可。当需要string对象和字符串混合拼接时,+操作符的左右操作数中必须有一个是string对象。
3.12.4 字符串的输入输出
string类重载了输入输出运算符,可以用>>进行输入,用<<进行输出。
示例代码:
using namespace std;
int main()
{
string s1;
cout<<"请输入字符串:"<<endl;
cin>>s1;
cout<<"你输入的字符串="<<s1<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
请输入字符串:
欢迎学习C++编程
你输入的字符串=欢迎学习C++编程
3.12.5 访问字符串中的字符
string字符串也可以像C风格的字符串一样按照下标来访问其中的每一个字符。string 字符串的起始下标仍是从 0 开始。
示例代码:
using namespace std;
int main()
{
string s1="1234567890";
cout<<"s1="<<s1<<endl;
s1[2]='A';
s1[3]='B';
cout<<"s1="<<s1<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
s1=1234567890
s1=12AB567890
3.12.6 字符处理
在实际开发中,经常要对string对象的单个字符进行处理,在cctype头文件中包含了各种字符操作函数。
下面列出了这些函数:
isalnum(c);如果c是数字或字母,则为true
isalpha(c);如果c是字母,则为true
iscntrl(c);如果c是控制字符,则为true
isdigit(c);如果c是数字,则为true
isgraph(c);如果c不是空格,但可打印,则为true
islower(c);如果c是小写字母,则为true
isprint(c);如果c是可打印的字符,则为true
ispunct(c);如果c是标点符号,则为true
isspace(c);如果c是空白字符,则为true
isupper(c);如果c是大写字母,则为true
isxdigi(c);如果c是十六进制,则为true
tolower(c);返回其小写字母形式
toupper(c);返回其大写字母形式
3.12.7 字符串插入、替换、删除
String支持的方法如下:
s.insert(pos,n,c); 在下标为pos的元素之前插入n个字符c
s.insert(pos,s2); 在下标为pos的元素之前插入string对象s2的副本
s.insert(pos,s2,pos2,len); 在下标为pos的元素之前插入s2从下标pos2开始的len个字符
s.insert(pos,cp,len); 在下标为pos的元素之前插入cp所指向数组的前len个字符
s.insert(pos,cp); 在下标为pos的元素之前插入cp所指向的以空字符结束的字符串副本
s.assign(s2); 用s2的副本替换s
s.assign(s2,pos,len); 用s2从下标pos开始的len个字符替换s
s.assign(cp,len); 用cp所指向数组的前len个字符替换s
s.assign(cp); 用cp所指向的以空字符结束的字符串副本替换s
s.erase(pos,len); 删除从下标pos开始的len个字符
/*除非特殊说明,上述所有操作都返回s的引用*/
示例代码:
using namespace std;
int main()
{
string s="1234567890";
cout<<"源字符串:"<<s<<endl;
//字符串插入:
s.insert(0,"abcdefg");
cout<<"插入新数据之后:"<<s<<endl;
//字符串替换
string s2="C++";
s.assign(s2);
cout<<"字符串替换之后:"<<s<<endl;
//字符串删除
s.erase(0,1);
cout<<"字符串删除之后:"<<s<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
源字符串:1234567890
插入新数据之后:abcdefg1234567890
字符串替换之后:C++
字符串删除之后:++
3.12.8 字符串查找
string类提供了6种查找函数,每种函数以不同形式的find命名。这些操作全都返回string::size_type类型的值,以下标的形式返回匹配的位置。当没有匹配到时返回一个string::npos的特殊值。npos定义为保证大于任何有效的下标值。
/*string类型的查找操作*/
s.find(args); 在s中查找args的第一次出现
s.rfind(args); 在s中查找args的最后一次出现
s.find_first_of(args); 在s中查找args的任意字符的第一次出现
s.find_last_of(args); 在s中查找args的任意字符的最后一次出现
s.find_first_not_of(args); 在s中查第一个不属于args的字符
s.find_last_not_of(args); 在s中查找最后一一个不属于args的字符
示例代码:
using namespace std;
int main()
{
string s="欢迎学习C++编程";
cout<<"字符串查找:"<<s.find("C++")<<endl; //返回8
cout<<"字符串查找:"<<s.find("编程")<<endl; //返回11
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
字符串查找:8
字符串查找:11
上面列出的每个查找函数都有四个重载版本,如下:
c,pos 在s中,从下标pos标记的位置开始,查找字符c。pos的默认值为0
s2,pos 在s中,从下标pos标记的位置开始,查找string对象s2。pos的默认值为0.
cp,pos 在s中,从下标pos标记的位置开始,查找指针cp指向的一空字符结束的字符串。pos的默认值为0.
cp,pos,n 在s中,从下标pos标记的位置开始,查找指针cp所指向的数组的前n个字符。pos的默认值为0.
3.12.9 字符串比较
compare函数用于实现string类型的字典顺序的比价。
compare返回下面是三种可能之一:
(1) 正数,此时s1大于args所代表的string对象。
(2) 负数,此时s1小于args所代表的string对象。
(3) 0,相等。
s.compare(s2); 比较s和s2
s.compare(pos1,n1,s2); 让s中从pos1下标位置开始的n1个字符与s2做比较
s.compare(pos1,n1,s2,pos2,n2); 让s中从pos1下标位置开始的n1个字符与s2中从pos2开始的n2个字符相比较
s.compare(cp); 比较s和cp所指向的以空字符结束的字符串
s.compare(pos1,n1,cp); 让s中从pos1下标位置开始的n1个字符与cp所指向的以空字符结束的字符串比较
s.compare(pos1,n1,cp,n2); 让s中从pos1下标位置开始的n1个字符与cp所指向的字符串的前n2个字符串比较
示例代码:
using namespace std;
int main()
{
string s="欢迎学习C++编程";
if(s.compare("欢迎学习C++编程")==false)
{
cout<<"字符串相等"<<endl;
}
else
{
cout<<"字符串不相等"<<endl;
}
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
字符串相等
3.12.10 提取子字符串
substr() 函数用于从 string 字符串中提取子字符串,它的原型为:
string substr (size_t pos = 0, size_t len = npos) const;
pos 为要提取的子字符串的起始下标,len 为要提取的子字符串的长度。
示例代码:
using namespace std;
int main()
{
string s="欢迎学习C++编程";
string s2;
s2=s.substr(4,7); //提取字符串
cout<<"s="<<s<<endl;
cout<<"s2="<<s2<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
s=欢迎学习C++编程
s2=学习C++
3.12.11 字符串追加
字符串拼接函数原型如下:
string& append (const string& str);
string& append (const string& str, size_t subpos, size_t sublen);
string& append (const char* s);
string& append (const char* s, size_t n);
string& append (size_t n, char c);
append() 函数可以完成以下工作:
在字符串的末尾添加str
在字符串的末尾添加str的子串,子串以subpos索引开始,长度为sublen
在字符串的末尾添加字符串s
在字符串的末尾添加字符串s,添加的数量为n
在字符串的末尾添加n个字符c
示例代码:
using namespace std;
int main()
{
string s="12345";
s.append("abcd",4);//末尾添加4个字符
s.append(5,'A');//末尾添加5个A
cout<<s<<endl;
return 0;
}
输出结果:
PS D:\linux-share-dir\c_code> g++ .\app.cpp
PS D:\linux-share-dir\c_code> .\a.exe
12345abcdAAAAA