深入理解C++中string类

背景介绍:在C++中使用string.h和cstring并不是所要介绍的string类指的是C语言库中字符串,而本文所要介绍的是string类。要使用string类主要是了解它的公共接口,也就是string类的众多方法。
下面介绍的是string类的构造函数,主要用于将字符串赋值给变量、合并字符串、比较字符串、若干重载操作符、在字符串中寻找子字符串。

一、构造字符串

string类的7个构造函数,如下表所示
构造函数 描述
string(const char* s) 将string对象初始化为s指向的NBTS
string(size_type n,char c) 创建一个包含n个元素的string对象,其中每个对象都被初始化为字符c
string(const string & str) 将一个string初始化为string对象str(赋值构造函数)
string() 创建一个默认的string对象,长度为0(默认构造函数)
string(const char* s,size_type n) 将string对象初始化为s指向的NBTS的前n个字符,即是超过了NBTS结尾
template<class Iter> string(Iter begin,Iter end) 将string对象初始化为区间[begin,end)内的字符,其中begin和end为迭代器用于指定位置,范围包括begin,但是不包括end
string(const string & str,string size_type pos=0,size_type n=npos) 将一个string对象初始化为对象str中从位置pos开始到结尾的字符,或从位置pos开始的n个字符
以下为C++11后添加的构造函数
string(string && str) noexcept 将string对象初始化为string对象str,并可能修改str(移动构造函数)
string(initializer_list <char > il) 他将string对象初始化为初始化列表il中的字符

注:NBTS是以空字符串结束的字符串,也就是传统的C字符串。
示例代码如下:

//str1.cpp -- introducing the string class
#include <iostream>
#include <string>
//using string constructorsint main()
{using namespace std;string one("Lottery Winner!");cout << one << endl;string two(20,'&');cout << two << endl;string three(one);cout << three << endl;one += "Oops!";cout << one << endl;two = "Sorry! That was";three[0] = 'P';string four;four = two + three;cout << four << endl;char alls[] = "All's well that ends well";string five(alls,20);cout << five << "!\n";string six(alls+6,alls+10);cout << six << ",";string seven(&five[6], &five[20]);cout << seven << "...\n";string eight(four,7,16);cout << eight << "in motion!" << endl;return 0;
}

结果如图:

说明:four = two + three; string类中重载了=和+操作符。

二、string类输入

对于C语言风格的字符串,有三种方式
char info[100];
cin >> info;cin.getline(info,100);cin.get(info,100);

string类有两种输入方式:

string stuff;
cin >> stuff;getline(cin,stuff);

string类的getline()可以自动调节大小。但是也会存在限制,比如:第一个限制因素是有string类中定义的string::npos决定的string对象最大长度,如果你用此方法来输入整个文件的内容可能会出错。第二个错误是你的计算机可以分配的最大内存大小。
往string对象中输入字符,可能会出现三种情况:
1、输入到文件尾了,输入流的寄存器eofbit将会被设置为true,这意味着string类中的fail()方法和eof()方法都将返回true;
2、如果遇到分界符\n,则会从输入流中删除分界符,不存储它;
3、读取的字符数达到最大允许值string::npos,或者是你计算机可分配内存中比较小的哪一个值,则会设置底层寄存器failbit,这意味中fail()方法将返回true。
实例代码如下:

