标准c++中string类介绍 (更加详细)

2024-09-01 16:38

本文主要是介绍标准c++中string类介绍 (更加详细),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这几天看了Bruce所著《Thinking in C++》一书中有关string类的介绍,结合之前收集到的一些相关资料,这里做个系统的总结,希望能和大家在C++的大路上共同前行。
C语言中,字符串基本就是字符型数组,并且总是以二进制零(即空结束付)作为其最末元素。C++ string类与它们在C语言中的前身截然不同,C++ string类具有很多优点:

1>.
 隐藏了字符串序列内部字符序列的物理表示:也就是说程序设计人员不必关心数组维数及空结束符问题,例如当程序访问越界时,字符串内部会做自动抛出异常等处理,而不用程序去检测是否遇到空结束符,这很大程度上隐藏了一些复杂的实现,更方便程序员使用。
2>.
 无需程序员干预,string类可以根据需要自动扩充规模:在C中,当对字符串操作时,通常需要程序员跟踪字符串的存储边界,当对一个对象扩充时,需要程序员手动扩充存储,同时,这些令人生厌的内务处理琐事不仅不方便,而且不安全,C++中的string类则解决了这些问题,使用C++时会最真切的感 受到这些。
3>.
 提高了便利性和安全性:在C语言中,为了实现对字符串方便的操作,提供了一系列库函数,然而但这些库函数名列表不仅冗长,而且充满了模糊不清、晦涩难懂的名字;C++通过理性化的命名机制、函数重载及默认参数解决了这些问题。

下面将从以下四方面做更详细的介绍:

1. 创建并初始化字符串

2. 字符串操作

字符串比较

4 其他常用函数介绍


1. 创建并初始化字符串


创建并初始化字符串至少有如下9种方法:

======================================================================================

string s; 生成一个空字符串s,并不立即初始化它


string s(“string”); 创建字符串并用引用字符数组进行初始化


string s = str; 采用重载运算符方法,用已有字符串初始化新字符串


string s(str,stridx,strlen); 将字符串str内始于stridx且长度顶多strlen的部分作为字符串的初值,其中strstridxstrlen的默认值分别为””0、极大整型值


string s(chars,chars_len); C字符串前chars_len个字符作为字符串s的初值,chars_len的默认值为极大整型值


string s(num,c); 生成一个字符串,包含numc字符


string s(s1.begin(),s1.end()); 采用迭代器方法,选取字符串区间beg-end(不包含end)内的字符作为字符串s的初值


string s = “a”+”b”; 使用operator+链接已有字符串后初始化新字符串

string s = str.substr(stridx,strlen);

使string对象的用成员函数substr()来初始化字符串,其中stridxstrlen的默认值分别为0、极大整型值

======================================================================================

实例1创建并初始化字符串

======================================================================================

#include <string>

#include <iostream>

using namespace std;

