目录:
一、C风格字符串
二、C++风格字符串
string对象的构造 | string与C风格字符串的转换 | 元素遍历和存取 |
---|---|---|
字符串的长度和容量相关 | 元素追加和相加 | 提取子串 |
元素删除 | 元素清空 | 字符串比较 |
搜索与查找 |
一、C风格字符串
字符串处理在程序中应用广泛,C风格字符串是以’\0’(空字符)来结尾的字符数组。对字符串进行操作的C函数定义在头文件<string.h>或中。常用的库函数如下:
//*****************字符检查函数(非修改式操作) *****************
//返回str的长度,不包括null结束符
size_t strlen( const char *str );
//比较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 );
//***************** 字符控制函数(修改式操作) *****************
//将src复制给dest,返 回dest
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t count);
//concatenates two strings(拼接)
char *strcat( char *dest, const char *src );
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++头文件中,注意和头文件区分,< cstring >其实是对C标准库中的<string.h>的封装,其定义的是一些对C风格字符串的处理函数。
尽管C++支持C风格字符串,但在C++程序中最好还是不要使用它们。这是因为C风格字符串不仅使用起来不太方便,而且极易引发程序漏洞,是诸多安全问题的根本原因。
与C风格字符串相比,string不必担心内存是否足够、字符串长度,结尾的空白符等等。string作为一个类出现,其集成的成员操作函数功能强大,几乎能满足所有的需求。从另一个角度上说,完全可以把string当成是C++的内置数据类型,放在和int、double等内置类型同等位置上。string类本质上其实是 basic_string类模板关于char型的实例化。
例:string 的基本用法
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 提供了很多方便字符串操作
其中
s1.size()
返回s1字符的个数s1.length()
返回s1字符的个数s1.find("world")
查找的子串的首字符位置,或若找不到这种子串则为 npos 。s1.substr(pos, n)
返回一个string,包含s1中从pos开始的n个字符的拷贝。pos默认为0,n默认为s,size() - pos 即从pos开始的所有字符
《C++primer》中的 字符串初始化 的描述
string对象的构造
首先来看一下string类型常用的构造函数
string();//默认构造函数,生成一个空字符串
string(const char * rhs);//通过c风格字符串rhs构造一个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();// 返回一个C风格字符串(生成一个const char*指针,指向以空字符终止的数组。)
const char * data();// c++11之后与c_str()效果一致,与c_str()类似,但是返回的数组不以空字符终止。
//字符串的内容复制或写入既有的C风格字符串或字符数组内
size_type copy(char* dest, size_type count, size_type pos = 0);
//参数dest,指向目标字符串的指针
//参数count,子串长度
//参数pos,包含的首字符位置
例:
const char * ch;
string s = "HelloWolrd";
ch = s.c_str();
cout << "ch = " << ch << endl;
元素遍历和存取
返回到位于指定位置 pos 的字符的引用。不进行边界检查。若 pos > size() ,则行为未定义。
operator[]
访问指定字符
at
访问指定字符,有边界检查
reference operator[]( size_type pos )const;// 返回下标为pos的元素
const_reference operator[]( size_type pos ) const;
reference at( size_type pos ) const;// 返回下标为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 & str); //后附 string str
string & operator+=(CharT ch); // 后附字符 ch
string & operator+=(const CharT* s); //s 指向要后附的空终止字符串的指针
string & append(size_type count, CharT ch); //后附 count个字符ch
string & append(const basic_string & str); //后附字符串str
string & append(const CharT* s); //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;
参数
- pos - 要包含的首个字符的位置
- count - 子串的长度
元素删除
//移除字符
// position要移除的字符的迭代器
iterator erase(iterator position); //移除位于 position 的字符。
iterator erase(const_iterator position); //移除位于 position 的字符。
iterator erase(iterator first, iterator last); //移除范围 [first, last) 中的字符。
元素清空
//清除内容
void clear();
//例
s.clear();
例:
#include <iostream>
#include <algorithm>
#include <string>
int main()
{
std::string s = "This is an example";
std::cout << s << '\n';
s.erase(0, 5); // 擦除 "This "
std::cout << s << '\n';
s.erase(std::find(s.begin(), s.end(), ' ')); // 擦除 ' '
std::cout << s << '\n';
s.erase(s.find(' ')); // 从 ' ' 到字符串尾裁剪
std::cout << s << '\n';
}
字符串比较
//非成员函数
//以字典序比较两个字符串
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;
更多详细的 string 用法参看【cppreference.com】