添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
会开车的香菜  ·  Golang httprouter 库分析 ...·  13 小时前    · 
有胆有识的鼠标垫  ·  PHP: ...·  7 小时前    · 
瘦瘦的斑马  ·  戴铭的博客·  1小时前    · 
失落的勺子  ·  app | Electron 中文网·  1小时前    · 
耍酷的便当  ·  最新规划 ...·  2 月前    · 
失望的斑马  ·  Pat_拼音_释义_百度汉语·  3 月前    · 
1
#include <string>

1.2 声明与初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string s0("Initial string");

// constructors used in the same order as described above:
string s1; // 默认初始化,s1为一个空字符串
string s2(s0); // s2是s0的副本
string s2 = s0; // 与上面是等价的
string s3(s0, 8, 3); // 将s0,从下标8开始,拷贝3个字符至s3
string s4("A character sequence"); // s4字符串的副本,处理字面值最后的那个空字符串外
string s4 = "A character sequence"; // 与上面是等价的
string s5("Another character sequence", 12);// 从字符串下标12开始,直到字符串结尾进行拷贝
string s6a(10, 'x'); // 把s6a初始化为10个字符'x'组成的串
string s6b(10, 42); // 把s6a初始化为10个'*'组成的串,42ASCII码为'*'
string s7(s0.begin(), s0.begin() + 7); // 从s0第一个个迭代器开始拷贝,直到s0.begin() + 7个迭代器
char cs[] = "12345";
string s8(cs, 3); // 复制字符串cs的前3个字符串到s当中

2. 运算符重载

+ 和 += 连接字符串

注意 :使用重载的运算符 + 时,必须保证前两个操作数至少有一个为 string 类型。例如,下面的写法是不合法的:

1
2
3
4
5
6
7
8
#include <iostream>
#include <string>
int main() {
string str1 = "cat";
cout << "apple" + "boy" + str1; // 不合法
string str2 = str1 + "apple"; // 合法
return 0;
}

3. 字符串处理

3.1 使用下标访问元素 []

1
cout << str[0] << endl;

3.2 使用 at() 方法访问

1
cout << str.at(0) << endl;  // (如果溢出会抛出异常)

3.3 size() 获取字符串长度

1
2
string str = "12345";
str.size(); // 长度为5

3.4 length() 获取字符串长度

1
2
string str = "12345";
str.length(); // 长度为5

3.5 capacity() 获取字符串容量

1
2
string str = "12345";
str.capacity(); // 字符串容量为5

3.6 resize() 更改字符串大小

这里改变的是 size() 大小,即string中字符数量。
(1)若新的大小n比原来的 size() 小,则多于n的部分直接删除。
(2)若新的大小n大于string中当前元素数量,则会在string当前的尾部掺入适量元素,是的vector的大小变为n。如果,为 resize() 方法 指定了第二个参数 ,则会把后插入的原始值,初始化为该指定值,如果没有为 resize() 指定第二个参数,则会把新插入的元素初始化为默认的初始值。

1
2
3
string str = "12345";
str.resize(3); // 结果为 123
str.resize(str.size()+2, '+'); // 结果为 123++

3.7 reserve() 改变字符串容量大小

3.8 empty() 字符串是否为空

1
str.empty();

3.9 clear() 清除字符串

1
str.clear();

3.10 substr() 获取子串

1
2
3
4
5
6
string s = "abcdefg";
// s.substr(pos1,n) : 返回字符串位置为pos1后面的n个字符组成的串
string s2 = s.substr(1, 5);// bcdef

// s.substr(pos) : 得到一个pos到结尾的串
string s3 = s.substr(4); // efg

3.11 push_back() 末尾追加一个字符

1
2
3
str.push_back('c');	 // 末尾追加一个字符'c'
str += "c"; // 末尾追加一个字符串"c"
str.append("c") // 末尾追加一个字符串"c"

3.12 pop_back() 删除末尾一个字符

1
str.pop_back();

以上这两个方法在 string中不常用
因为 字符串追加 += 运算符, append() insert()
字符串删除 erase() substr()

