《string类的使用介绍》

这篇具有很好参考价值的文章主要介绍了《string类的使用介绍》。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要介绍string的常见的接口的使用



一、什么是string类

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作

总结:

  1. string是表示字符串的字符串类

  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

  3. string在底层实际是**:basic_string模板类的别名**,typedef basic_string<char, char_traits, allocator> string;

  4. 不能操作多字节或者变长字符的序列。

  5. 在使用string类时,必须包含#include头文件以及using namespace std。

二、string类的使用

1、string类对象的常见构造

函数名称 功能
string s; 构造空的string类对象,即空字符串
string s1(const char* s); 复制s指向的字符串
string s2(size_t n,char c); 生成n个c字符的字符串
string s3(const string&s); 用string类对象拷贝构造

具体使用:

    string s;         // 构造空的string类对象s
 
	string s2("hello");//复制hello字符串给s2对象
 
	string s3(10, 'x');//生成10个x的字符串
 
	string s4(s2);     //用s2拷贝构造对象s4

2、string类对象的容量操作

函数 功能
size 返回字符串有效个数
length 返回有效字符串个数
capacity 返回总空间的大小
empty 判断字符串是否为空
clear 清空字符串
reserve 为字符串预留空间(有点像malloc)
resize 将有效的字符个数改成n个,多出的空间用字符c填充(有点像calloc)

具体使用

void test2()
{
	string s("hello");
 
	cout <<"size:"<< s.size() << endl;
	cout <<"length:"<< s.length() << endl;
	cout <<"capacity:"<< s.capacity() << endl;
	cout <<"empty:"<< s.empty() << endl;
}

结果如下:
《string类的使用介绍》
对于clear函数,只是将s中的字符串清空,size置为0,但是不改变底层空间capacity的大小

void test2()
{
	string s("hello");
 
	cout <<"size:"<< s.size() << endl;
	cout <<"length:"<< s.length() << endl;
	cout <<"capacity:"<< s.capacity() << endl;
	cout <<"empty:"<< s.empty() << endl;
	cout << "----------" << endl;
	s.clear();
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "empty:" << s.empty() << endl;
 
}

《string类的使用介绍》
我们再来详细看看resize:

void resize (size_t n);
void resize (size_t n, char c);

①按照给定的字符扩容