//strfile.cpp -- read strings from a file
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>int main()
{using namespace std;ifstream fin;fin.open("tobuy.txt");if (fin.is_open() == false){cerr << "can't open file.Bye.\n";exit(EXIT_FAILURE);//程序因为异常而结束}string item;int count = 0;getline(fin,item,':');while (fin){++count;cout << count << ":" << item << endl;getline(fin,item,':');}cout << "Done\n";fin.close();return 0;
}

结果如图所示:

注:辅助记忆ASCII码,数字0(48)< 大写字符A(65) < 小写字符a(97)。

三、使用字符串

好了到这里,本文可以总结一下,string类可以使用第一个表格中的九种方式构造string对象、重载<<和[]符号来显示string对象、使用getline(cin,a);将数据读取和附加到string对象上、重载了=给string对象赋值、重载+将两个string对象连接起来。
对于比较两个string对象的大小,则是重载了6个关系运算符,比较的对视这些字符串在不同系统中的机器码的大小,不限定于ASCII码。在此不细说了。
上面提到的string::npos,指的是string对象可存储的最大字符数,通常指的是无符号的int或者无符号的long的最大值,32位机和64位机的npos值是不一样的。如需研究,可参考计算机组成原理。
下面重点介绍find()方法,用于查找字符串中给定的子字符串。
方法原型 描述
size_type(const string & str,size_type pos = 0)const 从字符串的pos位置开始,查找子字符串str。如果找到则返回该子字符串首次出现的位置的索引;否则返回string::npos
size_type find(const char * s,size_type pos=0)const 从字符串的pos位置开始,查找子字符串s。如果找到则返回该子字符串首次出现的位置的索引;否则返回string::npos
size_type find(const char * s,size_type pos=0,size_type n) 从字符串的pos位置开始,查找子字符串s的前n个字符。如果找到则返回该子字符串首次出现的位置的索引;否则返回string::npos
size_type find(const char ch,size_type pos=0) 从字符串的pos位置开始,查找子字符ch。如果找到则返回该子字符串首次出现的位置的索引;否则返回string::npos

其中string类还提供了好多的其他变形方法,rfind()方法查找字符串最后一次出现的位置;find_first_of()方法在字符串中任一字符首先出现的位置。find_last_of()方法是在字符串中查找子字符串中每一个字符最后出现的位置。
应用代码如下:

//hangman.cpp -- some string methods
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cctype>
using std::string;
const int NUM = 26;
const string wordlist[NUM] = { "apiary","beetle","cereal","danger",
"ensign","florid","garage","health","insult","jackal",
"keeper","loaner","manage","nonce","onset","plaid","quilt","remote",
"stolid","train","useful","valid","whence","xenon","yearn","zippy" };int main()
{using std::cout;using std::cin;using std::tolower;using std::endl;std::srand(std::time(NULL));char play;cout << "Will you play a word game? <y/n>";cin >> play;play = tolower(play);//将大写的字母变成小写字母while (play == 'y'){string target = wordlist[std::rand()%NUM];int length = target.length();string attempt(length,'-');//复制length个-给attempt对象string badchars;int guesses = 6;cout << "Guess my secret word.It has " << length<< " letters,and you guess\n"<< "one letter at a time, you get " << guesses<< " wrong guesses.\n";cout << "Your word:" << attempt << endl;while (guesses>0&&attempt!=target){char letter;cout << "Guess a letter:";cin >> letter;if (badchars.find(letter) != string::npos || attempt.find(letter) != string::npos){cout << "You already guessed that. Try again.\n";continue;}int loc = target.find(letter);if (loc == string::npos){cout << "Oh,bad guess!\n";--guesses;badchars += letter;}else{cout << "Good guess!\n";attempt[loc] = letter;//check if letter appears againloc = target.find(letter,loc+1);while (loc!=string::npos){attempt[loc] = letter;loc = target.find(letter,loc+1);}}cout << "Your word:" << attempt << endl;if (attempt != target){if (badchars.length() > 0)cout << "Bad choices:" << badchars << endl;cout << guesses << "bad guesses left\n";}}if (guesses > 0)cout << "That's right!\n";elsecout << "Sorry, the word is" << target << ".\n";cout << "Will you play another? <y/n>";cin >> play;play = tolower(play);}cout << "Bye\n";return 0;
}

四、string还提供了哪些功能

1、删除字符串的部分或者全部内容;
2、用一个字符串的部分或者全部内容替换另一个字符串中的部分或者全部内容;
3、将数据插入到字符串中或删除字符串中数据;
4、将一个字符串中的部分或者全部内容与另一个字符串的全部或者部分的被内容进行比较;
5、从字符串中提取子字符串;
6、将一个字符串内容复制到另一个字符串中;
7、交换两个字符串的内容。
//str2.cpp -- capacity() and reserve()
#include <iostream>
#include <string>
int main()
{using namespace std;string empty;string small = "bit";string larger = "Elephants are a girl's best friend";cout << "Sizes:\n";cout << "\tempty:" << empty.size() << endl;cout << "\tsmall:" << small.size() << endl;cout << "\tlarger:" << larger.size() << endl;cout << "Capacities:\n";cout << "\tempty:" << empty.capacity() << endl;cout << "\tsmall:" << small.capacity() << endl;cout << "\tlarger:" << larger.capacity() << endl;empty.reserve();small.reserve();cout << "Capacity after empty.reserve(50):"<< empty.capacity()<<endl;cout << "Capacity after small.reserve(50):"<< small.capacity() << endl;return 0;
}

五、字符串的种类

string库实际上是基于一个模板类的:

template <class charT,class traits = char _traits<charT>,class Allocator = allocator<cahrT>>
basic_string {...};

模板basic_string有4个具体化,每一个躯体化都有一个typedef名称:

typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;

这样就可以使用基于类型wchar_t、char16_t、char32_t和char的字符串了。

深入理解C++中string类(详解)相关推荐

  1. Java的java.lang.String类详解

    String类详解 String(字符串常量)概述 在API中是这样描述: String 类代表字符串.Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现. ...

  2. 转载:c+string类详解

    C++ string 类详解 </h1><div class="clear"></div><div class="postBod ...

  3. php closure 类,PHP中Closure类详解

    本文主要和大家分享PHP中Closure类详解,PHP Closure 类是用于代表匿名函数的类,匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象,Closure类摘要如下:Closure ...

  4. c++之string类详解

    一.包含头文件 要想使用标准C++中string类,必须要包含 #include <string>// 注意是<string>,不是<string.h>,带.h的是 ...

  5. 对内置的String类详解.

    目录: 一.String字符串的储存原理 二.String类的构造方法 三.String类当中常用方法 四.[重点] StringBuffer 五.StringBuffer和StringBuilder ...

  6. 常用类详解(一)包装类和String类详解

    一.包装类 包装类的分类 (Wrapper) 针对八种基本数据类型相应的引用类型--包装类 有了类的特点,就可以调用类中的方法. 基本数据类型 包装类 boolean Boolean char Cha ...

  7. String 类详解

    public final class String 继承自java.lang.Object类. 实现了接口: java.io.Serializable, Comparable<String> ...

  8. 【JAVA基础篇】String类详解

    昨天参加了一场机试,发现自己居然对String类的api不熟了,所以今天来总结一下(基于JDK1.8). 1.父类和实现的接口 没有父类,或者说父类是Object 接口:Serializable.Co ...

  9. 【JavaSE】String类详解含面试经典

    目录 一.初识String类 二.String类的常用方法 2.1 字符串的构造 2.2 String对象的比较 2.2.1 ==比较是否引用同一个对象 2.2.2 boolean equals(Ob ...

最新文章

  1. 打造线下版元宇宙!机器人VR助力远程做核酸,登上Science子刊
  2. c语言对10求余不为7,【PTA | 基础编程题目集】7-12 两个数的简单计算器 (10分)
  3. POJ 2388 Who's in the Middle
  4. 成功解决TypeError: ‘str‘ object is not callable
  5. 4.2.1 路由算法与路由协议概述(静态路由和动态路由---距离-向量路由算法---链路状态路由算法、层次路由)
  6. 已知ABAP tcode,需要查找assign了该tcode的PFCG role
  7. python3 Connection aborted.', RemoteDisconnected('Remote end closed connection without response'
  8. (7)Node.js 全局函数
  9. 【一天一个C++小知识】008.内联函数
  10. 顺通鞋业鞋厂仓库库存管理系统软件
  11. cefsharp设置cookie_CefSharp 设置cookie
  12. 如何获得自己的外网IP?
  13. 学习java数组的练习代码
  14. 安卓手机突然很卡_安卓手机为什么很卡 安卓手机卡顿原因分析【详解】
  15. u盘里的文件不见了怎么恢复正常?
  16. 关于DVDScr, Screener,TS, TC等常见术语
  17. 史上最全的团队文档协作及管理工具盘点,看看哪款适合你
  18. 2015年中国云计算市场回顾与展望
  19. 制作动态网站比较好用的软件工具
  20. 小行助学答题系统编程等级考试scratch三级真题2023年3月(含题库答题软件账号)

热门文章

  1. 微信小程序登录流程,双登录,手机号登录和账户密码登录
  2. 前端请求 报错413的问题
  3. python垃圾回收机制原理_详解python的垃圾回收机制
  4. 初识设计模式(策略模式)
  5. 【Cprimerplus_03】算术运算符、关系运算符、逻辑运算符
  6. SQL 优化极简法则,还有谁不会?
  7. 摄影入门-之四-镜头篇
  8. 计算机找不到mfc110.dll解决方案
  9. cookie以及Storage的共同点、区别与使用
  10. Web服务器HTTP头信息公开 漏洞