😁博客主页😁:🚀https://blog.youkuaiyun.com/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
⏰发布时间⏰: 2024-09-24 09:10:24
本文未经允许,不得转发!!!
🎄一、概述
std::string 是C++语言中用来表示字符序列的对象。
标准库的 string 类通过类似于标准字节容器的接口提供了对此类对象的支持,但添加了专门设计用于操作单字节字符串的特性。
string类是basic_string类模板的实例化,该模板使用char(即字节)作为其字符类型,具有默认的char_traits和allocator类型(有关模板的更多信息,请参阅basic_string)。
请注意,该类处理字节独立于所使用的编码:如果用于处理多字节或变长字符序列(如UTF-8),则该类的所有成员(如length或size)及其迭代器仍将以字节(而不是实际编码的字符)进行操作。
本文从增删改查四个方面介绍 std::string。
注意:C++中使用std::string时需要包含头文件#include <string>
。
🎄二、增加、组合、拼接 字符串
✨2.1 构造字符串
std::string
的构造函数有下面几个:
string();
string (const string& str);
string (const string& str, size_t pos, size_t len = npos);
string (const char* s);
string (const char* s, size_t n);
string (size_t n, char c);
template <class InputIterator> string (InputIterator first, InputIterator last);
string (initializer_list<char> il);
string (string&& str) noexcept;
🌰直接看例子
std::string s0 ("Initial string");
// constructors used in the same order as described above:
std::string s1;
std::string s2 (s0);
std::string s3 (s0, 8, 3);
std::string s4 ("A character sequence");
std::string s5 ("Another character sequence", 12);
std::string s6a (10, 'x');
std::string s6b (10, 42); // 42 is the ASCII code for '*'
std::string s7 (s0.begin(), s0.begin()+7);
std::cout << "s1: " << s1 << "\ns2: " << s2 << "\ns3: " << s3;
std::cout << "\ns4: " << s4 << "\ns5: " << s5 << "\ns6a: " << s6a;
std::cout << "\ns6b: " << s6b << "\ns7: " << s7 << '\n';
🎯运行结果:
✨2.2 给 std::string 对象 赋值
如果实例化一个 std::string 对象后,可以使用 =
运算符给该对象赋值,函数原型如下:
string& operator= (const string& str);
string& operator= (const char* s);
string& operator= (char c);
string& operator= (initializer_list<char> il);
string& operator= (string&& str) noexcept;
🌰举例子:
std::string str1, str2, str3;
str1 = "Test string: "; // c-string
str2 = 'x'; // single character
str3 = str1 + str2; // string
std::cout << str3 << '\n';
🎯运行结果:
✨2.3 添加字符串到 std::string 对象尾部
添加字符串到 QString 对象尾部的相关函数原型如下:
// 添加到字符串尾部
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);
template <class InputIterator> string& append (InputIterator first, InputIterator last);
string& append (initializer_list<char> il);
// 将给定的其他字符附加到该字符串的末尾。
void push_back (char c);
// += 运算符(公开成员函数)
string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);
string& operator+= (initializer_list<char> il);
// + 运算符(友元函数,非成员函数)
string operator+ (const string& lhs, const string& rhs);
string operator+ (const string& lhs, string&& rhs);
string operator+ (const string& lhs, const char* rhs);
string operator+ (const string& lhs, char rhs);
string operator+ (string&& lhs, char rhs);
string operator+ (string&& lhs, string&& rhs);
string operator+ (string&& lhs, const string& rhs);
string operator+ (string&& lhs, const char* rhs);
string operator+ (const char* lhs, const string& rhs);
string operator+ (const char* lhs, string&& rhs);
string operator+ (char lhs, const string& rhs);
string operator+ (char lhs, string&& rhs);
上面这几种最常用的是+
运算符,使用比较方便,而且可以连续加,如:a+b+c。
🌰举例子:
// append
std::string str;
std::string str4="Writing ";
std::string str5="print 10 and then 5 more";
// used in the same order as described above:
str.append(str4); // "Writing "
str.append(str5,6,3); // "10 "
str.append("dots are cool",5); // "dots "
str.append("here: "); // "here: "
str.append(10u,'.'); // ".........."
str.append(str5.begin()+8,str5.end()); // " and then 5 more"
str.append<int>(5,0x2E); // "....."
std::cout << str << '\n';
// +=
std::string name ("John");
std::string family ("Smith");
name += " K. "; // c-string
name += family; // string
name += '\n'; // character
std::cout << name;
// +
std::string firstlevel ("com");
std::string secondlevel ("cplusplus");
std::string scheme ("http://");
std::string hostname;
std::string url;
hostname = "www." + secondlevel + '.' + firstlevel;
url = scheme + hostname;
std::cout << url << '\n';
🎯运行结果:
✨2.4 添加字符串到 std::string 对象开头
添加字符串到 std::string 对象开头也是使用 + 运算符;
// 将字符串str添加到该字符串的开头,并返回对该字符串的引用。
// + 运算符(友元函数)
string operator+ (const char* lhs, const string& rhs);
string operator+ (const char* lhs, string&& rhs);
string operator+ (char lhs, const string& rhs);
string operator+ (char lhs, string&& rhs);
✨2.5 添加字符串到 std::string 对象指定位置
// 插入到指定位置
string& insert (size_t pos, const string& str);
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
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);iterator insert (const_iterator p, size_t n, char c);
iterator insert (const_iterator p, char c);
template <class InputIterator>iterator insert (iterator p, InputIterator first, InputIterator last);
string& insert (const_iterator p, initializer_list<char> il);
🌰举例子:
std::string str_insert="to be question";
std::string str6="the ";
std::string str7="or not to be";
std::string::iterator it;
// used in the same order as described above:
str_insert.insert(6,str6); // to be (the )question
str_insert.insert(6,str7,3,4); // to be (not )the question
str_insert.insert(10,"that is cool",8); // to be not (that is )the question
str_insert.insert(10,"to be "); // to be not (to be )that is the question
str_insert.insert(15,1,':'); // to be not to be(:) that is the question
it = str_insert.insert(str_insert.begin()+5,','); // to be(,) not to be: that is the question
str_insert.insert (str_insert.end(),3,'.'); // to be, not to be: that is the question(...)
str_insert.insert (it+2,str7.begin(),str7.begin()+3); // (or )
std::cout << str_insert << '\n';
🎯运行结果:
✨2.6 其他添加、拼接字符串的方式
添加字符串有好几种方式,最常用的是直接使用+
运算符,下面给出其他添加字符串的函数原型:
string& assign (const string& str);
string& assign (const string& str, size_t subpos, size_t sublen);
string& assign (const char* s);
string& assign (const char* s, size_t n);
string& assign (size_t n, char c);
template <class InputIterator> string& assign (InputIterator first, InputIterator last);
string& assign (initializer_list<char> il);
string& assign (string&& str) noexcept;
🌰举例子:
// assign
std::string str_assign;
std::string base="The quick brown fox jumps over a lazy dog.";
// used in the same order as described above:
str_assign.assign(base);
std::cout << str_assign << '\n';
str_assign.assign(base,10,9);
std::cout << str_assign << '\n'; // "brown fox"
str_assign.assign("pangrams are cool",7);
std::cout << str_assign << '\n'; // "pangram"
str_assign.assign("c-string");
std::cout << str_assign << '\n'; // "c-string"
str_assign.assign(10,'*');
std::cout << str_assign << '\n'; // "**********"
str_assign.assign<int>(10,0x2D);
std::cout << str_assign << '\n'; // "----------"
str_assign.assign(base.begin()+16,base.end()-12);
std::cout << str_assign << '\n'; // "fox jumps over"
🎯运行结果:
🎄三、std::string对象的 清空、 删除
本小节介绍从 对象删除一段字符串、清空整个std::string对象等操作。
✨3.1 清空字符串
清除字符串的内容并设置为 null,执行这个函数后,调用empty()
会返回true
void clear() noexcept;
🌰举例子:
// clear
std::string strClear("strClear");
strClear.clear();
std::cout << strClear << '\n'; // ""
std::cout << strClear.empty() << '\n'; // 1
✨3.2 从字符串末尾删除字符
void pop_back(); // 从字符串末尾删除1个字符。 c++11开始才有这个函数
🌰举例子:
// pop_back
std::string str_hello ("hello world!");
str_hello.pop_back();
std::cout << str_hello << '\n';
🎯运行结果:
✨3.3 删除指定字符串、指定位置的子字符串
相关函数原型如下:
string& erase (size_t pos = 0, size_t len = npos);
iterator erase (const_iterator p);
iterator erase (const_iterator first, const_iterator last);
🌰举例子:
std::string str_erase ("This is an example sentence.");
std::cout << str_erase << '\n'; // "This is an example sentence."
str_erase.erase (10,8); // ^^^^^^^^
std::cout << str_erase << '\n'; // "This is an sentence."
str_erase.erase (str_erase.begin()+9); // ^
std::cout << str_erase << '\n'; // "This is a sentence."
str_erase.erase (str_erase.begin()+5, str_erase.end()-9); // ^^^^^
std::cout << str_erase << '\n'; // "This sentence."
🎯运行结果:
✨3.4 删除空白字符
在QT的QString类中有两个删除空白字符的函数:
- simplified:删除字符串首尾的空白字符,并且将字符串内部的空白字符替换为空格;
- trimmed:只删除字符串首尾的空白字符,其他不变。
但是 std::string 中并没有此类函数,如果需要的话,只能自己实现,下面是删除字符串的空白字符例子:
🌰举例子:
// 删除空白字符
std::string str_blank = "\n\r\t abc \n\t\r cba \r\t\n";
std::cout << str_blank << std::endl;
str_blank.erase(std::remove_if(str_blank.begin(), str_blank.end(), isspace), str_blank.end());
std::cout << str_blank << std::endl;
🎯运行结果:
🎄四、修改 字符串
✨4.1 修改字符串大小
将字符串的大小设置为size字符。
如果size大于当前大小,则扩展字符串以使其长度为字符长,并将额外的字符添加到末尾。新字符未初始化。
如果size小于当前大小,则从末尾删除字符。
void resize(int size)
void resize(int size, QChar fillChar)
void resize (size_t n);
void resize (size_t n, char c);
// 要求将字符串容量调整为适应计划中的大小变化,使其长度达到最大 n 个字符。
void reserve (size_t n = 0);
🌰举例子:
// resize
std::string strResize("strResize");
strResize.resize(6);
std::cout << strResize << '\n'; // "strRes"
strResize.resize(16, '*');
std::cout << strResize << '\n'; // "strRes**********"
✨4.2 替换掉字符串的字符
将从索引位置开始的n个字符替换为后面的字符串,并返回对该字符串的引用。
注意:如果指定的位置索引在字符串范围内,但pos + n超出了字符串范围,则n将被调整为停止在字符串末尾。
string& replace (size_t pos, size_t len, const string& str);
string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);
string& replace (size_t pos, size_t len, const char* s);
string& replace (size_t pos, size_t len, const char* s, size_t n);
string& replace (size_t pos, size_t len, size_t n, char c);
string& replace (const_iterator i1, const_iterator i2, const string& str);
string& replace (const_iterator i1, const_iterator i2, const char* s);
string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n);
string& replace (const_iterator i1, const_iterator i2, size_t n, char c);
string& replace (const_iterator i1, const_iterator i2, initializer_list<char> il);
template <class InputIterator> string& replace (const_iterator i1, const_iterator i2, InputIterator first, InputIterator last);
🌰举例子:
// 替换掉字符串的字符
std::string strReplace("strReplace");
std::cout << strReplace.replace(0, 3, "STR") << '\n'; // "STRReplace"
std::cout << strReplace.replace(0, 3, 1, '*') << '\n'; // "*Replace"
std::cout << strReplace.replace(strReplace.begin()+1, strReplace.begin()+4, "rep") << '\n'; // "*replace"
✨4.3 交换字符串
// 将字符串other与此字符串交换。这个操作非常快,从不失败。
void swap (string& str);
🌰举例子:
// 交换字符串
std::string strSwap("strSwap");
std::string strSwapWhat("strSwapWhat");
strSwap.swap(strSwapWhat);
std::cout << strSwap << '\n'; // "strSwapWhat"
✨4.4 字符串格式转换
// 格式转换,使用时,需要加 std::,如:std::stoi、std::stol、
// 1.转换为数值
int stoi (const string& str, size_t* idx = 0, int base = 10);
int stoi (const wstring& str, size_t* idx = 0, int base = 10);
long stol (const string& str, size_t* idx = 0, int base = 10);
long stol (const wstring& str, size_t* idx = 0, int base = 10);
unsigned long stoul (const string& str, size_t* idx = 0, int base = 10);
unsigned long stoul (const wstring& str, size_t* idx = 0, int base = 10);
long long stoll (const string& str, size_t* idx = 0, int base = 10);
long long stoll (const wstring& str, size_t* idx = 0, int base = 10);
unsigned long long stoull (const string& str, size_t* idx = 0, int base = 10);
unsigned long long stoull (const wstring& str, size_t* idx = 0, int base = 10);
float stof (const string& str, size_t* idx = 0);
float stof (const wstring& str, size_t* idx = 0);
double stod (const string& str, size_t* idx = 0);
double stod (const wstring& str, size_t* idx = 0);
long double stold (const string& str, size_t* idx = 0);
long double stold (const wstring& str, size_t* idx = 0);
// 2.转换为 std::string
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
🎄五、从字符串 查询
✨5.1 查询字符串的字符个数
// 返回此字符串中的字符数。相当于size()。
size_t size() const noexcept;
size_t length() const noexcept;
// 返回当前为字符串分配的存储空间的大小,以字节表示。
size_t capacity() const noexcept;
// 返回字符串可以达到的最大长度。
size_t max_size() const noexcept;
🌰举例子:
std::string strQuerySize("strQuerySize");
std::cout << strQuerySize.length() << '\n'; // 12
std::cout << strQuerySize.size() << '\n'; // 12
std::cout << strQuerySize.capacity() << '\n';
std::cout << strQuerySize.max_size() << '\n';
🎯运行结果:
✨5.2 查询字符串的字符
// 获取字符串中给定位置的字符,position的范围:0 <= position < size()
char& at (size_t pos);
const char& at (size_t pos) const;
// [] 运算符,返回指定位置的字符
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
// 返回字符串的最后一个字符,等同于at(size()-1)
char& back();
const char& back() const;
// 返回字符串的第一个字符,等同于at(0)
char& front();
const char& front() const;
// 返回一个指向存储在std::string中的数据的指针。指针可用于访问和修改组成字符串的字符。
// 返回一个指向数组的指针,该数组包含一个以空结尾的字符序列(即C-string),表示字符串对象的当前值。
// string::data和string::c_str都是同义词,返回相同的值。
const char* data() const noexcept;
const char* c_str() const noexcept;
🌰举例子:
// 查询字符串的一个字符
std::string strQueryChar("strQueryChar");
std::cout << strQueryChar.at(1) << '\n'; // t
std::cout << strQueryChar[2] << '\n'; // r
std::cout << strQueryChar.back() << '\n'; // r
std::cout << strQueryChar.front() << '\n'; // s
const char *pCharArr = strQueryChar.data();
for(int i=0; i<strQueryChar.length(); i++)
{
std::cout << pCharArr[i] << '\n';
}
🎯运行结果:
✨5.3 查询字符串是否为空、是否为大小写
std::string 中没有检查是否为大小写的成员函数,如果需要的话,可以下面几个函数去实现,这些函数定义在标准库的头文件<cctype>
或<ctype.h>
中。
isalpha(c)
: 检查c是否是字母。isdigit(c)
: 检查c是否是数字。isspace(c)
: 检查c是否是空白字符(如空格、制表符等)。isupper(c)
: 检查c是否是大写字母。islower(c)
: 检查c是否是小写字母。toupper(c)
: 如果c是小写字母,则转换为对应的大写字母。tolower(c)
: 如果c是大写字母,则转换为对应的小写字母。
std::string 查询字符串是否为空:
bool isEmpty() const // 如果字符串没有字符则返回true;否则返回false。
✨5.4 查询是否包含指定的 子字符串、字符
- find:查询是否包含第一个参数指定的字符串或字符,成功则返回首次查询到的子串的索引,失败返回
std::string::npos
; - rfind:从末端开始查询是否包含第一个参数指定的字符串或字符,并返回首次查询到的子串的索引,失败返回
std::string::npos
; - find_first_of:在字符串中搜索与参数中指定的任何字符匹配的第一个字符。成功返回索引,失败返回
std::string::npos
; - find_last_of:在字符串中搜索与参数中指定的任何字符匹配的最后一个字符。成功返回索引,失败返回
std::string::npos
;
// 查询是否包含第一个参数指定的字符串或字符,并返回该子串的索引
size_t find (const string& str, size_t pos = 0) const noexcept;
size_t find (const char* s, size_t pos = 0) const;
size_t find (const char* s, size_t pos, size_type n) const;
size_t find (char c, size_t pos = 0) const noexcept;
// 从末端开始查询是否包含第一个参数指定的字符串或字符,并返回该子串的索引
size_t rfind (const string& str, size_t pos = npos) const noexcept;
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 noexcept;
// 在字符串中搜索与参数中指定的任何字符匹配的第一个字符。
size_t find_first_of (const string& str, size_t pos = 0) const noexcept;
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 noexcept;
// 在字符串中搜索与参数中指定的任何字符匹配的最后一个字符。
size_t find_last_of (const string& str, size_t pos = npos) const noexcept;
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 noexcept;
🌰举例子:
// find、rfind
std::string strFind("strFind");
std::cout << (std::string::npos != strFind.find("str")) << '\n';
std::cout << (std::string::npos != strFind.find('F')) << '\n';
std::cout << (std::string::npos != strFind.find("strs")) << '\n';
std::cout << (std::string::npos != strFind.rfind("str")) << '\n';
std::cout << (std::string::npos != strFind.rfind('F')) << '\n';
std::cout << (std::string::npos != strFind.rfind("strs")) << '\n';
// find_first_of
std::string str_find_first ("Please, replace the vowels in this sentence by asterisks.");
std::size_t found = str_find_first.find_first_of("aeiou"); // 查找 aeiou 中任一字符
while (found!=std::string::npos)
{
str_find_first[found]='*';
found=str_find_first.find_first_of("aeiou",found+1);
}
std::cout << str_find_first << '\n';//Pl**s*, r*pl*c* th* v*w*ls *n th*s s*nt*nc* by *st*r*sks.
// find_last_of
std::string str_find_last ("c:\\windows\\winhelp.exe");
std::cout << "Splitting: " << str_find_last << '\n';
std::size_t found_last = str_find_last.find_last_of("/\\");
std::cout << " path: " << str_find_last.substr(0,found_last) << '\n';
std::cout << " file: " << str_find_last.substr(found_last+1) << '\n';
🎯运行结果:
✨5.5 获取一个 子字符串
substr
返回一个新构造的字符串对象,其值初始化为此对象的子字符串的副本。
// 返回包含字符串最左边n个字符的子字符串。
string substr (size_t pos = 0, size_t len = npos) const;
✨5.6 比较字符串
int compare (const string& str) const noexcept;
int compare (size_t pos, size_t len, const string& str) const;
int compare (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const;
int compare (size_t pos, size_t len, const char* s, size_t n) const;
int compare (size_t pos, size_t len, const char* s) const;
int compare (const char* s) const;
//
bool operator== (const string& lhs, const string& rhs);
bool operator== (const char* lhs, const string& rhs);
bool operator== (const string& lhs, const char* rhs);
bool operator!= (const string& lhs, const string& rhs);
bool operator!= (const char* lhs, const string& rhs);
bool operator!= (const string& lhs, const char* rhs);
bool operator< (const string& lhs, const string& rhs);
bool operator< (const char* lhs, const string& rhs);
bool operator< (const string& lhs, const char* rhs);
bool operator<= (const string& lhs, const string& rhs);
bool operator<= (const char* lhs, const string& rhs);
bool operator<= (const string& lhs, const char* rhs);
bool operator> (const string& lhs, const string& rhs);
bool operator> (const char* lhs, const string& rhs);
bool operator> (const string& lhs, const char* rhs);
bool operator>= (const string& lhs, const string& rhs);
bool operator>= (const char* lhs, const string& rhs);
bool operator>= (const string& lhs, const char* rhs);
🎄六、其他
写太多了,几乎翻译了Qt文档里的内容,其他的以后用到再补充吧!!!
本文详细介绍了C++标准库的 std::string,以及代码例子。
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁
C++ 一行代码删除string字符串中的“\n“、“\r“、“\t“ 和 所有空白字符
std::string的工具函数 - 用isspace实现trim函数
https://cplusplus.com/reference/string/string/