void test3()
{
	string s("hello");
	s.resize(10, 'x');//将s中的有效字符个数增加到10个,后面多出的位置用x填充
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下:
《string类的使用介绍》
②默认给定的“\0”来填充扩容

void test4()
{
	string s("hello");
	s.resize(15);//将s中的有效字符个数增加到15个,后面多出的位置用"\0"填充
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下:
《string类的使用介绍》
③当是缩小大小时,会截断字符

void test5()
{
	string s("hello");
	s.resize(3);//将s中的有效字符个数减少到3个,只剩下原来的前三个
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下:
《string类的使用介绍》
我们再来详细看看reserve:

void reserve (size_t n = 0);

①当n大于当前对象的容量时,将容量扩大到n或者大于n

void test6()
{
	string s;
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(100);//将原来的capacity扩大到100
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
}

结果如下:
《string类的使用介绍》
当n小于容量时,不会缩小到容量

void test6()
{
	string s;
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(100);//将原来的capacity扩大到100
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(20);//不会将之前的capacity缩小
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
}

结果如下:
《string类的使用介绍》
我们可以看到容量并没有缩小!!!

总结:

① resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
② reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小

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

函数名称 功能说明
operator[] (重点) 返回pos位置的字符,const string类对象调用
at 返回pos位置的字符,const string类对象调用
begin+ end begin 获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rend begin 获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
范围for C++11支持更简洁的范围for的新遍历方式

operator [] (i)

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

我们知道string类字符串的底层其实是数组实现的,于是我们可以采用下标的方式进行遍历
《string类的使用介绍》
举例说明:

void test7()
{
	string s1("hello");
	const string s2("HELLO");
	cout << s1 << " " << s2 << endl;
	cout << s1[0] << " " << s2[0] << endl;
 
	s1[0] = 'x';
	cout << s1 << endl;
 
	//s2[0] = 'x';const类对象不能修改
}

《string类的使用介绍》


at

char& at (size_t pos);
const char& at (size_t pos) const;

at的使用:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    std::string str("test string");
    for (size_t i = 0; i < str.size(); ++i)
    {
        cout << str.at(i) << " ";
    }
    return 0;
}

结果展示:
《string类的使用介绍》

总结:
operator[ ]和at函数功能相同,都是返回pos位置的字符,但是不同的是,at失败会assert断言错误,operator[ ]会抛异常


三种遍历操作:(常用)

①operator[ ]的用法
void test8()
{	
	string s1("hello");
	string s2(s1);//拷贝构造
	for (size_t i = 0; i < s2.size(); ++i)
	{
		cout << s2.operator[](i) << " ";
		cout << s2[i] << " ";
	}
	cout << endl;
	for (size_t i = 0; i < s2.size(); ++i)
	{
		s2[i] += 1;//支持修改
	}
	cout << s2 << endl;
}
②迭代器

注意:这里暂时将迭代器想象成像指针一样的类型

void test9()
{
	string s("hello");
	//迭代器的用法
	//string::iterator it = s.begin();
	auto it = s.begin();// C++11之后,直接使用auto定义迭代器,让编译器推到迭代器的类型
	while (it !=s.end())
	{
		cout << *it << endl;
		++it;
	}
}
③范围for

其实范围for的底层是将它给处理成了迭代器

void test10()
{
	string s("hello");
	for (auto ch : s)
		cout << ch << endl;
	//把s中的每个字符取出来,赋值给ch,不需要++,判断结束,自动往后迭代
}

4、string类对象的修改操作

函数 功能
push_back 在字符串后面尾插字符c
append 在字符串后面追加字符串
operator+= 在字符串后面追加字符串
c_str 返回C格式字符串(C形式的字符串打印时,遇到\0就停止了)
find+npos 从字符串pos位置开始,往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始,往前找字符c,返回该字符在字符串中的位置
substr 在字符串中,从pos位置开始,截取n个字符,然后将其返回
replace 将指定位置替换为自己想要的
swap 交换两个两个字符串(直接交换指针,效率更高)

注意:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般
    情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
①push_back
void push_back (char c);
void test11()
{
	string s("xxx");
	cout << s << endl;
	s.push_back('H');
	s.push_back('E');
	s.push_back('L');
	s.push_back('L');
	s.push_back('O');
	cout << s << endl;//将HELLO依次拼接到xxx后面
}

结果如下:
《string类的使用介绍》

②append
string& append (const string& str);
string& append (const char* s);
void test12()
{
	string s1("hello");
	string s2("C++");
	s1.append(s2);//直接拼接一个对象字符串
 
	cout << s1 << endl;
	s1.append("haha");//直接拼接一个字符串
	cout << s1 << endl;
}

结果展示:
《string类的使用介绍》

③operator+=(这是最常用的一个函数)
string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);
void test13()
{
	string s1("hello");
	string s2("world");
	s1 += s2;
	cout << s1 << endl;
 
	s1 += "xxx";
	cout << s1 << endl;
 
	s1 += 'A';
	cout << s1 << endl;
}

结果如下:
《string类的使用介绍》

④c_str
const char* c_str() const;
void test14()
{
	string s("hello");
	//以语言的格式打印字符串
	cout << s.c_str() << endl;
}

结果如下:
《string类的使用介绍》

⑤find函数

注意:static const size_t npos = -1;//其实npos就是size_t的最大值

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;
void test15()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");
	
	size_t pos1 = s1.find("com");//正向查找com字符串
	cout << pos1 << endl;
 
	string s2("http");
	size_t pos2 = s1.find(s2);//正向查找与s2对象匹配的字符串
	cout << pos2<< endl;
 
	size_t pos3 = s1.find('p');//正向查找字符p
	cout << pos3 << endl;
}

结果展示:
《string类的使用介绍》

⑥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;
void test16()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");
 
	size_t pos1 = s1.rfind("string");//反向查找是s1中第一次出现的string的首位置
	cout << pos1 << endl;
 
	string s2("cplusplus");
	size_t pos2 = s1.rfind(s2);//反向查找s1中与s2对象匹配的首位置
	cout << pos2 << endl;
 
	size_t pos3 = s1.rfind('h'); //反向查找s1中h字符
	cout << pos3 << endl;
}

