C++中string类的使用方法
如果所比较的两个string 相等,则返回0; 操作string 大于参数string,返回
正数;操作string 小于参数string,返回负数。
(1) 比较操作string 与 _Str 或C-string _Ptr
int compare( const basic _ string& _Str ) const;
int compare( const value _ type* _Ptr ) const;
int com = s.compare ( sp );
(2) 比较操作string 中 _Pos1 ( 下标)开始的 _Num1 个字符 与 string _Str
比较操作string 中 _Pos1 ( 下标)开始的 _Num1 个字符 与 C-string _Ptr
比较操作string 中 Pos1 ( 下标)开始的 Num1 个字符 与 Str 中 Off ( 下标)开始 Count 个字
符
int compare( size _ type _Pos1 , size _ type _Num1 , const basic _ string& _Str );
int compare( size _ type _Pos1 , size _ type _Num1 , const value _ type* _Ptr ) const;
int compare( size _ type _Pos1 , size _ type _Num1 , const basic _ string& _Str ,
size _ type _Off , size _ type _Count );
int com1 = s.compare ( 2 , 3 , sp );
int com2 = s.compare ( 2 , 3 , c );
int com3 = s.compare ( 1 , 3 , cs , 3 ,1 );
basic_string::erase
删除string 中的一个或几个元素。前两个成员函数,返回要被删除的子串的下
一个元素的iterator; 第三个函数,返回删除后的string 的引用。
(1) 删除string 中从 _ First 到 _ Last 的字符
iterator erase( iterator _First , iterator _Last );
basic_string ::iterator s_Iter;
s_Iter = s.erase ( s.begin ( ) + 3 , s.end ( ) - 1 ); // s_Iter=s.end( )
(2) 删除string 中 _It 所指的字符
iterator erase( iterator _It );
s_Iter = s.erase ( s.begin ( ) + 5 );
(3) 删除string 中从 _Pos ( 下标)开始的 _Count 个字符
basic _ string& erase( size _ type _Pos = 0, size _ type _Count = npos );
str = s.erase ( 6 , 8 ); // str 也是 string
basic_string::find
寻找给定的string。返回找到的第一个string 下标值;如果没找到则返回npos。
(1) 找一个character _Ch 。(默认从头找)
size _ type find( value _ type _Ch , size _ type _Off = 0 ) const;
string s ( "Hello Everyone" );
basic_string ::size_type index1, index2;
static const basic_string ::size_type npos = -1;
index1 = s.find ( "e" , 3 ); // index1=8, 不是 6
index2 = s.find ( "x" ); // index2=-1
if ( indexCh1a != npos ) cout <else cout << "The character 'e' was not found in str1 ." << endl;
(2) 找一个C-string。(默认从头找)
size _ type find( const value _ type* _Ptr , size _ type _Off = 0 ) const;
string s ( "Let me make this perfectly clear." );
basic_string ::size_type index;
const char *c = "perfect";
index = s.find ( c , 5 ); // index=17
(3) 找一个string。(默认从头找)
size _ type find( const basic _ string& _Str , size _ type _Off = 0 ) const;
string s ( "clearly this perfectly unclear." );
basic_string ::size_type index;
string sta ( "clear" );
index = s.find ( sta , 5 ); // index=24
其实string本质上跟vector差不多
深入剖析C++中的string类
一,C语言的字符串
在C语言里,对字符串的处理一项都是一件比较痛苦的事情,因为通常在实现字符串的操作的时候都会用到最不容易驾驭的类型——指针。
比如下面这个例子:
//example 1:
char str[12] = "Hello";
char *p = str;
*p = ''h''; //改变第一个字母
//example 2:
char *ptr = "Hello";
*ptr = ''h''; //错误
第一个字符串时用数组开辟的,它是可以改变的变量。而第二个字符串则是一个常量,也就是字面值。ptr只是指向它的指针而已,而不能改变指向的内容。
看两者的汇编即可明了:
char p[] = "Hello";
004114B8 mov eax,dword ptr [string "Hello" (4166FCh)]
004114BD mov dword ptr [ebp-10h],eax
004114C0 mov cx,word ptr ds:[416700h]
004114C7 mov word ptr [ebp-0Ch],cx
char *ptr = "Hello";
004114CB mov dword ptr [ebp-1Ch],offset string "Hello" (4166FCh)
可见用数组和用指针是完全不相同的。
要想通过指针来改变常量是错误,正确的写法应该是用const指针。
const char *ptr = "Hello";
二,初识string类
正是因为C风格字符串(以空字符结尾的字符数组)太过复杂难于掌握,不适合大程序的开发,所以C++标准库定义了一种string类,定义在头文件<string>。注意<string.h>和<cstring>都是错误的,这两个头文件主要定义C风格字符串操作的一些方法,譬如strlen(), strcpy()等。第一个是C的头文件格式,而第二个是C++风格的头文件,但是和<string.h>是一样的,它的目的是为了和C兼容。
看下面例子:
//example 3:
string str("world"); //可以用C风格字符串初始化
string words = "Hello";
string greet = words;
string join = greet + words; //可以像基本类型一样操作
但是如果试图把string类型的对象直接赋给C风格的字符串的话,编译器会报错的。
string var = "Olympic";
char *ptr = var; //error!
但是实际应用中这个问题也难以避免,很多时候我们还是需要将string类型的转化为char*来实现自定义的操作,C++标准库也为了和之前用C写的程序兼容,于是可以用string的c_str()函数。
string var = "Olympic";
char *ptr = var.c_str(); //还不能被编译
或者通过const_cast去掉其const属性亦可
char *ptr=const_cast<char *>(var.c_str()); //correct!
这样就可以通过ptr修改其指向的地址空间内容
但是c_str()为了防止意外地修改string对象,返回的是const指针,所以上面这段代码是不能被编译的。正确的应该是用const指针。
string var = "Olympic";
const char *p = var.c_str(); //Correct!
这个c_str()方法在C++IO流操作上也被广泛应用。
在打开文件时,如果要指定文件名,可以用C风格的字符串。如果用到string类型的字符串作为文件名时,就必须调用c_str()方法将其转换为一个C风格字符串。
//example 4:
string filename; //定义文件名称
cin >> filename;
ifstream.open(filename.c_str()); //要使用C风格字符串
三, 深入了解string类
对string有一定了解以后,我们可以来了解C++标准库定义的一系列丰富的字符串操作,当然都是基于string类型。从某一种程度上来说,string就是一种字符容器。
标准库为string定义了很多方法,包括构造、插入(insert)、替换(assign和replace)、比较(compare)、查找(find)、删除(erase)、连接(append)以及对子串的操作(substr)。而每一种操作都有很多种重载。
比如插入,除了包括标准容器的插入方式以外,string类本身还有一些特有的插入方法。
//example 5:
//与标准容器相同的插入操作:
str.insert(iter, value) //在迭代器iter之前插入value, 返回新元素的迭代器
str.insert(iter, n, value); //在迭代器iter之前插入n个value,返回void
str.insert(iter, begin, end); //在迭代器iter之前插入迭代器begin和end标记范围内的元素,返回void
//string类特有的插入方法:
str.insert(pos, n, ch); //在下标为pos的字符之前插入n个字符ch
str.insert(pos, str2); //在下标为pos的字符之前插入string类型的对象str2的副本
str.insert(pos1, str2, pos2, len); //在下标为pos1的z字符之前插入string类型str2中从下表为pos2开始的len个字符
str.insert(pos, cp); //在下标为pos的字符前插入字符指针cp指向的C风格字符串的副本
总之string是一种非常灵活的字符串类型,标准库让我们可以忽略内存管理和具体实现方式,我们只需要关注其接口就好。并且初学者在使用字符串的时候也应尽量使用这种类型,而不是C风格的字符串。
当然,无C语言学习经历的人可以例外。
如果所比较的两个string 相等,则返回0; 操作string 大于参数string,返回
正数;操作string 小于参数string,返回负数。
(1) 比较操作string 与 _Str 或C-string _Ptr
int compare( const basic _ string& _Str ) const;
int compare( const value _ type* _Ptr ) const;
int com = s.compare ( sp );
(2) 比较操作string 中 _Pos1 ( 下标)开始的 _Num1 个字符 与 string _Str
比较操作string 中 _Pos1 ( 下标)开始的 _Num1 个字符 与 C-string _Ptr
比较操作string 中 Pos1 ( 下标)开始的 Num1 个字符 与 Str 中 Off ( 下标)开始 Count 个字
符
int compare( size _ type _Pos1 , size _ type _Num1 , const basic _ string& _Str );
int compare( size _ type _Pos1 , size _ type _Num1 , const value _ type* _Ptr ) const;
int compare( size _ type _Pos1 , size _ type _Num1 , const basic _ string& _Str ,
size _ type _Off , size _ type _Count );
int com1 = s.compare ( 2 , 3 , sp );
int com2 = s.compare ( 2 , 3 , c );
int com3 = s.compare ( 1 , 3 , cs , 3 ,1 );
basic_string::erase
删除string 中的一个或几个元素。前两个成员函数,返回要被删除的子串的下
一个元素的iterator; 第三个函数,返回删除后的string 的引用。
(1) 删除string 中从 _ First 到 _ Last 的字符
iterator erase( iterator _First , iterator _Last );
basic_string ::iterator s_Iter;
s_Iter = s.erase ( s.begin ( ) + 3 , s.end ( ) - 1 ); // s_Iter=s.end( )
(2) 删除string 中 _It 所指的字符
iterator erase( iterator _It );
s_Iter = s.erase ( s.begin ( ) + 5 );
(3) 删除string 中从 _Pos ( 下标)开始的 _Count 个字符
basic _ string& erase( size _ type _Pos = 0, size _ type _Count = npos );
str = s.erase ( 6 , 8 ); // str 也是 string
basic_string::find
寻找给定的string。返回找到的第一个string 下标值;如果没找到则返回npos。
(1) 找一个character _Ch 。(默认从头找)
size _ type find( value _ type _Ch , size _ type _Off = 0 ) const;
string s ( "Hello Everyone" );
basic_string ::size_type index1, index2;
static const basic_string ::size_type npos = -1;
index1 = s.find ( "e" , 3 ); // index1=8, 不是 6
index2 = s.find ( "x" ); // index2=-1
if ( indexCh1a != npos ) cout <else cout << "The character 'e' was not found in str1 ." << endl;
(2) 找一个C-string。(默认从头找)
size _ type find( const value _ type* _Ptr , size _ type _Off = 0 ) const;
string s ( "Let me make this perfectly clear." );
basic_string ::size_type index;
const char *c = "perfect";
index = s.find ( c , 5 ); // index=17
(3) 找一个string。(默认从头找)
size _ type find( const basic _ string& _Str , size _ type _Off = 0 ) const;
string s ( "clearly this perfectly unclear." );
basic_string ::size_type index;
string sta ( "clear" );
index = s.find ( sta , 5 ); // index=24
其实string本质上跟vector差不多
深入剖析C++中的string类
一,C语言的字符串
在C语言里,对字符串的处理一项都是一件比较痛苦的事情,因为通常在实现字符串的操作的时候都会用到最不容易驾驭的类型——指针。
比如下面这个例子:
//example 1:
char str[12] = "Hello";
char *p = str;
*p = ''h''; //改变第一个字母
//example 2:
char *ptr = "Hello";
*ptr = ''h''; //错误
第一个字符串时用数组开辟的,它是可以改变的变量。而第二个字符串则是一个常量,也就是字面值。ptr只是指向它的指针而已,而不能改变指向的内容。
看两者的汇编即可明了:
char p[] = "Hello";
004114B8 mov eax,dword ptr [string "Hello" (4166FCh)]
004114BD mov dword ptr [ebp-10h],eax
004114C0 mov cx,word ptr ds:[416700h]
004114C7 mov word ptr [ebp-0Ch],cx
char *ptr = "Hello";
004114CB mov dword ptr [ebp-1Ch],offset string "Hello" (4166FCh)
可见用数组和用指针是完全不相同的。
要想通过指针来改变常量是错误,正确的写法应该是用const指针。
const char *ptr = "Hello";
二,初识string类
正是因为C风格字符串(以空字符结尾的字符数组)太过复杂难于掌握,不适合大程序的开发,所以C++标准库定义了一种string类,定义在头文件<string>。注意<string.h>和<cstring>都是错误的,这两个头文件主要定义C风格字符串操作的一些方法,譬如strlen(), strcpy()等。第一个是C的头文件格式,而第二个是C++风格的头文件,但是和<string.h>是一样的,它的目的是为了和C兼容。
看下面例子:
//example 3:
string str("world"); //可以用C风格字符串初始化
string words = "Hello";
string greet = words;
string join = greet + words; //可以像基本类型一样操作
但是如果试图把string类型的对象直接赋给C风格的字符串的话,编译器会报错的。
string var = "Olympic";
char *ptr = var; //error!
但是实际应用中这个问题也难以避免,很多时候我们还是需要将string类型的转化为char*来实现自定义的操作,C++标准库也为了和之前用C写的程序兼容,于是可以用string的c_str()函数。
string var = "Olympic";
char *ptr = var.c_str(); //还不能被编译
或者通过const_cast去掉其const属性亦可
char *ptr=const_cast<char *>(var.c_str()); //correct!
这样就可以通过ptr修改其指向的地址空间内容
但是c_str()为了防止意外地修改string对象,返回的是const指针,所以上面这段代码是不能被编译的。正确的应该是用const指针。
string var = "Olympic";
const char *p = var.c_str(); //Correct!
这个c_str()方法在C++IO流操作上也被广泛应用。
在打开文件时,如果要指定文件名,可以用C风格的字符串。如果用到string类型的字符串作为文件名时,就必须调用c_str()方法将其转换为一个C风格字符串。
//example 4:
string filename; //定义文件名称
cin >> filename;
ifstream.open(filename.c_str()); //要使用C风格字符串
三, 深入了解string类
对string有一定了解以后,我们可以来了解C++标准库定义的一系列丰富的字符串操作,当然都是基于string类型。从某一种程度上来说,string就是一种字符容器。
标准库为string定义了很多方法,包括构造、插入(insert)、替换(assign和replace)、比较(compare)、查找(find)、删除(erase)、连接(append)以及对子串的操作(substr)。而每一种操作都有很多种重载。
比如插入,除了包括标准容器的插入方式以外,string类本身还有一些特有的插入方法。
//example 5:
//与标准容器相同的插入操作:
str.insert(iter, value) //在迭代器iter之前插入value, 返回新元素的迭代器
str.insert(iter, n, value); //在迭代器iter之前插入n个value,返回void
str.insert(iter, begin, end); //在迭代器iter之前插入迭代器begin和end标记范围内的元素,返回void
//string类特有的插入方法:
str.insert(pos, n, ch); //在下标为pos的字符之前插入n个字符ch
str.insert(pos, str2); //在下标为pos的字符之前插入string类型的对象str2的副本
str.insert(pos1, str2, pos2, len); //在下标为pos1的z字符之前插入string类型str2中从下表为pos2开始的len个字符
str.insert(pos, cp); //在下标为pos的字符前插入字符指针cp指向的C风格字符串的副本
总之string是一种非常灵活的字符串类型,标准库让我们可以忽略内存管理和具体实现方式,我们只需要关注其接口就好。并且初学者在使用字符串的时候也应尽量使用这种类型,而不是C风格的字符串。
当然,无C语言学习经历的人可以例外。