string类本不是STL的容器,可是它与STL容器有着不少类似的操做,所以,把string放在这里一块儿进行介绍。之因此抛弃char*的字符串而选用C++标准程序库中的string类,是由于他和前者比较起来,没必要担忧内存是否足够、字符串长度等等,并且做为一个类出现,他集成的操做函数足以完成咱们大多数状况下的须要。咱们尽能够把它当作是C++的基本数据类型。
首先,为了在咱们的程序中使用string类型,咱们必须包含头文件。以下: ios
1 #include <string> // 注意这里不是string.h,string.h是C字符串头文件
声明一个字符串变量很简单:数组
1 string str;
这样咱们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,因此就直接使用了string的默认的构造函数,这个函数所做的就是把str初始化为一个空字符串。string类的构造函数和析构函数以下: app
1) string s; // 生成一个空字符串s 2) string s(str) ; // 拷贝构造函数生成str的复制品 3) string s(str, stridx); // 将字符串str内"始于位置stridx"的部分看成字符串的初值 4) string s(str, stridx, strlen) ; // 将字符串str内"始于stridx且长度顶多strlen"的部分做为字符串的初值 5) string s(cstr) ; // 将C字符串(以NULL结束)做为s的初值 6) string s(chars, chars_len) ; // 将C字符串前chars_len个字符做为字符串s的初值。 7) string s(num, ‘c’) ; // 生成一个字符串,包含num个c字符 8) string s(“value”); string s=“value”; // 将s初始化为一个字符串字面值副本 9) string s(begin, end); // 以区间begin/end(不包含end)内的字符做为字符串s的初值 10) s.~string(); //销毁全部字符,释放内存
string串要取得其中某一个字符,和传统的C字符串同样,能够用s[i]的方式取得。比较不同的是若是s有三个字符,传统C的字符串的s[3]是’\0’字符,可是C++的string则是只到s[2]这个字符而已。函数
(1)C风格字符串spa
(2)C字符数组及其与string串的区别指针
1 string s; 2 s.empty(); // s为空串 返回true 3 s.size(); // 返回s中字符个数 类型应为:string::size_type 4 s[n]; // 从0开始至关于下标访问 5 s1+s2; // 把s1和s2链接成新串 返回新串 6 s1=s2; // 把s1替换为s2的副本 7 v1==v2; // 比较,相等返回true 8 `!=, <, <=, >, >=` 惯有操做 任何一个大写字母都小于任意的小写字母
当进行string对象和字符串字面值混合链接操做时,+操做符的左右操做数必须至少有一个是string类型的:code
1 string s1(“hello”); 2 string s3=s1+”world”; //合法操做 3 string s4=”hello”+”world”; //非法操做:两个字符串字面值相加
(1)string类函数对象
1) =, s.assign() // 赋以新值 2) swap() // 交换两个字符串的内容 3) +=, s.append(), s.push_back() // 在尾部添加字符 4) s.insert() // 插入字符 5) s.erase() // 删除字符 6) s.clear() // 删除所有字符 7) s.replace() // 替换字符 8) + // 串联字符串 9) ==,!=,<,<=,>,>=,compare() // 比较字符串 10) size(),length() // 返回字符数量 11) max_size() // 返回字符的可能最大个数 12) s.empty() // 判断字符串是否为空 13) s.capacity() // 返回从新分配以前的字符容量 14) reserve() // 保留必定量内存以容纳必定数量的字符 15) [ ], at() // 存取单一字符 16) >>,getline() // 从stream读取某值 17) << // 将谋值写入stream 18) copy() // 将某值赋值为一个C_string 19) c_str() // 返回一个指向正规C字符串(C_string)的指针 内容与本string串相同 有’\0’ 20) data() // 将内容以字符数组形式返回 无’\0’ 21) s.substr() // 返回某个子字符串 22) begin() end() // 提供相似STL的迭代器支持 23) rbegin() rend() // 逆向迭代器 24) get_allocator() // 返回配置器
1 s.assign(str); // 不说 2 s.assign(str,1,3); // 若是str是"iamangel" 就是把"ama"赋给字符串 3 s.assign(str,2,string::npos); // 把字符串str从索引值2开始到结尾赋给s 4 s.assign("gaint"); // 不说 5 s.assign("nico",5); // 把’n’ ‘I’ ‘c’ ‘o’ ‘\0’赋给字符串 6 s.assign(5,'x'); // 把五个x赋给字符串
一个C++字符串存在三种大小:
1) 现有的字符数,函数是s.size()和s.length(),他们等效。s.empty()用来检查字符串是否为空。
2) max_size(); 这个大小是指当前C++字符串最多能包含的字符数,极可能和机器自己的限制或者字符串所在位置连续内存的大小有关系。
3) capacity()从新分配内存以前string所能包含的最大字符数。
这里另外一个须要指出的是resize()函数,这个函数为string从新分配内存。从新分配的大小由其参数决定,默认参数为0,这时候会对string进行非强制性缩减。 blog
咱们可使用下标操做符[]和函数at()对元素包含的字符进行访问。可是应该注意的是操做符[]并不检查索引是否有效(有效索引0~str.length()),若是索引失效,会引发未定义的行为。而at()会检查,若是使用at()的时候索引无效,会抛出out_of_range异常。
有一个例外不得不说,const string a;的操做符[]对索引值是a.length()仍然有效,其返回值是’\0’。其余的各类状况,a.length()索引都是无效的。 排序
C ++字符串支持常见的比较操做符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。在使用>,>=,<,<=这些操做符的时候是根据”当前字符特性”将字符按字典顺序进行逐一的比较。字典排序靠前的字符小,比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果肯定两个字符串的大小。
另外一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。他返回一个整数来表示比较结果,返回值意义以下:0-相等 、>0-大于、<0-小于。
也许你须要在string中间的某个位置插入字符串,这时候你能够用insert()函数,这个函数须要你指定一个安插位置的索引,被插入的字符串将放在这个索引的后面。
1 s.insert(0,”my name”); 2 s.insert(1,str);
这种形式的insert()函数不支持传入单个字符,这时的单个字符必须写成字符串形式。为了插入单个字符,insert()函数提供了两个对插入单个字符操做的重载函数:
1 insert(size_type index, size_type num, chart c) 2 insert(iterator pos, size_type num, chart c)
其中size_type是无符号整数,iterator是char*,因此,你这么调用insert函数是不行的:
insert(0, 1, ‘j’);这时候第一个参数将转换成哪个呢?
因此你必须这么写:insert((string::size_type)0, 1, ‘j’)!第二种形式指出了使用迭代器安插字符的形式。
1 s.substr(); // 返回s的所有内容 2 s.substr(11); // 从索引11日后的子串 3 s.substr(5,6); // 从索引5开始6个字符
Iostream标准库支持内存中的输入输出,只要将流与存储在程序内存中的string对象捆绑起来便可。此时,可以使用iostream输入和输出操做符读写这个stream对象。使用stringstream,咱们必须包含头文件#include。
1) >>操做符 // 用于从istream对象中读入输入 2) is >> s; // 从输入流is中读取一个以空白字符分割的字符串,写入s 3) <<操做符 // 用于把输出写到ostream对象中 4) os << s; // 将s写到输出流os中 5) getline(is, s); // 从输入流is中读取一行字符,写入s,直到遇到分行符或到了文件尾 6) istream // 输入流 提供输入操做 7) ostream // 输出流 提供输出操做
1) stringstream strm; // 建立自由的stringstream对象 2) stringstream strm(s); // 建立存储s的副本的stringstream对象,s是stringstream类型 3) strm.str(); // 返回strm中存储的string类型对象 4) strm.str(s); // 将string类型的s复制给strm 返回void
stringstream一般是用来作数据转换的,若是你打算在屡次转换中使用同一个stringstream对象,记住在每次转换前要使用clear()方法。在屡次转换中重复使用同一个stringstream(而不是每次都建立一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数一般是很是耗费CPU时间的。
string到int的转换(与其余类型间的转换同样大同小异):
1 string result=”10000”; 2 int n=0; 3 stream<<result; 4 stream>>n; // n等于10000
首先必须了解,string能够被当作是以字符为元素的一种容器。字符构成序列(字符串)。有时候在字符序列中进行遍历,标准的string类提供了STL容器接口。具备一些成员函数好比begin()、end(),迭代器能够根据他们进行定位。注意,与char*不一样的是,string不必定以NULL(‘\0’)结束。string长度能够根据length()获得,string能够根据下标访问。因此,不能将string直接赋值给char*。
若是要将字面值string直接转换成const char *类型。string有2个函数能够运用:一个是.c_str(),一个是data成员函数。
c_str()函数返回一个指向正规C字符串的指针,内容与本string串相同。这是为了与C语言兼容,在C语言中没有string类型,故必须经过string类对象的成员函数c_str()把string 对象转换成C中的字符串样式。注意:必定要使用strcpy()函数等来操做方法c_str()返回的指针
1 string str = "Hello World"; 2 const char *ch1 = str.c_str(); 3 const char *ch2 = str.data();
此时,ch1与ch2的内容将都是”Hello World”。可是只能转换成const char*,若是去掉const编译不能经过。
C++提供的由C++字符串获得对应的C_string的方法是使用data()、c_str()和copy(),其中
1) data()以字符数组的形式返回字符串内容,但并不添加’\0’。
2) c_str()返回一个以’\0’结尾的字符数组,返回值是const char*。
3) copy()则把字符串的内容复制或写入既有的c_string或字符数组内。
C++字符串并不以’\0’结尾。个人建议是在程序中能使用C++字符串就使用,除非万不得已不选用c_string。
若是要转换成char*,能够用string的一个成员函数strcpy实现。
1 string str = "Hello World"; 2 int len = str.length(); 3 char *data = new char[len+1]; //这里+1仍是不+1须要注意 4 strcpy(data, str.c_str()); // const char *data = new char[len+1]; strcpy(data, str);
此时,data中的内容为”Hello World”使用c_str()要么str赋给一个const指针,要么用strcpy()复制。
string类型可以自动将C风格的字符串转换成string对象:
1 string str; 2 const char *pc = "Hello World"; 3 str = pc; 4 printf(“%s\n”, str); //此处出现错误的输出 5 cout<<str<<endl;
不过这个是会出现问题的。有一种状况我要说明一下。当咱们定义了一个string类型以后,用printf(“%s”,str);输出是会出问题的。这是由于“%s”要求后面的对象的首地址。可是string不是这样的一个类型。因此确定出错。用cout输出是没有问题的,若必定要printf输出。那么能够这样:
1 printf("%s",str.c_str());
这个与char*的状况相同,也能够直接赋值,可是也会出现上面的问题,须要一样的处理。
- 字符数组转化成string类型:
1 char ch [] = "ABCDEFG"; 2 string str(ch); //也可string str = ch;
或者
1 char ch [] = "ABCDEFG"; 2 string str; 3 str = ch; //在原有基础上添加能够用str += ch;
string对象转换成C风格的字符串:
1 const char *str = s.c_str();
这是由于为了防止字符数组被程序直接处理c_str()返回了一个指向常量数组的指针。因为咱们知道string的长度能够根据length()函数获得,又能够根据下标直接访问,因此用一个循环就能够赋值了,这样的转换不能够直接赋值。
1 string str = "Hello World"; 2 int len=str.length(); 3 char ch[255]={}; 4 for( int i=0;i<str.length();i++) 5 ch[i] = str[i]; 6 ch[len+1] = '\0'; 7 printf("%s\n", ch); 8 cout<<ch<<endl;
1 stringstream strm; 2 string s; 3 strm<<s; // 将s写入到strm 4 strm>>s; // 从strm读取串写入s
1 strm.str(); // 返回strm中存储的string类型对象 2 strm.str(s); // 将string类型的s复制给strm 返回void
1 char* cstr; // 将C字符数组转换成流 2 string str(cstr); 3 stringstream ss(str);