`
pengc825
  • 浏览: 8551 次
文章分类
社区版块
存档分类
最新评论

标准库的String类型详解

 
阅读更多

标准库的String类型详解

String 是C++标准库STL里面的一种常用的容器,(相当于保存数据类型为char的vector容器)。这个类提供了相当丰富的函数来进行对自身元素字符串的操作,以及与C风格字符串之间的转换。

在C语言里,处理字符串是一件相当困难的事。(因为通常在使用字符串操作的时候会用到一个相当不容易驾驭的类型:指针)

比如下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//example 1:
char str[12] ="Hello";
char *p = str;
*p ='h';//改变第一个字母
//example 2:
char *ptr ="Hello";
*ptr ='h';//错误

第一个字符串数组是变量,是一个可变值得存储空间。而第二个字符串却是一个广义上的常量,指针只是指向存储常量的那块存储空间。

String 被设计出来主要是为了支持长度可变的字符串,以及一些常用的抽象操作方便用户进行多种字符串操作,满足对字符串的一半应用。

使用 String 对象的时候必须包含头文件和命名空间的指定:

1
2
3
#include<string>
using std::string

一. string对象的初始化

string标准库支持几个构造函数用于初始化对象:

1
2
3
4
5
6
7
8
9
string s;// 生成一个空字符串s
string s(str)// 拷贝构造函数 生成str的复制品
string s(str, stridx)// 将字符串str内“始于位置stridx”的部分当作字符串的初值
string s(str, stridx, strlen)// 将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值
string s(cstr)// 将C字符串作为s的初值
string s(chars, chars_len)// 将C字符串前chars_len个字符作为字符串s的初值。
string s(num, c)// 生成一个字符串,包含num个c字符
string s(beg, end)// 以区间beg;end(不包含end)内的字符作为字符串s的初值
s.~string()// 销毁所有字符,释放内存

特别的,因为不能直接把string对象复制给C风格的字符串:

1
2
stringvar="Olympic";
constchar *p =var.c_str();//Correct!

为了和C语言兼容,C++的string对象提供了一个c_str()方法,但是为了防止意外的修改string对象,注意其返回值为 const char * ;

1
2
stringvar="Olympic";
constchar *p =var.c_str();//Correct!

二. string对象的读写操作

string的读写方式为:

1. 忽略前导所有的非法字符(空格,换行符,制表符)。

2. 直到碰到第一个非法字符为止 。

利用 getline() 读取整行字符串 :

1
getline(cin, line);// 第一个参数为一个输入流对象,第二个参数为一个string对象;

( getline() 操作不吸收最后面的换行符,但是会吸收前面的换行符,所以当前面吸收换行符之后,line会被置为string)

三. string对象的函数操作

1. C++字符串和C字符串的转换:

C++ 提供的字符串转化为C所对应的C_string的方法有 data(); c_str(); copy();

其中data(); 以字符数组的形式返回字符串内容,但是并不添加'\0' 。

c_str(); 则返回一个以'\0'结尾的字符数组 。

而copy()则把字符串的内容复制或写入既有的c_string或字符数组内。

因为C++字符串并不以’\0’结尾。

2. string的大小和容量:

一个C++字符串存在3种大小:

  1. 现有字符数: size(); length(); empty();

  2. 当前C++最大能包含字符数: max_size();

  3. 为string重新分配内存: reserve();

3. 元素存取:

两种方法:一种是用下标操作符[]进行索引取值,一种是利用 .at();函数进行取值;

需要注意的 [] 操作符并不检查索引值是否有效,而 at() 函数会检查索引的有效性,如过非法,则会抛出out_of_range错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Str[3];// ok
Str.at(3);// ok
Str[100];// 未定义的行为
Str.at(100);// throw out_of_range
Str[Str.length()]// 未定义行为
Cstr[Cstr.length()]// 返回 ‘\0’
Str.at(Str.length());// throw out_of_range
Cstr.at(Cstr.length())// throw out_of_range
Str[100];// 未定义的行为
Str.at(100);// throw out_of_range
Str[Str.length()]// 未定义行为
Cstr[Cstr.length()]// 返回 ‘\0’
Str.at(Str.length());// throw out_of_range
Cstr.at(Cstr.length())// throw out_of_range

4. 比较函数:

C++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如str<”hello”)。在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得比较。字典排序靠前的字符小,比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小。同时,string(“aaaa”)另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。他返回一个整数来表示比较结果,返回值意义如下:(0 - 相等) (>0 - 大于) (<0 - 小于) 。

1
2
3
4
5
6
7
string s(“abcd”);
s.compare(“abcd”);// 返回0
s.compare(“dcba”);// 返回一个小于0的值
s.compare(“ab”);// 返回大于0的值
s.compare(s);// 相等
s.compare(0,2, s,2,2);// 用”ab”和”cd”进行比较 小于零
s.compare(1,2, ”bcx”,2);// 用”bc”和”bc”比较。
1
2
3
4
5
6
intcompare (conststring& str )const;
intcompare (constchar* s )const;
intcompare ( size_t pos1, size_t n1,conststring& str )const;
intcompare ( size_t pos1, size_t n1,constchar* s)const;
intcompare ( size_t pos1, size_t n1,conststring& str, size_t pos2, size_t n2 )const;
intcompare ( size_t pos1, size_t n1,constchar* s, size_t n2)const;

5. 修改内容:

赋值

第一个赋值方法当然是使用操作符=,新值可以是string(如:s=ns)、c_string(如:s=”gaint”)甚至单一字符(如:s=’j’)。还可以使用成员函数assign(),这个成员函数可以使你更灵活的对字符串赋值。

1
2
3
4
5
6
s.assign(str);// 不说
s.assign(str,1,3);// 如果str是”iamangel” 就是把”ama”赋给字符串
s.assign(str,2, string::npos);// 把字符串str从索引值2开始到结尾赋给s
s.assign(“gaint”);// 不说
s.assign(“nico”,5);// 把’n’ ‘I’ ‘c’ ‘o’ ‘\0’赋给字符串
s.assign(5, ’x’);// 把五个x赋给字符串s

清空:

把字符串的方法有三个:s=””; s.clear(); s.erase();

增加字符:

(这里说的增加是在尾巴上),函数有+=、 append()、 push_back() 。

1
2
3
4
5
6
7
8
9
s += str;// 加个字符串
s += ”my nameisjiayp”;// 加个C字符串
s += ’a’;// 加个字符
s.append(str);
s.append(str,1,3);// 不解释了 同前面的函数参数assign的解释
s.append(str,2, string::npos)// 不解释了
s.append(“my nameisjiayp”);
s.append(“nico”,5);
s.append(5, ’x’);

字符串操作:

字符串操作是一个不小的主题,在标准C++中,string字符串类成为一个标准,之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下的需要.
下面我们首先从一些示例开始学习下string类的使用:

1)

1
2
3
4
5
6
7
8
9
#include<string>
#include<iostream>
usingnamespacestd;
voidmain() {
string s("hehe");
cout << s << endl;
cin.get();
}

2)

1
2
3
4
5
6
7
8
9
10
#include<string>
#include<iostream>
usingnamespacestd;
voidmain() {
char chs[] ="hehe";
string s(chs);
cout << s << endl;
cin.get();
}

3)

1
2
3
4
5
6
7
8
9
10
#include<string>
#include<iostream>
usingnamespacestd;
voidmain() {
char chs[] ="hehe";
string s(chs,1,3);// 指定从chs的索引1开始,最后复制3个字节
cout << s << endl;
cin.get();
}

4)

1
2
3
4
5
6
7
8
9
10
#include<string>
#include<iostream>
usingnamespacestd;
voidmain() {
string s1("hehe");
string s2(s1);
cout << s2 << endl;
cin.get();
}

5)

1
2
3
4
5
6
7
8
9
10
#include<string>
#include<iostream>
usingnamespacestd;
voidmain() {
string s1("hehe",2,3);
string s2(s1);
cout << s2 << endl;
cin.get();
}

6)

1
2
3
4
5
6
7
8
9
10
11
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
char chs[] ="hehe";
string s(chs,3);// 将chs前3个字符作为初值构造
cout << s << endl;
cin.get();
}

7)

1
2
3
4
5
6
7
8
9
10
11
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s(10,'k');// 分配10个字符,初值都是'k'
cout << s << endl;
cin.get();
}
// 以上是string类实例的构造手段,都很简单.

8)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 赋新值
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s(10,'k');// 分配10个字符,初值都是'k'
cout << s << endl;
s ="hehehehe";
cout << s << endl;
s.assign("kdje");
cout << s << endl;
s.assign("fkdhfkdfd",5);// 重新分配指定字符串的前5的元素内容
cout << s << endl;
cin.get();
}

9)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s1 ="hehe";
string s2 ="gagaga";
cout <<"s1 : "<< s1 << endl;
cout <<"s2 : "<< s2 << endl;
s1.swap(s2);
cout <<"s1 : "<< s1 << endl;
cout <<"s2 : "<< s2 << endl;
cin.get();
}

10)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//+=,append(),push_back()在尾部添加字符
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="hehe";
s +="gaga";
cout << s << endl;
s.append("嘿嘿"); // append()方法可以添加字符串
cout << s << endl;
s.push_back('k');// push_back()方法只能添加一个字符...
cout << s << endl;
cin.get();
}


11)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// insert() 插入字符.其实,insert运用好,与其他的插入操作是一样的.
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="hehe";
s.insert(0,"头部");// 在头部插入
s.insert(s.size(),"尾部");// 在尾部插入
s.insert(s.size() /2,"中间");// 在中间插入
cout << s << endl;
cin.get();
}

12)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg";
s.erase(0,1);// 从索引0到索引1,即删除掉了'a'
cout << s << endl;
// 其实,还可以使用replace方法来执行删除操作
s.replace(2,3,"");// 即将指定范围内的字符替换成"",即变相删除了
cout << s << endl;
cin.get();
}

13)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//clear() 删除全部字符
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg";
cout << s.length() << endl;
s.clear();
cout << s.length() << endl;
// 使用earse方法变相全删除
s ="dkjfd";
cout << s.length() << endl;
s.erase(0, s.length());
cout << s.length() << endl;
cin.get();
}

14)

1
2
3
4
5
6
7
8
9
10
11
12
//replace() 替换字符
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg";
s.replace(2,3,"!!!!!");// 从索引2开始3个字节的字符全替换成"!!!!!"
cout << s << endl;
cin.get();
}

15)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// ==,!=,<,<=,>,>=,compare() 比较字符串
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s1 ="abcdefg";
string s2 ="abcdefg";
if(s1 == s2)cout <<"s1 == s2"<< endl;
elsecout <<"s1 != s2"<< endl;
if(s1 != s2)cout <<"s1 != s2"<< endl;
elsecout <<"s1 == s2"<< endl;
if(s1 > s2)cout <<"s1 > s2"<< endl;
elsecout <<"s1 <= s2"<< endl;
if(s1 <= s2)cout <<"s1 <= s2"<< endl;
elsecout <<"s1 > s2"<< endl;
cin.get();
}

16)

1
2
3
4
5
6
7
8
9
10
11
12
13
// size(),length() 返回字符数量
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg";
cout << s.size() << endl;
cout << s.length() << endl;
cin.get();
}

17)

1
2
3
4
5
6
7
8
9
10
11
12
// max_size() 返回字符的可能最大个数
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg";
cout << s.max_size() << endl;
cin.get();
}

18)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// empty() 判断字符串是否为空
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ;
if(s.empty())
cout <<"s 为空."<< endl;
else
cout <<"s 不为空."<< endl;
s = s +"abcdefg";
if(s.empty())
cout <<"s 为空."<< endl;
else
cout <<"s 不为空."<< endl;
cin.get();
}

19)

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
// [ ], at() 存取单一字符
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg1111";
cout <<"use []:"<< endl;
for(inti =0; i < s.length(); i++)
{
cout << s[i] << endl;
}
cout << endl;
cout <<"use at():"<< endl;
for(inti =0; i < s.length(); i++)
{
cout << s.at(i) << endl;
}
cout << endl;
cin.get();
}

20)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg1111";
constchar * chs1 = s.c_str();
constchar * chs2 = s.data();
cout <<"use at():"<< endl;
inti;
for(i =0; i < s.length(); i++)
{
cout <<"c_str() : "<< chs1[i] << endl;
cout <<"data() : "<< chs2[i] << endl;
}
cout <<"c_str() : "<< chs1 << endl;
cout <<"data() : "<< chs2 << endl;
cout << endl;
cin.get();
}

21)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// substr() 返回某个子字符串
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg1111";
string str = s.substr(5,3);// 从索引5开始3个字节
cout << str << endl;
cin.get();
}

22)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// find 查找函数
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg1111";
string pattern ="fg";
string::size_type pos;
pos = s.find(pattern,0);// 从索引0开始,查找符合字符串"f"的头索引
cout << pos << endl;
string str = s.substr(pos, pattern.size());
cout << str << endl;
cin.get();
}

23)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// begin() end() 提供类似STL的迭代器支持
#include<string>
#include<iostream>
usingnamespacestd;
voidmain()
{
string s ="abcdefg1111";
for(string::iterator iter = s.begin(); iter != s.end(); iter++)
{
cout << *iter << endl;
}
cout << endl;
cin.get();
}

版权声明:本文为博主原创文章,未经博主允许不得转载。By PengCoX ( Pengc825@foxmail.com )

分享到:
评论

相关推荐

    C++笔试面试宝典2009版与C++ String深入详解2.0版

    总的五个文档:C C++笔试面试宝典2009版.doc,C++ String深入详解2.0版.pdf,c++标准库——boost程序库导论.chm,C语言难点.wps,高质量C.编程指南.林锐著

    C++ string详解

    C++标准程序库中的string类方法详解

    C语言参考手册 C标准 (内含6个chm格式手册)

    标准 C 库: Standard C I/O Standard C String & Character Standard C Math Standard C Time & Date Standard C Memory Other st andard C functions C++ 标准模板库 C++ Bitsets C++ Double-Ended Queues C++ ...

    C++利用stringstream进行数据类型转换实例

    在C++标准库里面,使用stringstream 可以用于各种数据类型之间的转换 例如string 转 int 代码如下:std::string strId = “1”;  int id = 0;  std::stringstream ss;  ss &lt;&lt; strId&gt;&gt; id; 希望本文所述对大家...

    详解C++中string的用法和例子

    string是C++标准库的一个重要的部分,主要用于字符串处理。可以使用输入输出流方式直接进行操作,也可以通过文件等手段进行操作。同时C++的算法库对string也有着很好的支持,而且string还和c语言的字符串之间有着...

    c/c++ 标准库 bind 函数详解

    bind函数定义在头文件 functional 中。可以将 bind 函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。 bind函数:接收一个函数名作为参数,生成一个新的...

    详解C++中String类模拟实现以及深拷贝浅拷贝

    字符串是一个应用很广泛的类型,也是很基础的类型,C语言并没有直接处理字符串的操作而是采用字符指针和字符串数组进行操作,而在C++中标准库为我们封装了一个字符串的类供我们使用,使用需要#inlcude &lt;string&gt;...

    python利用标准库如何获取本地IP示例详解

    Python语言的核心只包含数字、字符串、列表、字典、文件等常见类型和函数,而由Python标准库提供了系统管理、网络通信、文本处理、数据库接口、图形系统、XML处理等额外的功能。 Python标准库的主要功能有:  1....

    深入解析Go语言的io.ioutil标准库使用

    今天我们讲解的是golang标准库里边的io/ioutil包–也就是package io/ioutil 1.ioutil.ReadDir(dirname string)这个函数的原型是这样的 func ReadDir(dirname string) ([]os.FileInfo, error) 不难看出输入的是...

    C++的sstream标准库详细介绍

    C++的sstream标准库介绍 接下来我们继续看一下C++风格的串流控制 ,C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含sstream.h头文件。 istringstream类用于执行C++...

    用python标准库difflib比较两份文件的异同详解

    这时候使用python的标准库difflib就能满足我们的需求。 下面这个脚本使用了difflib和argparse,argparse用于解析我们给此脚本传入的两个参数(即两份待比较的文件),由difflib执行比较,比较的结果放到了一个html里面...

    C++ Template应用详解

    C++ 的标准库提供许多有用的函数大多结合了模板的观念,如STL以及IO Stream。 函数模板 在c++入门中,很多人会接触swap(int&, int&)这样的函数类似代码如下: void swap(int&a , int& b) { int temp = a; a = b; ...

    详解python时间模块中的datetime模块

    time模块我在之前的文章已经有所介绍,它提供的接口与C标准库time.h基本一致。相比于time模块,datetime模块的接口则更直观、更容易调用。 1、datetime中包含三个类date ,time,datetime 函数datetime.combine(date,...

    Python随机函数库random的使用方法详解

    众所周知,python拥有丰富的内置库,还支持众多的第三方库,被称为胶水语言,随机函数库random,就是python自带的标准库,他的用法极为广泛,除了生成比较简单的随机数外,还有很多功能。使用random库: import ...

    64位xxHash算法(XXH64)的Go实现-Golang开发

    这是一种高质量的哈希算法,比Go标准库中的任何算法都要快得多。 该软件包提供了一个简单的API:xxhash xxhash是64位xxHash算法XXH64的Go实现。 这是一种高质量的哈希算法,比Go标准库中的任何算法都要快得多。 该...

    C++中用substr()函数消除前后空格的解决方法详解

    对于c++,查了一下,可以引用一个c++标准库Boost,可以轻松解决,但要下载,设置环境变量,因而没去弄。当然还可以用正则表达式进行匹配,但似乎都大材小用。不如就用substr()函数,而且string有find_last_not_of,...

    codeup《算法笔记》6.3题目A字符串处理题目编号1983全部测试样例和输出样例

    《算法笔记》6.3小节——C++标准模板库(STL)介绍-&gt;string的常见用法详解A字符串处理题目编号1983全部测试样例和输出样例: 题目描述: 读入两个字符串,字符串除了数字还可能包括 '—'、'E'、'e'、'.',相加之后...

    Kotlin中标准函数run、with、let、also与apply的使用和区别详解

    对于这五个标准函数它们都存在于Kotlin的源码标准库当中,也就是在Standard.kt文件当中。它们都是适用于任何对象的通用扩展函数。但是对于run,with,let,also和apply这五个函数他们的用法及其相似,以至于我们无法...

    对python中raw_input()和input()的用法详解

    raw_input([prompt]) -&gt; string 系统介绍中是:读取标准输入的字符串。因此,无论输入的是数字或者字符或者其他,均被视为字符格式。 如: print "Please input a num:" k = raw_input() print k print type(k) ...

Global site tag (gtag.js) - Google Analytics