C++ 中的字符串常量是用一对双引号括起来,由 '\0' 作为结束符的一组字符。字符串就是字符数组加上结束符’\0’,因此可以使用字符串来初始化字符数组,推荐使用标准库中的string
string
初始化
使用等号的初始化叫做拷贝初始化,不使用等号的初始化叫直接初始化。拷贝初始化意为先初始化值再拷贝到等号左边去,直接初始化则直接初始化对象
string s; // 默认初始化,一个空白的字符串
string s1("ssss"); // s1是字面值"ssss"的副本
string s2(s1); // s2是s1的副本
string s3 = s2; // s3是s2的副本
string s4(10, '4'); // s4初始化
string s5 = "Andre"; // 拷贝初始化
string s6 = string(10, 'c'); // 可拷贝初始化,生成一个初始化好的对象,拷贝给s6
char cs[] = "12345";
string s7(cs, 3); // 复制字符串cs的前三个字符到s当中
string s8 = "asdsfasdgf";
string s9(s8, 3, 4); // 从下标3开始4个字符的拷贝,超出size出现未定义
string比较
string已经重载== ,! = 等算数运算符
字面值与string相加
把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个+的两侧的运算对象至少有一个是string:
string s1 = "1";
string s2 = s1 + "2"; // 正确:把一个string对象和一个字面值相加
string s3 = "3" + "4"; // 错误:两个运算对象都不是string
string s4 = s1 + "5" + "6"; // 错误:+两边至少有一个是string
因为某些历史原因,也为了与C兼容,C++中的字符串字面值并不是标准库类型string的对象,字符串字面值与string是不同的类型
或使用append()函数在末尾添加字符
string s;
s.append('a');
字符访问
可以使用at(), operator[]直接访问字符,at有越界检查;operator[]无越界检查,如果index越界,则会取得不可预知的字符
string s("abcd");
cout << s[0] << s.at(2) << endl;
使用for循环访问字符:
for (auto c : str)
cout << c << endl;
如果想要改变string对象中字符的值,必须把循环变量定义成引用类型**,一般来说,迭代时不允许改变对象的值,但是通过引用就能改变所绑定的字符**
for (auto &c : str)
c = toupper(c) // 通过引用改变c的值
或使用传统方式通过下标改变字符
for (int i = 0; i < s.size(); i++) {
s[i] = toupper(s[i]);
}
获取子串
- 函数原型::
string substr(size_t pos = 0, size_t len = npos) const; - 功能: 从字符串中获取想要的子字符串
- pos: 想要获取的子字符串的第一个字符的位置
- len: 子字符串中要包含的字符数,
string::npos表示直到字符串末尾的所有字符
string s1 = "Hello World"
string s2 = s1.substr(3, 5);
string s3 = s1.substr(3, str::npos); //截取从下标3到结束的子字符串
查找子串
使用自带的find()函数,返回首次匹配的位置
string s = abcdefg, subs = "efg";
int pos = s.find(subs); // 如果找到子字符串则返回首次匹配的位置,否则返回-1
string迭代
同顺序容器一样,可以迭代string,自带迭代器begin()与end()
string s("abcdefg");
for(string::iterator it = s.begin(); it != s.end(); it++){
cout << *it;
}
//逆向迭代器
for (string::iterator it = s.rbegin(); it != s.rend(); it++){
cout << *it;
}
string插入
insert()在指定index处插入字符或字符串:insert(size_type index, size_type_count, char ch)
string s = "abc";
s.insert(1, 2, 'D') // "aDDbc"
string删除
erase()总共有三种用法:
erase(pos, n); //删除从pos开始的n个字符,如erase(0, 1)就是删除第一个字符
erase(position); //删除position处的一个字符(position是string类型的迭代器)
erase(first, last); //删除从first到last之间的字符(first和last都是迭代器)
常用方法
string长度:s.size() 或s.length()
string s = "Hello, world!"
int len = s.size();
int len = s.length(); //这两种方式是等价的
string判空:s.empty()
string s = "012345";
if(!s.empty()){
cout << s.length() << endl;
}
string清空:s.clear()
string s = "012345";
s.clear()
string替换:s.replace()
//用str替换指定字符串从起始位置pos开始长度为len的字符
string s="12345";
s=s.replace(2,3,"aa"); //s="12aa";
//用str替换迭代器起始位置和结束位置的字符
string s="12345";
s=s.replace(s.begin(),s.begin()+3,"aaa"); //s="aaa45";
常见转换
数字转string
c++11标准增加了全局函数std::to_string: ,可以方便的将各种数字类型转换成string
to_string(88);
string转int
string s = "12";
int a = atoi(s.c_str()); // 采用标准库中atoi函数
string转char*
string提供函数c_str() 或函数data() ,data除了返回字符串内容外,不附加结束符'\0',而c_str()返回一个以‘\0’结尾的字符数组。 **
c_str()函数返回一个指向正规C字符串的指针,内容与string串相同,这是为了与C语言兼容,必须通过string类对象的成员函数c_str()把string对象转换成C中的字符串样式
一定要作为函数参数传入来操作方法c_str()返回的指针,c_str()返回的是一个临时指针,不能对其进行操作
char* c;
string s="1234";
c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理
// 正确使用
char c[20];
string s="1234";
strcpy(c,s.c_str());
string s = "Hello World!";
printf("%s",s.c_str()); //输出 "Hello World!"
字符判断与处理
字符判断
继承自C的常见字符判断方法
- int isalnum(int c):检查所传的字符是否是字母和数字
- int isalpha(int c):检查所传的字符是否是字母
- int isdigit(int c):检查所传的字符是否是十进制数字
- int islower(int c):检查所传的字符是否是小写字母
- int isupper(int c):检查所传的字符是否是大写字母
- int ispunct(int c):检查所传的字符是否是标点符号字符