3.13 append() 末尾追加 字符 或 字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>

int main () {
std::string str;
std::string str2="Writing ";
std::string str3="print 10 and then 5 more";

//直接追加一个str2的字符串
str.append(str2); // "Writing "
//后面追加str3第6个字符开始的3个字符串
str.append(str3, 6, 3); // "10 "
//追加字符串形参的前5个字符
str.append("dots are cool", 5); // "dots "
//直接添加
str.append("here: "); // "here: "
//添加10个'.'
str.append(10u, '.'); // ".........."
//添加str3迭代器范围的字符串
str.append(str3.begin()+8, str3.end()); // " and then 5 more"
//最后这个比较特殊,意思是添加5个'A',实际上参数里面的65对应的asc码就是65
str.append<int>(5, 65); // "....."
//字符串追加也可以用重载运算符实现
str += "lalala";
std::cout << str << '\n';
return 0;
}

3.14 insert() 插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
using namespace std;
int main(){
string str="to be question";
string str2="the ";
string str3="or not to be";
string::iterator it;

//s.insert(pos,str): 在s的pos位置插入str,下标从0开始
str.insert(6,str2); // to be the question

//s.insert(pos,str,a,n): 在s的pos位置插入str中插入位置a到后面的n个字符
str.insert(6,str3,3,4); // to be not the question

//s.insert(pos,cstr,n): 在pos位置插入cstr字符串从开始到后面的n个字符
str.insert(10,"that is cool",8); // to be not that is the question

//s.insert(pos,cstr): 在s的pos位置插入cstr
str.insert(10,"to be "); // to be not to be that is the question

//s.insert(pos,n,ch): 在s.pos位置上面插入n个ch
str.insert(15,1,':'); // to be not to be: that is the question

//s.insert(s.it,ch): 在s的it指向位置前面插入一个字符ch,返回新插入的位置的迭代器
it = str.insert(str.begin()+5,','); // to be, not to be: that is the question

//s.insert(s.it,n,ch): 在s的it所指向位置的前面插入n个ch
str.insert(str.end(),3,'.'); // to be, not to be: that is the question...

//s.insert(it,str.ita,str.itb): 在it所指向的位置的前面插入[ita,itb)的字符串
str.insert (it+2,str3.begin(),str3.begin()+3); // to be, or not to be: that is the question...

return 0;
}

3.15 replace() 替换

replace支持使用无符号整数寻找位置,也支持用迭代器寻找位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>
using namespace std;
int main () {
string base = "this is a test string.";
string str2 = "n example";
string str3 = "sample phrase";
string str4 = "useful.";

// replace signatures used in the same order as described above:

// Using positions: 0123456789*123456789*12345
string str = base; // "this is a test string."
// 第9个字符以及后面的4个字符被str2代替
str.replace(9, 5, str2); // "this is an example string." (1)
// 第19个字符串以及后面的5个字符用str3的第7个字符以及后面的5个字符代替
str.replace(19, 6, str3, 7, 6); // "this is an example phrase." (2)
// 第8个字符以及后面的9个字符用字符串参数代替
str.replace(8, 10, "just a"); // "this is just a phrase." (3)
// 第8个字符以及后面的5个字符用字符串参数的前7个字符替换
str.replace(8, 6, "a shorty", 7); // "this is a short phrase." (4)
// 第22以及后面的0个字符用3个叹号替换
str.replace(22, 1, 3, '!'); // "this is a short phrase!!!" (5)
// 迭代器的原理同上
// Using iterators: 0123456789*123456789*
str.replace(str.begin(),str.end()-3,str3); // "sample phrase!!!" (1)
str.replace(str.begin(),str.begin()+6,"replace");// "replace phrase!!!" (3)
str.replace(str.begin()+8,str.begin()+14,"is coolness",7);// "replace is cool!!!" (4)
str.replace(str.begin()+12,str.end()-4,4,'o'); // "replace is cooool!!!" (5)
str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful." (6)
std::cout << str << '\n';
return 0;
}

以上的replace操作可以用insert和erase的操作组合替换,但是replace操作更加方便。

