C++string

string

1、C语言中的字符串

C语言中,字符串是以"\0"结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,容易越界访问

2、标准库中的string类

2.1、string类

string类的介绍

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

2.2、auto和for

auto关键字

  • 在早期 C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
  • 用auto声明指针类型时,用auto和auto*没有任何区别,但是auto声明引用类型时必须加&。
  • 当在同一行声明多个变量时,这些变量必须是相同类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
  • auto不能作为函数的参数,可以作为返回值,但是建议谨慎使用
  • auto不能直接用来声明数组
cpp 复制代码
#include<iostream>
using namespace std;
int func1()
{
    return 10;
}
// 不能做参数
//void func2(auto a)
//{
//}

// 可以做返回值,但是建议谨慎使用
auto func3()
{
    return 3;
}

int main()
{
    int a = 10;
    auto b = a;
    auto c = 'a';
    auto d = func1();
    // 编译报错:rror C3531: "e": 类型包含"auto"的符号必须具有初始值设定项
    //auto e;
    cout << typeid(b).name() << endl;
    cout << typeid(c).name() << endl;
    cout << typeid(d).name() << endl;
    int x = 10;
    auto y = &x;
    auto* z = &x;
    auto& m = x;
    cout << typeid(x).name() << endl;
    cout << typeid(y).name() << endl;
    cout << typeid(z).name() << endl;
    auto aa = 1, bb = 2;
    // 编译报错:error C3538: 在声明符列表中,"auto"必须始终推导为同一类型
    //auto cc = 3, dd = 4.0;
    //// 编译报错:error C3318: "auto []": 数组不能具有其中包含"auto"的元素类型
    //auto array[] = { 4, 5, 6 };
    return 0;
}
cpp 复制代码
#include<iostream>
#include <string>
#include <map>
using namespace std;
auto aa = 1, bb = 2;
// 编译报错:error C3538: 在声明符列表中,"auto"必须始终推导为同一类型
//auto cc = 3, dd = 4.0;
// 编译报错:error C3318: "auto []": 数组不能具有其中包含"auto"的元素类型
//auto array[] = { 4, 5, 6 };
int main()
{
	std::map<std::string, std::string> dict = { { "apple", "苹果" },{ "orange","橙子" }, {"pear","梨"} };
	// auto的用武之地
	//std::map<std::string, std::string>::iterator it = dict.begin();
	auto it = dict.begin();
	while (it != dict.end())
	{
		cout << it->first << ":" << it->second << endl;
		++it;
	}
	return 0;
}

范围for

  • 对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会犯错误,因此C++11中引入了基于范围的for循环。for循环后的括号由":"冒号分为两部分,第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束
  • 范围for可以作用到数组和容器对象上进行遍历
  • 范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到
cpp 复制代码
#include<iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
	int array[] = { 1, 2, 3, 4, 5 };
	// C++98的遍历
	for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
	{
		array[i] *= 2;
	}
	for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
	{
		cout << array[i] << endl;
	}
	// C++11的遍历
	for (auto& e : array)
		e *= 2;
	for (auto e : array)
		cout << e << " " << endl;
	string str("hello world");
	for (auto ch : str)
	{
		cout << ch << " ";
	}
	cout << endl;
	return 0;
}

2.3、string类的常用接口

2.3.1、string类对象的常见构造

string(); 构造一个空字符串,长度为零个字符
string(const char * s); 复制由 s 指向的空终止字符序列(C 字符串)
string (size_t n, char c); 用字符 c 的 n 个连续副本填充字符串
string(const string&str); 复制构造函数,构造str的副本

cpp 复制代码
#include<string>
#include<iostream>
using namespace std;
void Teststring()
{
	string s1;
	string s2("hello world");
	string s3(s2);
	cout << s1 << endl << s2 << endl << s3 << endl;
}

int main()
{
	Teststring();
	return 0;
}

2.3.2、string类对象的容量操作

size_t size() const; 返回字符串的长度,以字节为单位
size_t length() const; 返回字符串的长度,以字节为单位
size_t capacity() const; 返回已分配存储的大小
bool empty() const; 返回字符串是否为空(即长度是否为0)
void clear(); 清除字符串的内容, 使其变为一个空字符串(长度为0个字符)
void reserve (size_t n = 0); 请求将字符串容量调整为计划变更的大小,最多为n个字符的长度
void resize (size_t n);void resize (size_t n, char c); 将字符串调整为长度为n个字符

  • size ()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()
  • clear()只是将string中有效字符清空,不改变底层空间大小
  • resize(size_t n) 与resize(size_t n,char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(size_t n)用0来填充多出的元素空间,resize(size_t n,char c)用字符c来填充多出的元素空间。resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变
  • reserve(size_t res_arg=0):为string预留空间,不改有效元素个数,当reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小

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

char& operator[] (size_t pos);const char& operator[] (size_t pos) const; 返回字符串中位置为pos的字符的引用
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; 返回指向字符串理论元素之前(即其反向末尾)的反向迭代器
范围for C++11支持更简洁的范围for的新遍历方式

2.3.4、string类对象的修改操作

void push_back (char c); 将字符c追加到字符串末尾,使其长度增加一
append 在字符串后追加一个字符串
operator+= 在字符串后追加字符串str
const char * c_str() const; 返回c格式的字符串
find 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
string substr (size_t pos = 0, size_t len = npos) const; 在str中从pos位置开始,截取n个字符,然后将其返回

  • 在string尾部追加字符时,s.push_back( c ) / s.append(1,c) / s+='c'三种实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串
  • 对string操作时,如果能够大概预估到放多少字符,可以先通过reverse把空间预留好

2.3.5、string类非成员函数

operaotr+ 返回两个字符串的组合,因为是传值返回,导致深拷贝效率低
operator>> 输入运算符重载
operator<< 输出运算符重载
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
获取一行字符串
relational operators (string) 比较大小

相关推荐
StockTV几秒前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python
chaofan980几秒前
GPT-5.5 领衔 Image 2.0:像素级控制时代,AI 绘图告别开盲盒
开发语言·人工智能·python·gpt·自动化·api
七颗糖很甜11 分钟前
“十五五”气象发展规划:聚焦五大核心任务
大数据·python·算法
科研前沿18 分钟前
镜像视界浙江科技有限公司的关键技术突破有哪些?
大数据·人工智能·科技·算法·音视频·空间计算
爱码小白21 分钟前
Python 异常处理 完整学习笔记
开发语言·python
嫩萝卜头儿27 分钟前
2 - 复杂度收尾 + 链表经典OJ
数据结构·算法·链表·复杂度
c++之路36 分钟前
C++20概述
java·开发语言·c++20
星马梦缘40 分钟前
算法设计与分析 作业二 答案与解析
算法·图论·dfs·bfs·floyd-warshall·bellman_ford·多源最短路
玛丽莲茼蒿40 分钟前
Leetcode hot100 每日温度【中等】
算法·leetcode·职场和发展
cjp5601 小时前
009.UG二次开发,任务环境草图优化3(高级功能生成直线)
算法