【STL】C++ string基本使用

目录

一 概念

二 常见构造

三 string类对象的容量操作

1 size 和 length

2 capacity

3 reverse

4 resize

5 clear

6 empty

四 string类对象的访问及遍历操作

1 operator [ ]

2 begin + end

3 rbegin + rend

4 范围for 

五 string类对象的修改操作

1 push_back

2 append

3 operator+=

4 insert 

5 erase

6 replace 

7 swap 

8 pop_back

六 string其他操作

1 c_str

2 find

3 rfind

4 find_first_of + find_last_of

5 find_first_not_of + find_last_not_of

6 substr

七 string补充 

1 getline

2 to_string

3 stoi


一 概念

C++/C++11中std::string是个模板类,它是一个标准库。使用string类型必须首先包含头文件。作为标准库的一部分,string定义在命名空间std中。

std::string是C++中的字符串。字符串对象是一种特殊类型的容器,专门设计来操作字符序列

二 常见构造

【STL】C++ string基本使用_第1张图片

int main()
{
       string s1; //空字符串
       string s2("hello world");// 构造string类对象

       string s3(10, 'x');//包含n个字符

       string s4 = s2;//拷贝构造
       string s5(s2);//拷贝构造

       string s6 = "hello string";//隐形转换
       const string& s7 = "hello const string";//临时对象具有常属性
       cout << s1 << endl;
       cout << s2 << endl;
       cout << s3 << endl;
       cout << s4 << endl;
       cout << s4 << endl;
       cout << s6 << endl;
       cout << s7 << endl;

       //这些类是可以改变的
       s1 = s2;
       cout << s1 << endl;

       s1 = "world";
       cout << s1 << endl;

       s1 = 'x';
       cout << s1 << endl;

       return 0;
}

【STL】C++ string基本使用_第2张图片

三 string类对象的容量操作

【STL】C++ string基本使用_第3张图片

1 size 和 length

size_t size() const;

size_t length() const;

size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()

int main()
{
       string s1("hello world");
       cout << s1.size() << endl;
       cout << s1.length() << endl;

       return 0;
}

输出结果: 11   11

2 capacity

size_t capacity() const;
int main()
{
	string str("Test string");
	cout << "size: " << str.size() << "\n";
	cout << "length: " << str.length() << "\n";
	cout << "capacity: " << str.capacity() << "\n";
	return 0;
}

【STL】C++ string基本使用_第4张图片

3 reverse

void reserve (size_t n = 0);

为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。(只影响容量, 不影响数据)

int main()
{
	string s1("hello world");
	cout << s1.capacity() << endl;

	s1.reserve(500);//需要多少空间, 提前开好
	cout << s1.capacity() << endl;

	s1.reserve(100);//在vs2022下 空间容量不会缩小
	cout << s1.capacity() << endl;

	return 0;
}

【STL】C++ string基本使用_第5张图片

4 resize

void resize (size_t n);

void resize (size_t n, char c);

resize(size_tn) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用\0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。

既影响容量 也影响数据

int main()
{
	string s1("hello world");
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	cout << s1 << '\n' << endl;

	// > capacity --> 扩容+尾插
	//s1.resize(100);
	s1.resize(100, 'x');
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	cout << s1 << '\n' << endl;

	// size < n < capacity  -> 尾插
	string s2("hello world");
	cout << s2.size() << endl;
	cout << s2.capacity() << endl;
	cout << s2 << endl;
	s2.resize(12);
	cout << s2.size() << endl;
	cout << s2.capacity() << '\n' << endl;

	// n < size -> 删除数据,保留前n个
	string s3("hello world");
	cout << s3.size() << endl;
	cout << s3.capacity() << endl;
	cout << s3 << endl;
	s3.resize(5);
	cout << s3 << endl;
	cout << s3.size() << endl;
	cout << s3.capacity() << '\n' << endl;

	string s5;
	s5.resize(100, '#');
	cout << s5 << endl;

	return 0;
}

【STL】C++ string基本使用_第6张图片

5 clear

void clear();

 将string中有效字符清空,不改变底层空间大小。

int main()
{
	string s("hello world");
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.clear();
	cout << s << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	return 0;
}

