头文件和命名空间
#include <string>
using namespace std;
一. string 常用成员函数
1. 构造函数(构造string对象)
string s1; // 构造一个空字符串对象
string s2("example string1");
string s3 = "example string2";
string const s4("const example"); // 字符串常量, 与 s5的声明等效
const string s5("const example"); // 字符串常量, 与 s4的声明等效
string s6 = { 'a','b' }; // "ab"
string s7(s6); // "ab", 以s6对象构造s7对象
s4[0] = 'a'; // 非法
s5[0] = 'a'; // 非法
s1[0] = 'a'; // 合法
2. 使用 at,operator[] 访问指定index(从0开始)对应的字符
at 有越界检查,如果index越界,无论在Debug还是Release编译环境下,程序异常跳出执行;运行exe程序,弹出程序停止工作窗口。
operator[ ] 无越界检查,但是如果越界,取到不可预知字符
string s("a");
cout << s[0]; // a
cout << s[1]; // 不会发生异常,但是结果不可预知
count << s.at(1); // 异常跳出执行
3. front, bakc 分别访问首尾字符
string s("abc");
cout << s.front(); // a
cout << s.end(); // c
4. 指向首字符和末尾字符的迭代器(begin,end)
string s("012345");
for (string::iterator it = s.begin(); it != s.end(); it++)
{ cout << *it; } // 012345
5. 指向首字符和末尾字符的逆向迭代器(rbegin,rend)
string s("012345");
for (string::iterator it = s.rbegin(); it != s.rend(); it++)
{ cout << *it; } // 543210
6. 指向字符串常量的迭代器(cbegin,cend)及逆向迭代器(crbegin,crend)
const string s("012345")
for (string::const_iterator it = s.cbegin(); it != s.cend(); it++)
{ cout << *it; } // 012345, 只读内容,不能修改. 如, *it = 'a'; 非法
7. 应用auto类型,指代以上迭代器更方便
const string s("012345");
for (auto it = s.cbegin(); it != s.cend(); it++)
{ cout << *it; } // it自动转换为只读迭代器
8. empty()检查字符串是否为空, clear()清空字符串, size()/length()返回字符串中的字符数
string s1 = "abc", s2 = "012345";
cout << s1.size() << "\t" << s2.length() << endl; // 3 6
s1.clear();
cout << s1.size << "\t" << s1.empty() << s2.empty() << endl; // 0 1 0
9. insert()在指定index处插入字符或字符串
string s = "abc";
// insert(size_type index, size_type count, char ch),在index处插入count个ch
s.insert(1, 2, 'D'); // "aDDbc"
s = "abc";
// insert(size_type index, const char* s),在index处插入C语言字符串s
// insert(size_type index, const string& s),在index处插入字符串s
s.insert(1, "123"); // "a123bc"
s = "abc.xt";
// insert(const_iterator pos, char ch)
s.insert(s.cbegin() + s.find_last_of('.') + 1, 't'); // "abc.txt"
10. erase()删除字符
// 从index处开始删除count个字符; 不指定count, 则index到末尾的字符全部删除
basic_string& erase( size_type index = 0, size_type count = npos );
// 删除位于position处的字符
iterator erase( iterator position );
iterator erase( const_iterator position );
// 删除first到last的字符
iterator erase( iterator first, iterator last );
iterator erase( const_iterator first, const_iterator last );
string s = "This is an example";
s.erase(0, 5); // 删除 "This "
cout << s << '\n'; // is an example
s.erase(s.find(' ')); // 从' '到字符串尾裁剪, 不指定count, 则index到末尾的字符全部删除
cout << s << '\n'; // is
s.erase(s.begin()); // s, 删除位于position处的字符
cout << s << endl;
11. replace() 替换
以新字符串替换 [pos, pos + count) 或 [first, last) 所指示的 string 部分。
basic_string& replace( size_type pos, size_type count, const basic_string& str );
basic_string& replace( const_iterator first, const_iterator last, const basic_string& str );
basic_string& replace( size_type pos, size_type count, const CharT* cstr );
basic_string& replace( const_iterator first, const_iterator last, const CharT* cstr );
string str("The quick brown fox jumps over the lazy dog.");
str.replace(10, 5, "red"); // The quick red fox ...
str.replace(str.begin(), str.begin() + 3, 1, 'A'); // A quick red fox ...
cout << str << '\n'; // A quick red fox jumps over the lazy dog.
12. append(),operator+=,assign()的使用方法
string s;
int a = 10;
s.assign("P").append(to_string(a)); // 给s赋值"P",后附"10"
// 或
s += "P" + to_string(a);
13. compare(const string& str)比较两个字符串,返回 >0,0,<0; 分别表示当前字符串大于,等于,小于str
// 逐字符字典序比较,可以用关系运算符( < 、 <= 、 == 、 > 等)替代
string s1 = "P2",s2="P10";
cout << s1.compare(s2) << endl; // 1,表示s1大于s2
cout << (s1 > s2) << endl; // 1,表示s1大于s2
14. substr()取子串
basic_string substr( size_type pos = 0, size_type count = npos ) const;
返回子串 [pos, pos+count). 若请求的子串越过 string 的结尾, 或若 count == npos, 则返回的子串为 [pos, size()).
string s("abcd");
string sub1 = s.substr(1); // "bcd"
string sub2 = s.substr(1,2); // "bc"
15. find()从pos开始,查找首个等于给定字符序列的子串
// 从pos开始,查找首个等于给定字符序列的子串,找到返回index,否则返回string::npos
size_type find( const basic_string& str, size_type pos = 0 ) const
size_type find( const CharT* s, size_type pos = 0 ) const;
// 查找单个字符
size_type find( CharT ch, size_type pos = 0 ) const;
string::size_type n;
const string s = "This is a string";
// 从 pos = 0 开始搜索
n = s.find("is");
if(n == string::npos) cout << "not found";
else cout << "found: " << s.substr(n); // is is a string
// 从位置 pos = 5 开始搜索
n = s.find("is", 5);
if(n == string::npos) cout << "not found";
else cout << "found: " << s.substr(n); // is a string
// 寻找单个字符
n = s.find('a');
if(n == string::npos) cout << "not found";
else cout << "found: " << s.substr(n); // a string
// 寻找单个字符
n = s.find('q');
if(n == string::npos) cout << "not found"; // not found
else cout << "found: " << s.substr(n);
类似的查找函数 |
---|
rfind |
find_first_of |
find_first_not_of |
find_last_of |
find_last_not_of |
16. c_str() 返回C语言字符串常量,常用于使用C语言的字符串库函数时使用
string s1("ABc"), string s2("abc");
int a = _strcmpi(s1.c_str(), s2.c_str()); // 忽略大小写比较两个c语言字符串
cout << a << endl; // 0
二. 非成员函数
1. operator+ 连接两个字符串或者一个字符串和一个字符
string s1 = "Hello", s2 = "world";
cout << s1 + ' ' + s2 + "!\n";
2. 以字典序比较二个字符串
operator==, operator!=, operator<, operator>, operator<=, operator>=
string s1 = "P1", s2 = "P2";
if(s1 == s2) cout << "equal."
else cout << "not equal!";
3. getline()从I/O流读取数据到字符串
// 从cin读取字符并将它们放进str, 回车('\n')结束
string str;
while(str.empty()) // 为了防止用户直接回车,而得到一个空串
getline(cin, str); // str中不包含'\n'
// 从文件读取一行
string line;
ifstream fin("test.txt"); // 添加 #include <fstream>
if (!fin) cout << "Error!! read test.txt.";
else
{
while (!fin.eof())
{
getline(fin, line);
// ....
}
fin.close();
}
4. stoi(const string& str), stof(const string& str)字符串转整型和浮点型
string str1 = "45";
string str2 = "3.14159";
string str3 = "31337 with words";
string str4 = "words and 2";
int myint1 = std::stoi(str1);
int myint2 = std::stoi(str2);
int myint3 = std::stoi(str3);
// int myint4 = std::stoi(str4); // 错误: 'std::invalid_argument'
cout << myint1 << '\n'; // 45
cout << myint2 << '\n'; // 3
cout << myint3 << '\n'; // 31337
5. to_string()数值转字符串
double f = 23.43;
double f2 = 1e-9;
double f3 = 1e40;
double f4 = 1e-40;
double f5 = 123456789;
string f_str = std::to_string(f); // 23.430000
string f_str2 = std::to_string(f2); // 注意:返回 "0.000000"
string f_str3 = std::to_string(f3); // 注意:不返回 "1e+40".
string f_str4 = std::to_string(f4); // 注意:返回 "0.000000"
string f_str5 = std::to_string(f5); // 123456789.000000
三. 综合应用
/*************************************
* 去除前后缀空格('\n','\r','\t',' ')
*************************************/
static string& trim(string& s)
{
if (s.empty()) return s;
// 去掉s的前缀空格
string::size_type pos = 0;
for (auto it = s.begin(); it < s.end(); it++) {
if (*it == '\n' || *it == '\r' || *it == '\t' || *it == ' ') pos++;
else break;
}
s = s.substr(pos);
// 删除s的后缀空格
while (1)
{
char end = s.back();
if (end == '\n' || end == '\r' || end == '\t' || end == ' ')
s.erase(prev(s.end()));
else break;
}
return s;
}
/*************************************
* 首先去除s的前后缀空格,
* 然后提取以指定分隔符隔开的子字符串至sVector.
* 并且保证各个子串前后无空格
* 空串或去除前后缀的空格后是空串,直接返回
*************************************/
static vector<string>& split(const string& s, vector<string>& sVector, char delimit)
{
if (s.empty()) return sVector;
string str(s); // 复制s至str
trim(str); // 去除前后缀空格('\n','\r','\t',' ')
if (str.empty()) return sVector;
string::size_type pos1 = 0, pos2 = 0;
while (1)
{
pos2 = str.find(delimit, pos1); // 从pos1开始找分隔符
if (pos2 == string::npos) break; // 未找到分隔符
string sub = str.substr(pos1, pos2 - pos1);
trim(sub);
if (sub.empty()) std::cout << "Waring, have empty sub string in " << s << endl;
sVector.push_back(sub);
pos1 = pos2 + 1;
}
// 添加最后一个
string sub = str.substr(pos1);
trim(sub);
if (sub.empty()) std::cout << "Waring, have empty splited substring in " << s << endl;
sVector.push_back(sub);
return sVector;
}
/*************************************
* 获取文件扩展名(如,".docx")
* 参数ext返回文件扩展名
* 无扩展名,函数返回false; 否则返回true
*************************************/
static bool extFile(const string& file, string& ext)
{
string::size_type pos;
pos = file.find_last_of('.');
if(pos == string::npos) return false;
ext = file.substr(pos);
return true;
}
/*************************************
* 字符串中的小写字母转为大写字母
*************************************/
static string& toUpper(string &s)
{
for (string::iterator it = s.begin(); it != s.end(); ++it)
if (*it >= 'a' && *it <= 'z') *it = *it - ('a' - 'A');
return s;
}
/*************************************
* 调用C语言字符串库函数,忽略大小写,比较两个字符串
* s1 > s2, s1= s2, s1 < s2 分别返回: 大于0,0,小于0的整数
*************************************/
static int compareI(const string& s1, const string& s2)
{
return _strcmpi(s1.c_str(), s2.c_str());
}
参考:
C++ 参考手册 https://zh.cppreference.com/w/cpp/string/basic_string