结果展示:

《string类的使用介绍》

⑦substr
string substr (size_t pos = 0, size_t len = npos) const;
void test17()
{
	//获取file的后缀
	string file("string.cpp");
	size_t pos = file.rfind('.');//反向查找 . 点
	string suffix(file.substr(pos,file.size()-pos));//从点开始,包括点的后面部分
	cout << suffix << endl;
}

结果:
《string类的使用介绍》

string& replace (size_t pos,  size_t len,  const string& str);
string& replace (size_t pos,  size_t len,  const string& str);
string& replace (size_t pos,  size_t len,  size_t n, char c);
⑧利用find取出网站的域名以及删除前缀
void test()
{
	// 取出url中的域名
	string url("http://www.cplusplus.com/reference/string/string/find/");
	cout << url << endl;
	size_t start = url.find("://");
	if (start == string::npos)
	{
		cout << "invalid url" << endl;
		return;
	}
	start += 3;
	size_t finish = url.find('/', start);
	string address = url.substr(start, finish - start);
	cout << address << endl;

	// 删除url的协议前缀
	size_t pos = url.find("://");
	url.erase(0, pos + 3);
	cout << url << endl;
}

结果如下:
《string类的使用介绍》

⑨利用replace和find替换字符

面试题:将这个字符串的空格替换为%%20.
`“hello world I love ereryday!”

方法1:找到空格后替换

int main()
{
	string s1 = "hello world I love you!";
	//我们提前算好我们的空格,然后提前开空间
	size_t num = 0;
	for (auto ch : s1)
	{
		if (ch == ' ')
		{
			++num;
		}
	}
	//提前开空间,避免replace时扩容
	s1.reserve(s1.size() + 3 * num);
	//第二个参数是缺省值=0,就是从开始的地方找
	size_t pos = s1.find(' ');
	while (string::npos != pos)
	{
		s1.replace(pos, 1, "%%20");
		//在pos之后第四个位置开始找
		pos = s1.find(' ',pos+4);
	}
	cout << s1 << endl;
}

方法2:空间换时间,创建新的string对象,遍历原字符串,不是空格就尾插字符,是空格就尾插%%20

//第二种方法以空间换时间
int main()
{
	string s1 = "hello world I love you!";
	//我们提前算好我们的空格,然后提前开空间
	string tmp;
	for (auto ch : s1)
	{
		if (ch != ' ')
		{
			tmp += ch;
		}
		if (ch == ' ')
		{
			tmp += "%% 20";
		}
	}
	s1 = tmp;
	cout << s1 << endl;
}

⑩swap

在我们的string中我们也有一个交换函数。库里面也有一个swap。
我们使用string中swap效率更高。

因为在我们的string中可以直接交换指针,指向不同的字符串。
而库中的swap,我们还要用一个临时变量去交换。

《string类的使用介绍》
《string类的使用介绍》

int main()
{
	string s1("abcd");
	string s2("xxxx");
	
	//用string中的交换
	s1.swap(s2);
	cout << s1 << endl << s2 << endl;

	//用库中的交换
	swap(s1, s2);
	cout << s1 << endl << s2 << endl;
}

5、string类非成员函数

函数 功能
operator+ 尽量少用,因为是传值返回,导致拷贝效率低
operator>> 流插入运算符重载
operator<< 流提取运算符重载
getline 获取一行字符串
relational operators 大小比较
getline的使用

输入输出问题:

void test18()
{
	string s;
	cin >> s;//输入hello world
	cout << s << endl;//只会打印hello
}

我们知道cin标准输入,当从键盘上面读取到空格或者\n时,会停止读取,这时候就要用到getline函数了

istream& getline (istream& is, string& str, char delim);
//从is中读取字符串,储存在str对象中,直到遇到delim界限符或者\n停止(自己指定)
 
istream& getline (istream& is, string& str);
//从is中读取字符串,储存在str对象中,直到遇到\n停止

演示遇到指定字符就停止读取

void test18()
{
	string s1;
	getline(cin,s1,'e');//输入hello world,
	cout << s1 << endl;//输出h
}

演示遇到\n停止

void test18
{
	string s2;
	getline(cin, s2);//输入hello world
	cout << s2 << endl;//输出hello world
}

总结:
以后使用getline

string s1; 
getline(cin,s1);

大小比较问题:
我们的string的大小比较就和stercmp一样,是比较字符的ASCII的大小

void test19()
{
	string s1("hello");
	string s2("string");
	cout << (s1 > s2) << endl;//输出0
}

这里的有点不一样,比较的是第一个字符的ASCII码值的大小,若第一个相等则比较第二个,返回一个bool值,以此类推。

6、其他函数

做OJ题的时候比较常用文章来源地址https://www.toymoban.com/news/detail-438217.html

① stoi——字符串转为整型
void test20()
{
	int val = stoi("12345");
	cout << val << endl;
}
② to_string——其他类型转为字符串
void test21()
{
	string str = to_string(3.14);
	cout << str << endl;
}

到了这里,关于《string类的使用介绍》的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】string类的深入介绍

    作者:爱写代码的刚子 时间:2023.5.26 本篇博客主要深入介绍string类、string类的常用接口及操作,string中迭代器的使用,以及string中的部分方法。(由于篇幅有限,剩余方法以及string的深浅拷贝将在之后的博客介绍) 前言:C语言中,字符串是以’\\0’结尾的一些字符的集合,

    2024年02月08日
    浏览(28)
  • 【C++】——string类的介绍及模拟实现

    C语言中,字符串是以’\\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。所以我们今天来学习C++标准库中的string类。

    2024年02月07日
    浏览(46)
  • [C++] string类的介绍与构造的模拟实现,进来看吧,里面有空调

    C语言中,字符串是以’\\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合面向对象的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 因此C++中,为了让我们更简单、方便

    2024年02月12日
    浏览(30)
  • 【c++】string类的使用

    目录 一、标准库中的string类 1、简单介绍string类 2、string类的常用接口注意事项 2.1、string类对象的常用构造 2.2、string类对象的容量操作 2.3、string类对象的访问及遍历操作 2.4、string类对象的修改操作 二、string类的模拟实现         (1)string是表示字符串的字符串类;    

    2024年02月01日
    浏览(62)
  • C++ String类的基本使用

            放弃时间的人,时间也会放弃他。——莎士比亚 ; 本篇章是关于string类内一些函数的介绍以及使用方法,都是我们编程必须掌握的基础! ​ 全文共7000字左右. 话不多说安全带系好,发车啦 (建议电脑观看) 。 附:红色,部分为重点部分;蓝颜色为需要记忆的

    2024年02月09日
    浏览(30)
  • 【c++】string类的使用及模拟实现

    我们先了解一下什么是OOP思想 OOP思想,即面向对象编程(Object-Oriented Programming)的核心思想,主要包括“抽象”、“封装”、“继承”和“多态”四个方面。 抽象:抽象是忽略一个主题中与当前目标无关的那些方面,以便充分地注意与当前目标有关的方面。抽象并不打算了

    2024年04月11日
    浏览(27)
  • 【C++】STL容器——string类的使用指南(含代码演示)(8)

    前言 大家好吖,欢迎来到 YY 滴C++系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《初学者易

    2024年02月08日
    浏览(32)
  • 模板类的成员模板使用常见问题

    模板类中的模板类结束分号得带上 ; 这个报错的原因是函数定义我是用快捷键生成的,导致: 应该是下面的模板书写方式,我全部改过来: 测试函数:

    2024年02月15日
    浏览(31)
  • string类的模拟实现

    上一篇博客我们对string类函数进行了讲解,今天我们就对string类进行模拟实现,以便于大家更加深入地了解string类函数的应用 由于C++的库里面本身就有一个string类,所以我们为了不让编译器混淆视听,我们可以首先将我们自己模拟实现的string类放入一个我们自己定义的命名空

    2024年01月21日
    浏览(25)
  • String 类的运用

    目录 1.字符串构造  2.String对象的比较 2.1==比较是否引用同一个对象 2. 2boolean equals(Object anObject) 2.3int compareTo(String s) 方法: 按照字典序进行比较 2.4int compareToIgnoreCase(String str)  3.字符串查找  4.2大小写转换 4.3字符串转数组  4.4 格式化 5.字符串替换 5.1把字符串中的某个字符替

    2024年02月13日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包