C++字符串

567 阅读5分钟

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):检查所传的字符是否是标点符号字符