【STL】C++ string基本使用_第7张图片

6 empty

bool empty() const;

 返回字符串是否为空(即其长度是否为 0)。

int main()
{
	string s("hello world");
	cout << s.empty() << endl;

	s.clear();
	cout << s.empty() << endl;
	return 0;
}

【STL】C++ string基本使用_第8张图片

四 string类对象的访问及遍历操作

【STL】C++ string基本使用_第9张图片

1 operator [ ]

char& operator[] (size_t pos);

const char& operator[] (size_t pos) const;

int main()
{
       //operator [] 
       string s1("hello world");
       for (size_t i = 0; i < s1.size(); i++)
       {
              cout << s1[i] << " ";
              //底层是这样-->cout << s1.operator[](i) << " "
       }
       cout << endl;
       s1[0] = 'x';
       cout << s1 << endl;
}

【STL】C++ string基本使用_第10张图片

 补充:

字符串中元素的访问是允许的,一般可使用两种方法访问字符串中的单一字符:下标操作符[] 和 成员函数at()。

两者均返回指定的下标位置的字符。第 1 个字符索引(下标)为 0,最后的字符索引为 length()-1。

需要注意的是,这两种访问方法是有区别的:

  • 下标操作符 [] 在使用时不检查索引的有效性,如果下标超出字符的长度范围,会示导致未定义行为。对于常量字符串,使用下标操作符时,字符串的最后字符(即 '\0')是有效的。对应 string 类型对象(常量型)最后一个字符的下标是有效的,调用返回字符 '\0'。

  • 函数 at() 在使用时会检查下标是否有效。如果给定的下标超出字符的长度范围,系统会抛出 out_of_range 异常。

int main()
{
	try
	{
		string s1("hello world");
		cout << s1.at(10) << endl;
		cout << s1.at(11) << endl;
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}

	return 0;
}

下标操作符 [] 和函数 at() 均返回字符的“引用” 

2 begin + end

iterator begin();     const_iterator begin() const;

iterator end();        const_iterator end() const;

begin()函数返回一个迭代器,指向字符串的第一个元素

end()函数返回一个迭代器,指向字符串的末尾(最后一个字符的下一个位置)

int main()
{
	string s1("hello world");
	// iterator用法像指针
	string::iterator it = s1.begin();
	while (it != s1.end())// s.end()指向'\0'
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	reverse(s1.begin(), s1.end());//左闭右开区间
	cout << s1 << endl;

	const string s2("hello world");
	s1[0] = 'x';
	//s2[0] = 'x' --> error
	cout << s1 << endl;

	//遍历s2
	string::const_iterator itt = s2.begin();
	while (itt != s2.end())
	{
		cout << *itt << " ";
		++itt;
	}
}

const_iterator it 本质保护迭代器指向的数据 *it不能修改

const iterator it 包含的迭代器本身不能修改  it不能修改 不符合我们的需求

对于迭代器可以遍历顺序表, 链表, 栈等数据结构

3 rbegin + rend

reverse_iterator rbegin();  const_reverse_iterator rbegin() const;

reverse_iterator rend();     const_reverse_iterator rend() const;

rbegin()返回一个逆向迭代器,指向字符串的最后一个字符。

