string类

string类

  • 构造
  • 容量操作
  • 访问及遍历
  • 修改
  • 常用string类非成员函数
  • 不同平台下string的结构
  • 写时拷贝

string是表示字符串的字符串类,为basic_string模板类的一个实例,支持流插入和流提取。

typedef basic_string<char,char_traits,allocators> string

在使用时,要包含头文件string并使用命名空间std。

构造

1.构造空的string类对象

string();
string s1;


string s("hello world!");
cin>>s1;//支持流插入
s1=s;//可以赋值
s1="hello world!";//可以赋值

2.用C-string构造string类对象

string(const char*s);
string s2("hello world!");

3.拷贝构造函数

string(const string&s);
string s3(s2);

4.用n个字符c构造string类对象

string(size_t n,char c);
string s4(11,'a');

5.截取部分字符串构造string类对象

string (const string&str,size_t pos,size_t len=npos);

npos的定义如下:
static const size_t npos = -1;
即整型的最大值

string s5(s,6,100);
//打印s5为:world!

容量操作

1.获取string类对象字符串长度

size_t size() const;
int str_length=s.lenth();

size_t length() const;
int str_length=s.size();

这两个函数没有区别,只不过为了保持以后使用其他容器时接口的统一性,推荐使用size()函数
string类_第1张图片

2.获取string类对象的容量大小

size_t capacity() const;
int str_capacity=s.capacity();

3.为string类对象字符串预留空间

void reserve (size_t n = 0);
s.reserve(100);//为s预留100个字节的空间

该函数默认预留0个字节的空间大小,其实际预留空间会比我们预期的大一点,具体大多少不同编译器有不同的机制。
该函数不能缩减容量。

s.reserve(100);//为s预留100个字节的空间
int str_capacity=s.capacity();//100

s.reserve(50);//希望缩容到50,不成功
str_capacity=s.capacity();//100

4.修改string类对象有效字符串大小

void resize (size_t n);//①
void resize (size_t n, char c);//②
s.resize(5);//缩减有效字符到5
cout<<s;//打印:hello
s.resize(4,'b');//缩减有效字符到4
cout<<s;//打印:hell

当有效字符增加后其大小超过了容量的大小,这两个函数都可以发生扩容,即影响容量capacity。
这两个函数唯一的区别是:
函数①在有效容量增加时,以‘\0’填充,函数②在有效字符增加时,以传入的字符c填充。

5.检验string类对象字符串是否为空串

bool empty() const;
s.empty();//空串返回true,非空false

6.清空string类对象有效字符

void clear();
s.clear();//清空s

将字符串的有效大小设为0,不影响容量的大小。

访问及遍历

1.下标访问

      char& operator[] (size_t pos);//这个构造函数是没有必要的
const char& operator[] (size_t pos) const;

下标访问的方式只适用于物理内存连续的结构,比如链表就不能用下标访问,下面介绍的迭代器的方法可以各种容器的访问方式,推荐使用。

2.迭代器

iterator begin();
iterator end();
string::iterator it = s.begin();
while(it!=s.end())
{
	cout<<*it;
	++it;
}
//打印:hello world!

②反向迭代器

reverse_iterator rbegin();
reverse_iterator rend()
string::reverse_iterator it = s.rbegin();
while(it!=s.rend())
{
	cout<<*it;
	++it;
}
//打印:!dlrow olleh

③const修饰的迭代器

const_iterator begin() const;
const_iterator end() const;

const_reverse_iterator rbegin() const;
const_reverse_iterator rend() const;

const修饰的迭代器用于要访问的对象被const修饰时

3.范围for

	for (char c : s)
	{
		cout << c;
	}
	//打印:hello world!

其实范围for就是简单的替换,在编译阶段其就会被替换成迭代器。

修改

1.追加(增)

//用于追加一个字符
void push_back (char c);
s.push_back('a');//追加了一个字符a

//用于追加字符串,也可以追加一个字符

string& append (const string& str);

//将str的subpos位置开始的sublen个字符进行追加
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);

//用于追加字符串,也可以追加一个字符

string& operator+= (const string& str);

string& operator+= (const char* s);

string& operator+= (char c);

我们推荐使用第③种方法来追加。

2.删除


string& erase (size_t pos = 0, size_t len = npos);

iterator erase (iterator p);

//删除2个迭代器及其之间的字符串
iterator erase (iterator first, iterator last);

3.查找

//从pos位置往后寻找,返回首次查找成功位置

size_t find (const string& str, size_t pos = 0) const;

size_t find (const char* s, size_t pos = 0) const;

//从pos位置开始往后匹配s的前n个字符
size_t find (const char* s, size_t pos, size_t n) const;

size_t find (char c, size_t pos = 0) const;

//从pos位置往前寻找,返回首次查找成功位置

size_t rfind (const string& str, size_t pos = npos) const;
	
size_t rfind (const char* s, size_t pos = npos) const;

//从pos位置开始往前匹配s的前n个字符
size_t rfind (const char* s, size_t pos, size_t n) const;

size_t rfind (char c, size_t pos = npos) const;

4.截取

//截取并返回一个string类对象
string substr (size_t pos = 0, size_t len = npos) const;

5.交换

//交换两个string类对象的内容

void swap (string& str);

要注意库中也有一个swap函数,为了交换效率,我们推荐使用string类为我们提供的swap函数。

常用string类非成员函数

1.输入

//输入结束符为delim
istream& getline (istream& is, string& str, char delim);

//输入结束符为'\n'
istream& getline (istream& is, string& str);
string s;
getline(cin,s);

若使用流插入或scanf获取字符串,默认读取到空格或换行符就不再读取。

2.数字转字符串

//用于将数字转为字符串,并返回一个string类对象

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

3.字符串转数字

//size_t一般传NULL即可,base表示str的进制

int stoi (const string&  str, size_t* idx = 0, int base = 10);
float stof (const string&  str, size_t* idx = 0);
double stod (const string&  str, size_t* idx = 0);
long double stold (const string&  str, size_t* idx = 0);
long stol (const string&  str, size_t* idx = 0, int base = 10);
long long stoll (const string&  str, size_t* idx = 0, int base = 10);
unsigned long stoul (const string&  str, size_t* idx = 0, int base = 10);
unsigned long long stoull (const string&  str, size_t* idx = 0, int base = 10);

不同平台下string的结构

1.VS,32位平台
其string内部结构包括一个联合体、2个size_t字段,一个指针,联合体用于定义了16个字节大小的存储空间,当字符串长度小于16时直接可以存进去,就不必在堆上开辟空间了,2个size_t字段用于保存字符串长度和堆上开辟的空间的大小,故其至少占:16+2*4+4=28个字节。

2.g++,32位置平台
其内部只有一个指针,指向堆区的一块空间,故其大小为4字节,堆空间内部包含如下字段:
空间总大小、字符串有效长度、引用计数、指向堆空间(用于存储字符串)的指针。

写时拷贝

用引用计数记录资源的使用者的个数。在构造一个对象时,将其计数设为1,每当需要使用该对象进行拷贝时,先不拷贝,而是使计数加1,当我们要对该资源写入且其计数大于1时,才会进行拷贝。当使用该资源的对象销毁时计数就减1,如果计数为0,就将资源释放掉。

你可能感兴趣的:(c++)