3.16 assign() 为字符串赋新值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
using namespace std;
int main () {
string str;
string base = "The quick brown fox jumps over a lazy dog.";

// used in the same order as described above:
// 直接把base赋值给str
str.assign(base);
std::cout << str << '\n';
// 把base第10个字符以及后面的8个字符赋给str
str.assign(base, 10, 9);
std::cout << str << '\n'; // "brown fox"
// 把参数中的0到6个字符串赋给str
str.assign("pangrams are cool", 7);
std::cout << str << '\n'; // "pangram"
// 直接使用参数赋值
str.assign("c-string");
std::cout << str << '\n'; // "c-string"
// 给str赋值10个'*'字符
str.assign(10, '*');
std::cout << str << '\n'; // "**********"
// 赋值是10个'-'
str.assign<int>(10, 0x2D);
std::cout << str << '\n'; // "----------"
// 指定base迭代器范围的字符串
str.assign(base.begin()+16, base.end()-12);
std::cout << str << '\n'; // "fox jumps over"

return 0;
}

3.17 erase() 删除

删除操作有三种:

  • 指定pos和len,其中pos为为起始位置,pos以及后面len-1个字符串都删除
  • 迭代器,删除迭代器指向的字符
  • 迭代器范围,删除这一范围的字符串,范围左闭右开
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <iostream>
    #include <string>

    int main () {
    std::string str ("This is an example sentence.");
    std::cout << str << '\n'; // "This is an example sentence."

    // 直接指定删除的字符串位置第十个后面的8个字符
    str.erase(10, 8);
    std::cout << str << '\n'; // "This is an sentence."

    // 删除迭代器指向的一个字符
    str.erase(str.begin()+9); // "This is a sentence."
    std::cout << str << '\n';

    // 删除迭代器范围的字符
    str.erase (str.begin()+5, str.end()-9);
    std::cout << str << '\n'; // "This sentence."
    return 0;
    }

    3.18 compare() 函数

    由于string重载了运算符,可以直接用>、<、>=、<=、==、!=来进行比较
    或者使用 compare() 函数比较,其和strcmp函数一样,如果两个字符串相等,那么返回0,调用对象大于参数返回1,小于返回-1。 在compare当中还支持部分比较,里面有6个参数可以设置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <bits/stdc++.h>
    using namespace std;
    int main() {
    ios::sync_with_stdio(false);
    string s1="123",s2="123";
    cout<<s1.compare(s2)<<endl;//0

    s1="123",s2="1234";
    cout<<s1.compare(s2)<<endl;//-1

    s1="1234",s2="123";
    cout<<s1.compare(s2)<<endl;//1

    std::string str1 ("green apple");
    std::string str2 ("red apple");

    if (str1.compare(str2) != 0)
    std::cout << str1 << " is not " << str2 << '\n';
    //str1的第6个字符以及后面的4个字符和参数比较
    if (str1.compare(6,5,"apple") == 0)
    std::cout << "still, " << str1 << " is an apple\n";

    if (str2.compare(str2.size()-5,5,"apple") == 0)
    std::cout << "and " << str2 << " is also an apple\n";
    //str1的第6个字符以及后面的4个字符和str2的第4个字符以及后面的4个字符比较
    if (str1.compare(6,5,str2,4,5) == 0)
    std::cout << "therefore, both are apples\n";
    return 0;
    }

    3. string 转换为 const char* 、char * 或者 char[]

    1、如果要将 string 转换为 const char* ,可以使用string提供的函数 c_str() ,或是函数 data()

  • data() 除了返回字符串内容外,不附加结束符’’
  • c_str() 返回一个以‘’结尾的字符数组
  • 2、 const char *c_str()
    函数返回一个指向正规C字符串的指针,内容与本string串相同。这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数 c_str() 把string 对象转换成c中的字符串样式。 注意:一定要使用 strcpy() 函数 等来操作方法 c_str() 返回的指针

    比如: 最好不要这样

    1
    2
    3
    string s = "1234";
    const char* p = s.c_str(); // c最后指向的内容是垃圾,因为s对象被析构,其内容被处理
    // 加const或者用char *p = (char*)str.c_str(); 强制转换

    应该使用如下方式:

    3.1 调用 string的 c_str() 函数 [返回的是const char , 或者使用(char ) 强转成 char *]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
    #include <string>
    #include <cstring>
    int main() {

    char p[20];
    string str = "hello world";
    // c_str()函数返回一个指向正规C字符串的指针cosnt char *, 内容与本string串相同,以'\0'结尾.
    strcpy(p, str.c_str()); // 使用strcpy将返回的字符串拷贝至char p[] 数组
    cout << p << endl;
    }

    3.2 调用 string 的 data() 函数 [返回的是const char , 或者使用(char ) 强转成 char *]

    和上面方法一致,只是返回字符串内容,不附加结束符’’

    3.3 调用 string 的 copy() 函数 [返回的是 char *]

    1
    2
    3
    4
    5
    string str = "hello world"; 
    char p[40];
    str.copy(p, 5, 0); // 这里5,代表复制几个字符,0代表复制的位置
    *(p+5)='\0'; // 要手动加上结束符!!!
    cout << p << endl;

    4. char * 、char []转换为 string

    4.1 char * 转 string

    可以直接赋值

    1
    2
    3
    string s;
    char *p = "hello world";
    s = p;

    4.2 char [] 转 string

    可以直接赋值

    1
    2
    3
    string s;
    char ch[] = "hello world";
    s = ch;

    5. char* 与 char[] 互转

    5.1 char[] 转 char*

    可以直接赋值

    1
    2
    char ch[] = "hello world";
    char *p = ch;

    5.2 char * 转 char[]

    不能直接赋值,可以循环char*字符串逐个字符赋值,也可以使用 strcpy() strcpy_s() 等函数。

    1
    2
    3
    char *p = "hello world";
    char ch[20];
    strcpy(ch, p);

    总结:char[] 数组转换为其他类型,可以直接赋值。

    6. 查找

    6.1 find() 函数

    主要是查找一个字符串是否在调用的字符串中出现过,大小写敏感。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <iostream>
    using namespace std;
    int main(){
    string str ("There are two needles in this haystack with needles.");
    string str2 ("needle");

    // different member versions of find in the same order as above:
    //在str当中查找第一个出现的needle,找到则返回出现的位置,否则返回结尾
    size_t found = str.find(str2);
    if (found!=string::npos)
    cout << "first 'needle' found at: " << found << '\n';
    //在str当中,从第found+1的位置开始查找参数字符串的前6个字符
    found=str.find("needles are small",found+1,6);
    if (found!=string::npos)
    cout << "second 'needle' found at: " << found << '\n';
    //在str当中查找参数中的字符串
    found=str.find("haystack");
    if (found!=string::npos)
    cout << "'haystack' also found at: " << found << '\n';
    //查找一个字符
    found=str.find('.');
    if (found!=string::npos)
    cout << "Period found at: " << found << '\n';
    //组合使用,把str2用参数表中的字符串代替
    // let's replace the first needle:
    str.replace(str.find(str2),str2.length(),"preposition");
    cout << str << '\n';
    return 0;
    }

    6.2 rfind() 函数

    找最后一个出现的匹配字符串,返回的位置仍然是从前往后数的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <iostream>
    using namespace std;

    int main() {
    string str ("The sixth sick sheik's sixth sheep's sick.");
    string key ("sixth");// ^
    //rfind是找最后一个出现的匹配字符串
    size_t found = str.rfind(key);
    if (found!=string::npos) {
    cout<<found<<endl;//输出23
    str.replace (found,key.length(),"seventh");//找到的sixth替换成seventh
    }

    cout << str << '\n';
    return 0;
    }

    6.3 find_….of 函数

  • find_first_of(args) :查找args中任何一个字符第一次出现的位置
  • find_last_of(args) :最后一个出现的位置
  • find_fist_not_of(args) : 查找第一个不在args中的字符
  • find_last_not_of(args) : 查找最后一个不在args中出现的字符
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <iostream>
    using namespace std;

    int main() {
    string str1 ("Please, replace the vowels in this sentence by asterisks.");
    size_t found1 = str1.find_first_of("aeiou");
    //把所有元音找出来用*代替
    while (found1!=string::npos) {
    str1[found1]='*';
    found1=str1.find_first_of("aeiou",found1+1);
    }
    cout << str1 << '\n';

    //在str2中找到第一个不是消协英文字母和空格的字符
    string str2 ("look for non-alphabetic characters...");
    size_t found2 = str2.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");
    if (found2!=string::npos) {
    cout << "The first non-alphabetic character is " << str2[found2];
    cout << " at position " << found2 << '\n';
    }
    return 0;
    }

    find_last_of() find_last_not_of() first 基本相同,就不写例子代码了。

    7. 实例

    7.1 查找给定字符串并把相应子串替换为另一给定字符串

    string 并没有提供这样的函数,所以我们自己来实现。由于给定字符串可能出现多次,所以需要用到 find() 成员函数的第二个参数,每次查找之后,从找到位置往后继续搜索。直接看代码(这个函数返回替换的次数,如果返回值是 0 说明没有替换):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int str_replace(string &str, const string &src, const string &dest) {
    int counter = 0;
    string::size_type pos = 0;
    while ((pos = str.find(src, pos)) != string::npos) {
    str.replace(pos, src.size(), dest);
    ++counter;
    pos += dest.size();
    }
    return counter;
    }

    7.2 从给定字符串中删除一给定字串

    方法和上面相似,内部使用 erase() 完成。代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    int str_erase(string &str, const string src) {
    int counter = 0;
    string::size_type pos = 0;
    while ((pos = str.find(src, pos)) != string::npos) {
    str.erase(pos, src.size());
    ++counter;
    }
    return counter;
    }

    7.3 给定一字符串和一字符集,从字符串剔除字符集中的任意字符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    int str_wash(string &str, const string src) {
    int counter = 0;
    string::size_type pos = 0;
    while ((pos = str.find_first_of(src, pos)) != string::npos) {
    str.erase(pos, 1);
    ++counter;
    }
    return counter;
    }

    7.4 分割字符串(以逗号分隔符为例,分割得到相应数字)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    /*
    输入一连串数字,数字之间逗号隔开,把数字存到数组或者向量里。
    */
    #include <iostream>
    #include <string>
    #include <vector>
    #include <stdio.h>
    using namespace std;

    int main() {
    string str_input;
    cout<<"输入一串以逗号为分隔符的数字字符串:"<<endl;
    while(cin >> str_input) {
    vector<int> nums;
    // string->char *
    char *s_input = (char *)str_input.c_str();
    const char * split = ",";
    // 以逗号为分隔符拆分字符串
    char *p = strtok(s_input, split);

    int a;
    while(p != NULL) {
    // char * -> int
    sscanf(p, "%d", &a);
    nums.push_back(a);
    p=strtok(NULL, split);
    }

    cout<<"输出得到的数字:"<<endl;
    for(a = 0; a < nums.size(); a++) {
    cout<<nums[a]<<endl;
    }
    }
    return 0;
    }

    8. 数值转换

    在io的部分有过数值和字符串相互转换的例子,使用的是stringstream函数,在c++11当中有定义好的现成的函数取调用,非常方便。

    string和数值转换

    //注意,下段代码在MinGw中会报错!即使使用c++11编译也一样,无法识别to_string!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <bits/stdc++.h>
    using namespace std;

    int main() {
    ios::sync_with_stdio(false);
    string s1;
    s1=to_string(100);
    cout<<s1<<endl;
    int a=stoi(s1,0,10)+1;
    cout<<a<<endl;
    return 0;
    }

    9. Reference

  • https://blog.csdn.net/tengfei461807914/article/details/52203202
  • https://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html
  • https://www.cnblogs.com/devilmaycry812839668/p/6353807.html
  • https://blog.csdn.net/hebbely/article/details/79577880
  • https://blog.csdn.net/techfield/article/details/77855620
  • http://www.cplusplus.com/reference/string/string/?kw=string
  •