rend()函数返回一个逆向迭代器,指向字符串的开头(第一个字符的前一个位置

void func(const string& s)
{
	string::const_reverse_iterator it = s.rbegin();
	while (it != s.rend())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

int main()
{
	string s1("hello world");
	string::reverse_iterator it1 = s1.rbegin();
	while (it1 != s1.rend())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;
	func(s1);
	return 0;
}

4 范围for 

int main()
{
       string s1("hello world");
       for (auto e : s1)
       {
              cout << e << " ";
       }
       cout << endl;

       return 0;
}

五 string类对象的修改操作

【STL】C++ string基本使用_第11张图片

1 push_back

void push_back (char c);

将字符附加到字符串

int main()
{
       string s1("hello");
       s1.push_back('#');
       cout << s1 << endl;
       return 0;
}
//输出 hello#

2 append

string& append(const string& str);

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 s1("123"), s2("abc");
s1.append(s2);  // s1 = "123abc"
s1.append(s2, 1, 2);  // s1 = "123abcbc"
s1.append(3, 'K');  // s1 = "123abcbcKKK"
s1.append("ABCDE", 2, 3);  // s1 = "123abcbcKKKCDE",添加 "ABCDE" 的子串(2, 3)
int main()
{
       string s1("hello");
       s1.push_back(' ');
       s1.append("world");
       cout << s1 << endl;

       string s2 = "xxxx";
       s2.append(s1);
       cout << s2 << endl;

       s2.append(++s1.begin(), --s1.end());
       cout << s2 << endl;

       return 0;
}

【STL】C++ string基本使用_第12张图片

3 operator+=

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

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

string& operator+= (char c);

int main()
{
	string s1("hello");
	string s2("world");

	string ret1 = s1 + s2;
	cout << ret1 << endl;

	string ret2 = s1 + "xx";
	cout << ret2 << endl;

	string ret3 = "xx" + s1;
	cout << ret3 << endl;

	string ret4 = 'a' + s1;
	cout << ret4 << endl;

	return 0;
}

【STL】C++ string基本使用_第13张图片

4 insert 

string& insert (size_t pos, const string& str);

string& insert (size_t pos, const char* s);

string& insert (size_t pos, const char* s, size_t n);

string& insert (size_t pos, size_t n, char c);

insert 成员函数可以在 string 对象中插入(头插)另一个字符串,返回值为对象自身的引用

int main()
{
	string s1("Limitless"), s2("00");
	s1.insert(2, "123");//在p0位置插入字符串
	cout << s1 << endl;

	s1.insert(3, s2);
	cout << s1 << endl;

	s1.insert(3, 5, 'X');//在p0位置插入n个字符
	cout << s1 << endl;

	s1.insert(3, "abc", 2);//在p0位置插入字符串前两个字符
	cout << s1 << endl;
	return 0;
}

【STL】C++ string基本使用_第14张图片

 5 erase

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

character(2)
iterator erase(const_iterator p);

range(3)
iterator erase(const_iterator first, const_iterator las
 

三种用法:

(1)erase(pos, n); 删除从pos开始的n个字符,比如erase(0, 1)就是删除第一个字符

(2)erase(position); 删除position处的一个字符(position是个string类型的迭代器)

(3)erase[first, last); 删除从first到last之间的字符(first和last都是迭代器)

int main()
{
	string s1("hello world");
	s1.erase(9, 1);
	cout << s1 << endl;

	s1.erase(4);//不指明n, 默认把4位置(包括4位置)后面所有的删除
	cout << s1 << endl;

	s1.erase(s1.begin());
	cout << s1 << endl;


	s1.erase(s1.begin(), s1.end() - 1);
	cout << s1 << endl;
	return 0;
}

【STL】C++ string基本使用_第15张图片

6 replace 

替换字符串中以字符 pos 开头的部分,并替换跨越len 字符

string& replace (size_t pos, size_t len, const string& str);

string& replace (iterator i1, iterator i2, const string& str);

int main()
{
	string s1("hello world hello yf");
	cout << s1 << endl;

	s1.replace(5, 2, "abc");//s1 pos位置开始往后2个位置被abc覆盖
	cout << s1 << endl;
	return 0;
}

【STL】C++ string基本使用_第16张图片

7 swap 

void swap (string& str);

int main()
{
	string s2("hello world");
	string s3("yf");
	s2.swap(s3);

	cout << s2 << endl;
	cout << s3 << endl;
	return 0;
}

【STL】C++ string基本使用_第17张图片

8 pop_back

尾删

void pop_back();

int main()
{
	string s2("hello  world hello yf");
	s2.pop_back();
	cout << s2 << endl;
	return 0;
}

六 string其他操作

【STL】C++ string基本使用_第18张图片

1 c_str

const char* c_str() const;

c_str()是封装的String类中的一个函数,它返回当前字符串的首字符地址。换种说法,c_str()函数返回一个指向正规C字符串的指针常量,内容与本string串相同。这是为了与C语言兼容,在C语言中没有string类型,故必须通过string类对象的成员函数c_str()把string对象转换成C中的字符串样式。

注意:一定要使用strcpy()等函数来操作c_str()返回的指针

int main()
{
       char* c;
       string s = "1234";
       c = s.c_str();// --> error
       //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理,同时编译器将会报错
       return 0;
}

 改正如下

int main()
{
       char* cstr;
       string str("Please split this phrase into tokens");
       cstr = new char[str.size() + 1];
       strcpy(cstr, str.c_str());
       cout << cstr << endl;
}

2 find

size_t find(const string& str, size_t pos = 0) const;
size_t find(const char* s, size_t pos = 0) const;
size_t find(const char* s, size_t pos, size_t n) const;
size_t find(char c, size_t pos = 0) const;

string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos。(返回值可以看成是一个int型的数)(从前向后找)

int main()
{
	string s1("hello world");
	string s2("world");
	cout << s1 << endl;

	//1.从下标0位置开始找字符
	size_t pos1 = s1.find(' ', 0);
	cout << pos1 << endl;

	//2.从下标0位置找字符串
	size_t pos2 = s1.find("world", 0);
	cout << pos2 << endl;

	//3.从下标0位置找string
	size_t pos3 = s1.find(s2, 0);
	cout << pos3 << endl;

	//从下标0位置开始找s前n个的字符串
	size_t pos4 = s1.find("woaaa", 0, 2);
	cout << pos4 << endl;
	return 0;
}

【STL】C++ string基本使用_第19张图片

3 rfind

查找字符串中最后一次出现的内容(从后向前找)

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

int main()
{
	string s1("hello world world");
	cout << s1.size() << endl;
	string s2("world");

	//1.从下标5位置往前开始找字符
	size_t pos1 = s1.rfind(' ', 5);
	cout << pos1 << endl;

	//2.从下标最后一个元素位置往前找字符串
	size_t pos2 = s1.rfind("world");
	cout << pos2 << endl;

	//3.从下标最后一个元素位置往前找string
	size_t pos3 = s1.rfind(s2);
	cout << pos3 << endl;

	//从下标16位置开始往前找s前n个的字符串
	size_t pos4 = s1.rfind("woaaa", 16, 2);
	cout << pos4 << endl;
	return 0;
}

【STL】C++ string基本使用_第20张图片

4 find_first_of + find_last_of

size_t find_first_of(const string& str, size_t pos = 0) const;
size_t find_first_of(const char* s, size_t pos = 0) const;
size_t find_first_of(const char* s, size_t pos, size_t n) const;
size_t find_first_of(char c, size_t pos = 0) const;

size_t find_last_of(const string& str, size_t pos = npos) const;
size_t find_last_of(const char* s, size_t pos = npos) const;
size_t find_last_of(const char* s, size_t pos, size_t n) const;
size_t find_last_of(char c, size_t pos = npos) const;

在字符串中搜索与其参数中指定的任何字符匹配的第一个字符。

在字符串中搜索与其参数中指定的任何字符匹配的最后一个字符。

int main()
{
	string s("hello world hello yf");
	cout << "lenth == " << s.size() << endl;

	//找l或者l 第一次出现的位置
	size_t pos1 = s.find_first_of("ll");
	cout << pos1 << endl;

	//找l或者o 第一次出现的位置
	size_t pos2 = s.find_first_of("lo");
	cout << pos2 << endl;

	//找l或者o 最后一次出现的位置
	size_t pos3 = s.find_last_of("lo");
	cout << pos3 << endl;

	//从下标5往前找
	size_t pos4 = s.find_last_of('o', 5);
	cout << pos4 << endl;

	return 0;
}

【STL】C++ string基本使用_第21张图片

5 find_first_not_of + find_last_not_of

在字符串中搜索与其参数中指定的任何字符都不匹配的第一个字符。

在字符串中搜索与其参数中指定的任何字符都不匹配的最后一个字符。

size_t find_first_not_of(const string& str, size_t pos = 0) const;
size_t find_first_not_of(const char* s, size_t pos = 0) const;
size_t find_first_not_of(const char* s, size_t pos, size_t n) const;
size_t find_first_not_of(char c, size_t pos = 0) const;

size_t find_last_not_of(const string& str, size_t pos = npos) const;
size_t find_last_not_of(const char* s, size_t pos = npos) const;
size_t find_last_not_of(const char* s, size_t pos, size_t n) const;
size_t find_last_not_of(char c, size_t pos = npos) const;

int main()
{
	string s("hello world hello yf");
	cout << "lenth == " << s.size() << endl;

	//找第一次不是 l 或者 l 的位置
	size_t pos1 = s.find_first_not_of("ll");
	cout << pos1 << endl;

	//找第一次不是 l 或者 o 的位置
	size_t pos2 = s.find_first_not_of("lo");
	cout << pos2 << endl;

	//找最后一次不是 l 或者 o 的位置
	size_t pos3 = s.find_last_not_of("lo");
	cout << pos3 << endl;

	//从下标5往前找
	size_t pos4 = s.find_last_not_of('o', 5);
	cout << pos4 << endl;

	return 0;
}

【STL】C++ string基本使用_第22张图片

find 和find_first_of   find_last_of  find_first_not_of    find_last_not_of 的共同点:

查找成功时返回所在位置,失败返回string::npos的值,string::npos一般是MAX_INT(即2^32 - 1)

不同点:

find(): 查找字符串中第一次出现字符c、字符串s的位置;

find_first_of()等: 查找字符串中字符c、字符数组s中任意一个字符出现的位置。

6 substr

string substr (size_t pos = 0, size_t len = npos) const;

 返回一个新构造的对象,其值初始化为此对象的子字符串的副本

int main()
{
	string s("hello world");
	size_t pos = s.find("world");
	cout << pos << endl;

	string sub = s.substr(pos);
	cout << sub << endl;

	return 0;
}

七 string补充 

1 getline

输入字符串 但是有空格的时候

当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读,当它读取到下一个空白字符时,它将停止读取。以下面的语句为例:

int main()
{
	string s;
	getline(cin, s);
	cout << s << endl;
	size_t pos = s.rfind(' ');
	if (pos != string::npos)
	{
		cout << s.size() - pos - 1 << endl;
	}
	else
	{
		cout << s.size() << endl;
	}

	return 0;
}

【STL】C++ string基本使用_第23张图片

2 to_string

返回表示为 val 的字符串

int main()
{
	string s1 = to_string(123);
	string s2 = to_string(100.1111);
	cout << s1 << endl;
	cout << s2 << endl;

	return 0;
}

【STL】C++ string基本使用_第24张图片

补充:

对于将数字转换为字符串来说

可以用 itoa

char * itoa ( int value, char * str, int base )

int main()
{
	int i;
	char buffer[33];
	printf("Enter a number: ");
	scanf("%d", &i);
	itoa(i, buffer, 10);
	printf("decimal: %s\n", buffer);
	itoa(i, buffer, 16);
	printf("hexadecimal: %s\n", buffer);
	itoa(i, buffer, 2);
	printf("binary: %s\n", buffer);
	return 0;
}

输出:

Enter a number: 1750
decimal: 1750
hexadecimal: 6d6
binary: 11011010110

3 stoi

解析 str 并将其内容解释为指定基数的整,该整数作为 int 值返回.

int main()
{
	string s1("123");
	string s2("100.11111");

	int ret1 = stoi(s1);
	int ret2 = stoi(s2);
	cout << ret1 << endl;
	cout << ret2 << endl;
	return 0;
}

【STL】C++ string基本使用_第25张图片

补充:

对于字符串的话 可以用aoti 

int atoi (const char * str)

分析 C 字符串,将其内容解释为整数,该整数作为 类型的值返回

本节的内容很多, 但是难度不大, 根据代码很容易上手, 但是STL的string的某些设计还是有些缺陷的, 会感觉要记住的很多, 我觉得不用全部去记, 记住肯定是记不住的, 把本节写到的这些记住就可以了, 因为其他没讲到的我们实际当中也不怎么会用, 要用的时候再去查一下也无妨, 我们最主要的是理解用法就可以了.

继续加油!

你可能感兴趣的:(c++,开发语言,stl)