C++之字符串

C风格字符串

字符串处理在程序中应用广泛,C风格字符串是以'\0'(空字符)来结尾的字符数组。对字符串进行操作的C函数定义在头文件<string.h>或中。常用的库函数如下:

//字符检查函数(非修改式操作)
size_t strlen( const char *str );//返回str的长度,不包括null结束符
//比较lhs和rhs是否相同。lhs等于rhs,返回0; lhs大于rhs,返回正数; lhs小于rhs,返回负数
int strcmp( const char *lhs, const char *rhs );
int strncmp( const char *lhs, const char *rhs, size_t count );
//在str中查找首次出现ch字符的位置;查找不到,返回空指针
char *strchr( const char *str, int ch );
//在str中查找首次出现子串substr的位置;查找不到,返回空指针
char *strstr( const char* str, const char* substr );
//字符控制函数(修改式操作)
char *strcpy(char *dest, const char *src);//将src复制给dest,返回dest
char *strncpy(char *dest, const char *src, size_t count);
char *strcat( char *dest, const char *src );//concatenates two strings
char *strncat( char *dest, const char *src, size_t count );

在使用时,程序员需要考虑字符数组大小的开辟,结尾空字符的处理,使用起来有诸多不便。

void test0()
{
  char str[] = "hello";
  char * pstr = "world";
 
  //求取字符串长度
  printf("%d\n", strlen(str));
 
  //字符串拼接
  char * ptmp = (char*)malloc(strlen(str) + strlen(pstr) + 1);
  strcpy(ptmp, str);
  strcat(ptmp, pstr);
  printf("%s\n", ptmp);
 
  //查找子串
  char * p1 = strstr(ptmp, "world");
 
  free(ptmp);
}

C++风格字符串

C++提供了std::string(后面简写为string)类用于字符串的处理。string类定义在C++头文件中,注意和头文件区分,其实是对C标准库中的<string.h>的封装,其定义的是一些对C风格字符串的处理函数。
尽管C++支持C风格字符串,但在C++程序中最好还是不要使用它们。这是因为C风格字符串不仅使用起来不太方便,而且极易引发程序漏洞,是诸多安全问题的根本原因。与C风格字符串相比,string不必担心内存是否足够、字符串长度,结尾的空白符等等。string作为一个类出现,其集成的成员操作函数功能强大,几乎能满足所有的需求。从另一个角度上说,完全可以string当成是C++的内置数据类型,放在和int、double等内置类型同等位置上。string类本质上其实是basic_string类模板关于char型的实例化。
我们先来看一个简单的例子:

void test1()
{
  //C风格字符串转换为C++风格字符串
  std::string s1 = "hello";
  std::string s2("world");
 
  //求取字符串长度
  cout << s1.size() << endl;
  cout << s1.length() << endl;
 
  //字符串的遍历
  for(size_t idx = 0; idx != s1.size(); ++idx)
 {
    cout << s1[idx] << " ";
 }
  cout << endl;
 
  //字符串拼接
  std::string s3 = s1 + s2;
  cout << "s3 = " << s3 << endl;
 
  //查找子串
  size_t pos = s1.find("world");
 
  //截取子串
  std::string substr = s1.substr(pos);
  cout << "substr = " << substr << endl;
}

std::string提供了很多方便字符串操作的方法。

string对象的构建

string();//默认构造函数,生成一个空字符串
string(const char * rhs);//通过c风格字符串构造一个string对象
string(const char * rhs, size_type count);//通过rhs的前count个字符构造一个string
对象
string(const string & rhs);//复制拷贝构造函数
string(size_type count, char ch);//生成一个string对象,该对象包含count个ch字符
string(InputIt first, InputIt last);//以区间[first, last)内的字符创建一个string对
象

string与C风格字符串的转换

C风格字符串转换为string字符串相对来说比较简单,通过构造函数即可实现。但由于string字符串实际上是类对象,其并不以空字符'\0'结尾,因此,string字符串向C风格字符串的转化是通过3个成员函数完成的,分别为: 

const char *c_str() const;// 返回一个C风格字符串
const char *data() const;// c++11之后与c_str()效果一致
//字符串的内容复制或写入既有的C风格字符串或字符数组内
size_type copy(char* dest, size_type count, size_type pos = 0) const;

 元素遍历和存取

string对象可以使用下标操作符[]和函数at()对字符串中包含的字符进行访问。需要注意的是操作符[]并不检查索引是否有效,如果索引超出范围,会引起未定义的行为。而at()会检查,如果使用at()的时候索引无效,会抛出out_of_range异常。

reference operator[]( size_type pos );// 返回下标为pos的元素
const_reference operator[]( size_type pos ) const;//
reference at( size_type pos );// 返回下标为pos的元素
const_reference at( size_type pos ) const;//

除此以外,还可以使用迭代器进行遍历访问

iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;

其示意图如下:

字符串的长度和容量相关

bool empty() const;
size_type size() const;
size_type length() const;
size_type capacity() const;
size_type max_size() const;

元素追加和相加

string &operator+=(const string & tr);
string &operator+=(CharT ch);
string &operator+=(const CharT* s);
string &append(size_type count, CharT ch);
string &append(const basic_string & str);
string &append(const CharT* s);
string &append(InputIt first, InputIt last);
//以下为非成员函数
string operator+(const string & lhs, const string & rhs);
string operator+(const string & lhs, const char* rhs);
string operator+(const char* lhs, const string & rhs);
string operator+(const string & lhs, char rhs);
string operator+(char lhs, const string & rhs);

提取子串

string substr(size_type pos = 0, size_type count = npos) const;

元素删除

iterator erase(iterator position);
iterator erase(const_iterator position);
iterator erase(iterator first, iterator last);

元素清空

void clear();

字符串比较

//非成员函数
bool operator==(const string & lhs, const string & rhs);
bool operator!=(const string & lhs, const string & rhs);
bool operator>(const string & lhs, const string & rhs);
bool operator<(const string & lhs, const string & rhs);
bool operator>=(const string & lhs, const string & rhs);
bool operator<=(const string & lhs, const string & rhs);

搜索与查找

//find系列:
size_type find(const basic_string & str, size_type pos = 0) const;
size_type find(const CharT* s, size_type pos = 0) const;
size_type find(const CharT* s, size_type pos, size_type count) const;
size_type find(char ch, size_type pos = npos ) const;
//rfind系列:
size_type rfind(const basic_string & str, size_type pos = 0) const;
size_type rfind(const CharT* s, size_type pos = 0) const;
size_type rfind(const CharT* s, size_type pos, size_type count) const;
size_type rfind(char ch, size_type pos = npos) const;

思维导图

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~|Bernard|

你的鼓励是我写下去最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值