int main() {

string s1("What is the sound of one clam napping?");

string s2("Anything worth doing is worth overdoing.");

string s3("I saw Elvis in a UFO");

// Copy the first 8 chars:

string s4(s1, 0, 8);

string str("a new string", 5);

cout << s4 << endl;

// Copy 6 chars from the middle of the source:

string s5(s2, 15, 6);

cout << s5 << endl;

// Copy from middle to end:

string s6(s3, 6, 15);

cout << s6 << endl;

// Copy many different things:

string quoteMe = s4 + "that" +

// substr() copies 10 chars at element 20

s1.substr(20, 10) + s5 +

// substr() copies up to either 100 char

// or eos starting at element 5

"with" + s3.substr(5, 100) +

// OK to copy a single char this way

s1.substr(37, 1);

cout << quoteMe << endl;

///:~

======================================================================================

2. 字符串操作

2.1 插入、追加和连接操作(增操作)

======================================================================================

s.insert(stridx, str ); 在指定下标stridx对应的字符前插入字符串str,即执行插入操作

s.append(str); 在指定字符串s后追加给定字符串str,如果存储规模不足,会自动扩展,即执行追加操作

a = a + str; 连接操作由重载运算符实现

===============================================================================

实例2插入、追加和连接操作

======================================================================================

#include <string>

#include <iostream>

using namespace std;

int main() {

string bigNews("I saw Elvis in a UFO. ");

cout << bigNews << endl;

// How much data have we actually got?

cout << "Size = " << bigNews.size() << endl;

// How much can we store without reallocating?

cout << "Capacity = " << bigNews.capacity() << endl;

// Insert this string in bigNews immediately

// before bigNews[1]:

bigNews.insert(1, " thought I");

cout << bigNews << endl;

cout << "Size = " << bigNews.size() << endl;

cout << "Capacity = " << bigNews.capacity() << endl;

// Make sure that there will be this much space

bigNews.reserve(500);

// Add this to the end of the string:

bigNews.append("I've been working too hard.");

cout << bigNews << endl;

cout << "Size = " << bigNews.size() << endl;

cout << "Capacity = " << bigNews.capacity() << endl;

///:~

===============================================================================

2.2 从字符串中删除字符(删操作)

===============================================================================

s.erase(stridx, strlen); 删除字符串中的字符,stridx指定删除起始位置,默认值为0strlen表示删除字符序列个数,默认值为极大整型值

======================================================================================

2.3 替换字符串中的字符(改操作)

======================================================================================

s.replace(stridx, strlen, str); 对指定下标开始到指定长度strlen区间的字符序列用字符串str替换

======================================================================================

2.4 字符串的查找(查操作)

======================================================================================

s.find(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找单个字符或字符串: 如果找到,返回首次匹配的开始位置;否则返回string::npos

s. find_first_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找第一个与指定字符数组str中任何字符匹配的字符位置: 如果找到,返回第一次匹配的开始位置;否则返回string::npos

s. find_last_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找最后一个与指定字符数组str中任何字符匹配的字符位置: 如果找到,返回最后一次匹配的开始位置;否则返回string::npos。功能和find类似

s. find_first_not_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找第一个不与指定字符数组str中任何字符匹配的字符位置: 如果找到,返回第一次匹配的开始位置;否则返回string::npos

s. find_last_not_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找最后一个不与指定字符数组str中任何字符匹配的字符位置: 如果找到,返回最后一次匹配的开始位置;否则返回string::npos。功能和find类似

s.rfind(char|str, stridx); 在指定单词中,从指定下标stridx开始,反向查找单个字符或字符串: 如果找到,返回首次匹配的开始位置;否则返回string::npos

======================================================================================

实例3:字符串的查找(查操作)

======================================================================================

#ifndef SIEVE_H

#define SIEVE_H

#include <cmath>

#include <cstddef>

#include <string>

#include "../TestSuite/Test.h"

using std::size_t;

using std::sqrt;

using std::string;

class SieveTest : public TestSuite::Test {

string sieveChars;

public:

// Create a 50 char string and set each

// element to 'P' for Prime:

SieveTest() : sieveChars(50, 'P') {}

void run() {

findPrimes();

testPrimes();

}

bool isPrime(int p) {

if(p == 0 || p == 1) return false;

int root = int(sqrt(double(p)));

for(int i = 2; i <= root; ++i)

if(p % i == 0) return false;

return true;

}

void findPrimes() {

// By definition neither 0 nor 1 is prime.

// Change these elements to "N" for Not Prime:

sieveChars.replace(0, 2, "NN");

// Walk through the array:

size_t sieveSize = sieveChars.size();

int root = int(sqrt(double(sieveSize)));

for(int i = 2; i <= root; ++i)

// Find all the multiples:

for(size_t factor = 2; factor * i < sieveSize;

++factor)

sieveChars[factor * i] = 'N';

}

void testPrimes() {

size_t i = sieveChars.find('P');

while(i != string::npos) {

test_(isPrime(i++));

i = sieveChars.find('P', i);

}

i = sieveChars.find_first_not_of('P');

while(i != string::npos) {

test_(!isPrime(i++));

i = sieveChars.find_first_not_of('P', i);

}

}

};

#endif // SIEVE_H ///:~

#include "Sieve.h"

int main() {

SieveTest t;

t.run();

return t.report();

///:~

======================================================================================

3 字符串比较

字符串的比较其实是进行字典比较;字典比较的意思是,当测试一个字符看它是否大于另一个字符时,时机比较的是它们的数值表示,而这些数值表示是由当前所使用的字符集的校对序列决定的,通常这种校对序列是ASCII校对序列;当字典比较报告字符串S1大于S2时,也即两者相比较时,字符串S1中第一个不同的字符比字符串S2中同样位置的字符在ASCII表中的位置更靠后。

方法一 运算符重载

C++ string类提供了运算符重载的方法,用于比较字符串;这种方法直观而且使用方便。

实例4 运算符重载

======================================================================================

#ifndef COMPSTR_H

#define COMPSTR_H

#include <string>

#include "../TestSuite/Test.h"

using std::string;

class CompStrTest : public TestSuite::Test {

public:

void run() {

// Strings to compare

string s1("This");

string s2("That");

test_(s1 == s1);

test_(s1 != s2);

test_(s1 > s2);

test_(s1 >= s2);

test_(s1 >= s1);

test_(s2 < s1);

test_(s2 <= s1);

test_(s1 <= s1);

}

};

#endif

#include "CompStr.h"

int main() {

CompStrTest t;

t.run();

return t.report();

///:~

======================================================================================

方法二 compare函数

除运算符重载之外,可以利用compare函数进行更复杂精密的比较手段;它提供重载版本,可以比较:

  • 两个完整的字符串: str1.compare(str2);
  • 一个字符串的某一部分和另一个字符串的全部: str1.compare(stridx, strlen, str2);
  • 两个字符串的子串: str1.compare(stridx, strlen, str2, stridx, strlen);

其中,stridx是给定字符串进行比较部分的开始,stdlen是要比较的字符长度。

实例: compare函数

======================================================================================

#include <cassert>

#include <string>

using namespace std;

int main() {

string first("This is a day that will live in infamy");

string second("I don't believe that this is what "

"I signed up for");

// Compare "his is" in both strings:

assert(first.compare(1, 7, second, 22, 7) == 0);

// Compare "his is a" to "his is w":

assert(first.compare(1, 9, second, 22, 9) < 0);

///:~

======================================================================================

4 其他常用函数介绍

除了以上介绍到的对字符串的操作,下面对于一些经常用到的几个有意义的函数做如下解释及对比:

======================================================================================

s.size(); 返回当前在字符串中存储的字符数

s.length(); 作用等同于size()成员函数


s.capacity(); 返回为当前字符串分配的存储空间的规模,一般大于size()成员函数的返回值

s.reserve(strlen); 按照程序员的意图,预留指定长度的存储空间,此时capacity()成员函数的返回值与strlen接近:当strlen大于字符串长度时,扩充存储空间;否则不做任何处理

s.resize(strlen); 按照程序员的意图,重定义字符串: 如果strlen长度大于当前字符串长度,则在当前字符串后补空格;否则,则会截取当前字符串。resize对字符串本身操作,而reserve对存储空间操作

s.swap( str); 用于交换两个字符串的内容,参数必须为字符串型变量

s.clear(); 清空指定字符串,删除其中全部字符

s[stridx]; 用于元素存取,但是应该注意的是操作符[]并不检查索引是否有效(有效索引0~str.length()),如果索引失效,会引起未定义的行为

s.at(stridx); 用于元素存取,at()会做正确性检查,如果使用 at()的时候索引无效,会抛出out_of_range异常

s.empty(); 判断字符串是否为空:为空返回true,否则返回false

======================================================================================

这篇关于标准c++中string类介绍 (更加详细)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1127484

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)