string字符串使用
概述
定义于头文件<string>。
类模板:
template<
class CharT,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>
> class basic_string;
模板形参:
CharT - 字符类型;
Traits - 指定字符类型上操作的特性类
Allocator - 用于分配内部存储的分配器 (Allocator) 类型
创建string
构造函数
从各种数据源构造新 string ,可选地使用用户提供的分配器 alloc 。
用法:
// string::string()
std::string s;
// string::string(size_type count, charT ch)
std::string s(4, '='); // "===="
std::string const other("Exemplary");
// string::string(string const& other, size_type pos, size_type count)
std::string s(other, 0, other.length()-1); // Exemplar"
// string::string(charT const* s, size_type count)
std::string s("C-style string", 7); // "C-style"
// string::string(charT const* s)
std::string s("C-style\0string"); // "C-style"
char mutable_c_str[] = "another C-style string";
// string::string(InputIt first, InputIt last)
std::string s(std::begin(mutable_c_str)+8, std::end(mutable_c_str)-1); // "C-style string"
std::string const other("Exemplar");
std::string s(other); // "Exemplar"
// string::string(string&& str)
std::string s(std::string("C++ by ") + std::string("example")); // "C++ by example"
// string(std::initializer_list<charT> ilist)
std::string s({ 'C', '-', 's', 't', 'y', 'l', 'e' }); // "C-style"
{
// 重载决议选择 string(InputIt first, InputIt last) [with InputIt = int]
// 这表现为如同调用 string(size_type count, charT ch)
std::string s(3, std::toupper('a')); // "AAA"
operator=
替换字符串的内容。
定义:
// 1、以 str 的副本替换内容
basic_string& operator=( const basic_string& str );
// 2、用移动语义以 str 的内容替换内容。
basic_string& operator=( basic_string&& str );
// 3、以 s 所指向的空终止字符串的内容替换内容,如同用 assign(s, Traits::length(s))
basic_string& operator=( const CharT* s );
// 4、以字符 ch 的内容替换内容,如同用 assign(std::addressof(ch), 1)
basic_string& operator=( CharT ch );
// 5、以 initializer_list ilist 的内容替换内容,如同用 assign(ilist.begin(), ilist.size())
basic_string& operator=( std::initializer_list<CharT> ilist );
// 6、隐式转换 t 为 string_view sv
template<class T>
basic_string& operator=( const T& t );
用法:
std::string str1;
std::string str2 { "alpha" };
// (1) operator=( const basic_string& );
str1 = str2;
// (2) operator=( basic_string&& );
str1 = std::move(str2); // str1 : "alpha" str2 : "" 或 "alpha" (未指定)
// (3) operator=( const CharT* );
str1 = "beta";
// (4) operator=( CharT );
str1 = '!';
// (5) operator=( std::initializer_list<CharT> );
str1 = {'g','a','m','m','a'};
// (6) operator=( const T& );
str1 = 35U; // equivalent to str1 = static_cast<char>(35U);
std::cout << str1 << '\n'; // "#" (ASCII = 35)
assign
替换字符串的内容。
用法:
std::string s;
// assign(size_type count, CharT ch)
s.assign(4, '=');
std::string const c("Exemplary");
// assign(basic_string const& str)
s.assign(c);
// assign(basic_string const& str, size_type pos, size_type count)
s.assign(c, 0, c.length()-1); // "Exemplar"
// assign(basic_string&& str)
s.assign(std::string("C++ by ") + "example"); // "C++ by example"
// assign(charT const* s, size_type count)
s.assign("C-style string", 7); // "C-style"
// assign(charT const* s)
s.assign("C-style\0string"); // "C-style"
char mutable_c_str[] = "C-style string";
// assign(InputIt first, InputIt last)
s.assign(std::begin(mutable_c_str), std::end(mutable_c_str)-1); // "C-style string"
// assign(std::initializer_list<charT> ilist)
s.assign({ 'C', '-', 's', 't', 'y', 'l', 'e' }); // "C-style"
元素访问
at
访问指定字符,有边界检查
对于容器 c ,表达式 c.front() 等价于 *c.begin() 。
用法:
std::string s("message"); // 为容量
s = "abc";
s.at(2) = 'x'; // ok
std::cout << s.at(0) << '\n';
operator[]
访问指定字符,无边界检查
定义:
reference operator[]( size_type pos );
const_reference operator[]( size_type pos ) const;
用法:
std::string s("message"); // 为容量
s = "abc";
s[2] = 'x'; // ok
std::cout << s[0] << '\n';
front
访问首字符
定义:
CharT& front();
const CharT& front() const;
用法:
{
std::string s("Exemplary");
char& f = s.front();
f = 'e';
std::cout << s << '\n'; // "exemplary"
}
{
std::string const c("Exemplary");
char const& f = c.front();
std::cout << &f << '\n'; // "Exemplary"
}
back
访问最后的字符
定义:
CharT& back();
const CharT& back() const;
用法:
{
std::string s("Exemplary");
char& back = s.back();
back = 's';
std::cout << s << '\n'; // "Exemplars"
}
{
std::string const c("Exemplary");
char const& back = c.back();
std::cout << back << '\n'; // 'y'
}
data
返回指向字符串首字符的指针
定义:
const CharT* data() const;
用法:
std::string str = "fhn";
std::cout << str.data() << std::endl; // fhn
c_str
返回字符串的不可修改的 C 字符数组版本
定义:
const CharT* c_str() const;
用法:
c_str() 与 data() 进行同一功能。
上述两个函数可以将C++风格的字符串转换为C风格的字符串。
迭代器
begin\cbegin
返回指向起始的迭代器 cbegin中的c表示const,即返回const_iterator,不允许通过迭代器修改元素。
定义:
iterator begin();
const_iterator begin() const;
const_iterator cbegin() const noexcept;
用法:
std::string s("Exemplar");
*s.begin() = 'e';
std::cout << s <<'\n';
auto i = s.cbegin();
std::cout << *i << '\n';
// *i = 'E'; // 错误: i 是常迭代器
end\cend
返回指向后随字符串末字符的字符的迭代器。
定义:
iterator end();
const_iterator end() const;
const_iterator cend() const noexcept;
用法:
std::string s("Exemparl");
std::next_permutation(s.begin(), s.end());
std::string c;
std::copy(s.cbegin(), s.cend(), std::back_inserter(c));
std::cout << c <<'\n'; // "Exemplar"
rbegin\crbegin
返回指向逆转字符串首字符的逆向迭代器。 它对应非逆向字符串的末字符。
定义:
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
const_reverse_iterator crbegin() const noexcept;
用法:
std::string s("Exemplar!");
*s.rbegin() = 'y';
std::cout << s << '\n'; // "Exemplary"
std::string c;
std::copy(s.crbegin(), s.crend(), std::back_inserter(c));
std::cout << c << '\n'; // "yralpmexE"
rend\crend
返回指向后随逆向字符串末字符的字符的逆向迭代器。 它对应前驱非逆向字符串首字符的字符。此字符表现为占位符,试图访问它会导致未定义行为。
定义:
reverse_iterator rend();
const_reverse_iterator crend() const noexcept;
用法:
std::string s("A man, a plan, a canal: Panama");
{
std::string c;
std::copy(s.rbegin(), s.rend(), std::back_inserter(c));
std::cout << c <<'\n'; // "amanaP :lanac a ,nalp a ,nam A"
}
{
std::string c;
std::copy(s.crbegin(), s.crend(), std::back_inserter(c));
std::cout << c <<'\n'; // "amanaP :lanac a ,nalp a ,nam A"
}
容量
empty
检查字符串是否为空,即是否 begin() == end()
定义:
bool empty() const;
用法:
std::string str;
bool flag = str.empty(); // 输出 true
size/length
返回 string 中的 CharT 元素数 即 std::distance(begin(), end()) 。
定义:
size_type size() const;
size_type length() const;
用法:
std::string str("abcde");
std::cout << str.size() << std::endl; // 输出 5
std::cout << str.length() << std::endl; // 输出 5
max_size
返回字符数的最大值 即对于最大string的 std::distance(begin(), end()) 。
定义:
size_type max_size() const;
用法:
std::string s;
std::cout << s.max_size() << "\n"; // 4611686018427387897
reserve
保留存储
定义:
void reserve( size_type new_cap = 0 );
用法:
std::string s;
s.reserve(100);
capacity
返回当前对象分配的存储空间能保存的字符数量
定义:
size_type capacity() const;
用法:
std::string s{"Exemplar"};
std::cout << s.capacity() << "\n"; // 8
s += " is an example string.";
std::cout << s.capacity() << "\n"; // 30
s.reserve(100);
std::cout << s.capacity() << "\n"; // 100
shrink_to_fit
返回字符数的最大值 即对于最大string的 std::distance(begin(), end()) 。
定义:
void shrink_to_fit();
用法:
std::string s;
std::cout << "Default-constructed capacity is " << s.capacity()
<< " and size is " << s.size() << '\n';
for (int i=0; i<42; i++)
s.append(" 42 ");
std::cout << "Capacity after a couple of appends is " << s.capacity()
<< " and size is " << s.size() << '\n';
s.clear();
std::cout << "Capacity after clear() is " << s.capacity()
<< " and size is " << s.size() << '\n';
s.shrink_to_fit();
std::cout << "Capacity after shrink_to_fit() is " << s.capacity()
<< " and size is " << s.size() << '\n';
// 输出
// Default-constructed capacity is 0 and size is 0
// Capacity after a couple of appends is 256 and size is 168
// Capacity after clear() is 256 and size is 0
// Capacity after shrink_to_fit() is 0 and size is 0
操作
clear
清除内容
如同通过执行 erase(begin(), end()) 从 string 移除所有字符。非法化所有指针、引用及迭代器。
定义:
void clear();
用法:
std::string s{ "Exemplar" };
s.clear();
std::cout << s.size() << std::endl; // 输出 0
insert
插入字符
用法:
std::string s = "xmplr";
// insert(size_type index, size_type count, char ch)
s.insert(0, 1, 'E');
assert("Exmplr" == s);
// insert(size_type index, const char* s)
s.insert(2, "e");
assert("Exemplr" == s);
// insert(size_type index, string const& str)
s.insert(6, "a"s);
assert("Exemplar" == s);
// insert(size_type index, string const& str,
// size_type index_str, size_type count)
s.insert(8, " is an example string."s, 0, 14);
assert("Exemplar is an example" == s);
// insert(const_iterator pos, char ch)
s.insert(s.cbegin() + s.find_first_of('n') + 1, ':');
assert("Exemplar is an: example" == s);
// insert(const_iterator pos, size_type count, char ch)
s.insert(s.cbegin() + s.find_first_of(':') + 1, 2, '=');
assert("Exemplar is an:== example" == s);
// insert(const_iterator pos, InputIt first, InputIt last)
{
std::string seq = " string";
s.insert(s.begin() + s.find_last_of('e') + 1,
std::begin(seq), std::end(seq));
assert("Exemplar is an:== example string" == s);
}
// insert(const_iterator pos, std::initializer_list<char>)
s.insert(s.cbegin() + s.find_first_of('g') + 1, { '.' });
assert("Exemplar is an:== example string." == s);
erase
移除字符
定义:
// 1、移除始于 index 的 min(count, size() - index) 个字符。
basic_string& erase( size_type index = 0, size_type count = npos );
// 2、移除范围 position 的元素。
iterator erase( iterator position );
// 3、移除范围 [first, last) 中的字符。
iterator erase( const_iterator first, const_iterator last );
用法:
std::string s = "This is an example";
s.erase(0, 5); // 擦除 "This "
s.erase(std::find(s.begin(), s.end(), ' ')); // 擦除 ' ', 输出:isan example
s.erase(s.find(' ')); // 从 ' ' 到字符串尾裁剪, 输出:isan
push_back
后附字符到结尾
定义:
void push_back( CharT ch );
用法:
std::string letters {"abc"};
letters.push_back('d'); // letters : "abcd"
pop_back
移除末尾字符
定义:
void pop_back();
用法:
std::string letters {"abc"};
letters.push_back(); // letters : "ab"
append
后附字符到结尾
用法:
std::basic_string<char> str = "string";
const char* cptr = "C-string";
const char carr[] = "Two and one";
std::string output;
// 1) 后附 char 3 次。
// 注意,这是仅有的接受 char 的重载。
output.append(3, '*');
std::cout << "1) " << output << "\n";
// 2) 后附整个 string
output.append(str);
std::cout << "2) " << output << "\n";
// 3) 后附字符串的一部分(此情况为最后 3 个字母)case)
output.append(str, 3, 3);
std::cout << "3) " << output << "\n";
// 4) 后附 C 字符串的一部分
// 注意,因为 `append` 返回 *this ,我们能一同链式调用
output.append(1, ' ').append(carr, 4);
std::cout << "4) " << output << "\n";
// 5) 后附整个 C 字符串
output.append(cptr);
std::cout << "5) " << output << "\n";
// 6) 后附范围
output.append(std::begin(carr) + 3, std::end(carr));
std::cout << "6) " << output << "\n";
// 7) 后附 initializer_list
output.append({ ' ', 'l', 'i', 's', 't' });
std::cout << "7) " << output << "\n";
// 输出:
// 1) ***
// 2) ***string
// 3) ***stringing
// 4) ***stringing Two
// 5) ***stringing Two C-string
// 6) ***stringing Two C-string and one
// 7) ***stringing Two C-string and one list
operator+=
后附字符到结尾
用法:
std::string str;
str.reserve(50); // 预留足够的存储空间以避免内存分配
std::cout << std::quoted(str) << '\n'; // 空字符串
str += "This";
std::cout << std::quoted(str) << '\n';
str += std::string(" is ");
std::cout << std::quoted(str) << '\n';
str += 'a';
std::cout << std::quoted(str) << '\n';
str += {' ','s','t','r','i','n','g','.'};
std::cout << std::quoted(str) << '\n';
str += 76.85; // 等价于 str += static_cast<char>(76.85) ,可能不合意图
std::cout << std::quoted(str) << '\n'; // "This is a string.L"
compare
比较二个字符串 返回值: >0 =0 <0。
用法:
int main()
{
// 1) 与另一 string 比较
{
int compare_value{
std::string{"Batman"}.compare(std::string{"Superman"})
};
}
// 2) 与另一 string 比较子串
{
int compare_value{
std::string{"Batman"}.compare(3, 3, std::string{"Superman"})
};
}
// 3) 与另一子串比较子串
{
std::string a{"Batman"};
std::string b{"Superman"};
int compare_value{a.compare(3, 3, b, 5, 3)};
// 与另一子串比较子串
// 默认到为另一 string 的末尾
assert(compare_value == a.compare(3, 3, b, 5));
}
// 4) 与另一 char 指针比较
{
int compare_value{std::string{"Batman"}.compare("Superman")};
}
// 5) 与另一 char 指针比较子串
{
int compare_value{std::string{"Batman"}.compare(3, 3, "Superman")};
}
// 6) 与另一 char 指针子串比较子串
{
int compare_value{std::string{"Batman"}.compare(0, 3, "Superman", 5)};
}
}
starts_with
检查 string 是否始于给定前缀 C++20
定义:
constexpr bool starts_with( std::basic_string_view<CharT,Traits> sv )
const noexcept;
constexpr bool starts_with( CharT c ) const noexcept;
constexpr bool starts_with( const CharT* s ) const;
用法:
std::string str {"hello word!"};
str.contains('h'); // true
str.contains('x'); // false
ends_with
检查 string 是否终于给定后缀 C++20
定义:
constexpr bool ends_with( std::basic_string_view<CharT,Traits> sv )
const noexcept;
constexpr bool ends_with( CharT c ) const noexcept;
constexpr bool ends_with( const CharT* s ) const;
用法:
std::string str {"hello word!"};
str.contains('!'); // true
str.contains('x'); // false
contains
检查字符串是否含有给定的子串或字符 C++23
定义:
constexpr bool contains( std::basic_string_view<CharT,Traits> sv )
const noexcept;
constexpr bool contains( CharT c ) const noexcept;
constexpr bool contains( const CharT* s ) const;
用法:
std::string str {"hello word!"};
str.contains('h'); // true
str.contains('x'); // false
substr
返回子串
定义:
basic_string substr( size_type pos = 0, size_type count = npos ) const;
用法:
#include <string>
#include <iostream>
int main()
{
std::string a = "0123456789abcdefghij";
// count 为 npos ,返回 [pos, size())
std::string sub1 = a.substr(10);
std::cout << sub1 << '\n';
// pos 和 pos+count 都在边界内,返回 [pos, pos+count)
std::string sub2 = a.substr(5, 3);
std::cout << sub2 << '\n';
// pos 在边界内, pos+count 不在,返回 [pos, size())
std::string sub4 = a.substr(a.size()-3, 50);
std::cout << sub4 << '\n';
try {
// pos 在边界外,抛出
std::string sub5 = a.substr(a.size()+3, 50);
std::cout << sub5 << '\n';
} catch(const std::out_of_range& e) {
std::cout << "pos exceeds string size\n";
}
}
// 输出:
// abcdefghij
// 567
// hij
// pos exceeds string size
replace
替换字符串的指定部分
用法:
#include <iostream>
#include <string>
int main()
{
std::string str("The quick brown fox jumps over the lazy dog.");
str.replace(10, 5, "red"); // 在 10 位置上替换 5 个字符串 为“red”
str.replace(str.begin(), str.begin() + 3, 1, 'A'); // (6)
std::cout << str << '\n';
// 输出 :A quick red fox jumps over the lazy dog.
}
copy
复制字符
定义:
size_type copy( CharT* dest, size_type count, size_type pos = 0 ) const;
用法:
std::string foo("quuuux");
char bar[7]{};
foo.copy(bar, sizeof bar);
std::cout << bar << '\n'; // quuuux
resize
更改存储的字符数
定义:
void resize( size_type count );
void resize( size_type count, CharT ch );
用法:
std::string str {"abc"};
str.resize(2);
std::cout << str << std::endl; // ab
str.resize(5);
std::cout << str << std::endl; // ab
str.resize(6, 'a');
std::cout << str << std::endl; // aba
swap
交换内容
定义:
void swap( basic_string& other );
用法:
std::string a = "AAA";
std::string b = "BBB";
a.swap(b);
查找
find
于字符串中寻找字符
用法:
std::string str {"hello world"};
std::cout << str.find('l') << std::endl; // 2
std::cout << str.find('l', 5) << std::endl; // 9
std::cout << str.find('x') << std::endl; // 18446744073709551615
std::cout << str.find("wor") << std::endl; // 6
rfind
寻找子串的最后一次出现
用法:
std::string str {"hello world"};
std::cout << str.rfind('l') << std::endl; // 9
std::cout << str.rfind('l', 5) << std::endl; // 3
std::cout << str.rfind('x') << std::endl; // 18446744073709551615
std::cout << str.rfind("wor") << std::endl; // 6
非成员函数
operator+
连接两个字符串或者一个字符串和一个字符
用法:
std::string s1 = "Hello";
std::string s2 = "world";
std::cout << s1 + ' ' + s2 + "!\n"; // Hello world!
operator==
以字典序比较两个字符串
定义:
template< class CharT, class Traits, class Alloc >
bool operator==( const std::basic_string<CharT,Traits,Alloc>& lhs,
const std::basic_string<CharT,Traits,Alloc>& rhs ) noexcept;
std::swap
特化 std::swap 算法
定义:
template< class CharT, class Traits, class Alloc >
void swap( std::basic_string<CharT, Traits, Alloc> &lhs,
std::basic_string<CharT, Traits, Alloc> &rhs );
erase(std::string)
擦除元素(C++ 20)
定义:
template< ..., class U >
constexpr typename std::basic_string<...>::size_type
erase(std::basic_string<...>& c, const U& value);
用法:
std::string<char> cnt {"12356"};
auto erased = std::erase(cnt, '3');
erase_if(std::string)
擦除所有满足特定判别标准的元素(C++ 20)
定义:
template< ..., class Pred >
constexpr typename std::basic_string<...>::size_type
erase_if(std::basic_string<...>& c, Pred pred);
用法:
std::string<char> cnt {"12356"};
std::erase_if(cnt,
[](char x) { return (x - '0') % 2 == 0; }
);
输入/输出
operator<< ,operator>>
执行字符串的流输入与输出
定义:
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);
template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
std::basic_string<CharT, Traits, Allocator>& str);
用法:
std::string greeting = "Hello, whirled!";
std::istringstream is(greeting);
std::string hello_comma;
is >> hello_comma;
std::cout << greeting << '\n'; // Hello, whirled!
std::cout << hello_comma << '\n'; // Hello,
getline
从 I/O 流读取数据到字符串
定义:
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>&& input,
std::basic_string<CharT,Traits,Allocator>& str, CharT delim );
template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>&& input,
std::basic_string<CharT,Traits,Allocator>& str );
用法:
// 问候用户
std::string name;
std::cout << "What is your name? ";
std::getline(std::cin, name);
std::cout << "Hello " << name << ", nice to meet you.\n";
// 逐行读文件
std::istringstream input;
input.str("1\n2\n3\n4\n5\n6\n7\n");
int sum = 0;
for (std::string line; std::getline(input, line); ) {
sum += std::stoi(line);
}
std::cout << "\nThe sum is: " << sum << "\n"; // 28
数值转换
stoi、stol、stoll
- 转换字符串为有符号整数
定义:
int stoi( const std::string& str, std::size_t* pos = 0, int base = 10 );
long stol( const std::string& str, std::size_t* pos = 0, int base = 10 );
long long stoll( const std::string& str, std::size_t* pos = 0, int base = 10 );
用法:
std::string str1 = "45";
std::string str2 = "3.14159";
std::string str3 = "31337 with words";
std::string str4 = "words and 2";
int myint1 = std::stoi(str1); // 45
int myint2 = std::stoi(str2); // 3
int myint3 = std::stoi(str3); // 31337
// int myint4 = std::stoi(str4); // 错误: 'std::invalid_argument'
stoul、stoull
- 转换字符串为无符号整数
stof、stod、stold
- 转换字符串为浮点值
to_string
用法:
int a = 1;
float b = 2.1;
double c = 3.2;
std::cout << std::to_string(a) << std::endl; // 1
std::cout << std::to_string(b) << std::endl; // 2.100000
std::cout << std::to_string(c) << std::endl; // 3.200000
辅助类
std::hash< std::string >
string 的散列支持
定义:
template<> struct hash<std::string>;
用法:
std::string s1 {"hello word"};
std::cout << std::hash<std::string>{} (s1) << std::endl; // 17574985697032329722
std::string s2 {"hello word!"};
std::cout << std::hash<std::string>{} (s2) << std::endl; // 8153032484661702781