STL第一章-string的使用方法
2014-03-01 21:57
369 查看
1.一些常用的使用方法,我还是觉得自己用代码打出来更适合自己的记忆。所以再简单的程序我都是要码字,调试的。
在下面的程序中,我列举了几乎所有string的常见用法。
并且自己写了一个判断string是不是一个数字的算法,感觉string很强大,要用好真的会很方便。
①string与wstring的区别
string是对char*的管理,一个字符只占一个字节大小。一个汉字占两个字节,ASCII编码。
wstring是对wchar_t*的管理,一个字符占两个字节大小,一个汉字占两个字节,Unicode编码。
wstring的使用方法跟string类似,区别主要在于函数参数char*与函数参数wchar_t*
②string与wstring的转换
第一种方法:
调用Windows的API函数:WideCharToMultiByte()函数和MultiByteToWideChar()函数。
第二种方法:
使用ATL的CA2W类与CW2A类。或使用A2W宏与W2A宏。
第三种方法:
跨平台的方法,使用CRT库的mbstowcs()函数和wcstombs()函数,需设定locale。
③编码统一化,编写单一源代码
如果我们想建立两个版本的程序,一个处理ASCII字符串,另一个处理Unicode字符串,最好的解决办法是编写出既能按ASCII编译又能按Unicode编译的单一源代码。
把以下代码加入到程序中,只要修改一个宏就能满足我们的要求。
3.string类中data()和c_str()的区别
偶尔看到这两个成员函数,有点奇怪,为什么给了两个相近函数,一定是有差别的。查了一下,结果如下:
定义:
const value_type *c_str( ) const;
const value_type *data( ) const;
1. c_str()返回的相当与const char * ,而data()返回的是数组;
2.c_str()返回的字符串带有”\0″, data()的数组没有;
3.c_str()返回的长度应该是整个长度, 而data()返回的是不含结束符的长度, 当然,如果用size()和length()求是一样的。
4. c_str()返回的是一个安全C标准串,data()返回的内容中可能没有traits::eos(), 但实际测试,发现data()没有无结束符的,但据说不是所有的stl都这样支持。
摘抄了其他人总结的一些相关内容,感觉挺有用的。
// c_str()源码,比较奇怪那个terminate()这不是异常的最终处理吗,难道是检测了异常??
———————————————————————————————
const charT* c_str () const
{
if (length () == 0)
return “”;
terminate ();
return data ();
}
原来c_str()的流程是:先调用terminate(),然后在返回data()。因此如果你对效率要求比较高,而且你的处理又不一定需要以\0的方式结束,你最好选择data()。但是对于一般的C函数中,需要以const char*为输入参数,你就要使用c_str()函数。
对于c_str() data()函数,返回的数组都是由string本身拥有,千万不可修改其内容。其原因是许多string实现的时候采用了引用机制,也就是说,有可能几个string使用同一个字符存储空间。而且你不能使用sizeof(string)来查看其大小。详细的解释和实现查看Effective STL的条款15:小心string实现的多样性。
另外在你的程序中,只在需要时才使用c_str()或者data()得到字符串,每调用一次,下次再使用就会失效,如:
string strinfo(“this is Winter”);
…
//最好的方式是:
foo(strinfo.c_str());
//也可以这么用:
const char* pstr=strinfo.c_str();
foo(pstr);
//不要再使用了pstr了, 下面的操作已经使pstr无效了。
strinfo += ” Hello!”;
foo(pstr);//错误!
会遇到什么错误?当你幸运的时候pstr可能只是指向”this is Winter Hello!”的字符串,如果不幸运,就会导致程序出现其他问题,总会有一些不可遇见的错误。总之不会是你预期的那个结果。
在下面的程序中,我列举了几乎所有string的常见用法。
并且自己写了一个判断string是不是一个数字的算法,感觉string很强大,要用好真的会很方便。
#include<iostream> #include <string> using namespace std; bool IsStringNum(string strNum); int main() { //初始化strOne() string strOne("The day you went away!"); for (string::iterator itStr = strOne.begin();itStr != strOne.end();++itStr) { cout<<(*itStr); } cout <<endl; //初始化10个y字符 string strTwo(10,'y'); for (string::reverse_iterator itStr = strTwo.rbegin();itStr != strTwo.rend();++itStr) { cout<<(*itStr); } cout<<endl; cout<<strOne.size()<<endl; //返回字符串的大小 cout<<strOne.length()<<endl; //返回字符串的长度 cout<<strOne.capacity()<<endl; //返回分配字符串空间的大小 cout<<strOne.max_size()<<endl; //返回可以存储的最大长度 if(!strOne.empty()) //判断字符串是否为空 { cout<<"strOne is not empty"<<endl; } strTwo.resize(8); //重新设置string的长度 cout<< strTwo <<endl; strTwo.resize(10,'x'); //重新设置string的长度,不够的用x拼接 cout<<strTwo<<endl; strTwo.reserve(50); //设置字符串存储大小 cout<<strTwo.capacity()<<endl; //查看字符串的存储能力 strTwo.clear(); //清空字符串 if (strTwo.empty()) { cout<<"strTwo is empty"<<endl; } for (int i = 0 ; i < strOne.length();++i) { cout<<strOne.at(i)<<endl; //按元素访问字符串 } strOne.append("I Love You!");//strOne尾部插入字符串 cout<<strOne.c_str()<<endl; strOne.append(10,'M'); //strOne尾部插入10个M cout<<strOne.c_str()<<endl; strOne.append("SSSSSSSSSSSSSSS",6); cout<<strOne.c_str()<<endl; strOne.append("I Love Asuna!",7,5); cout<<strOne.c_str()<<endl; strOne.push_back('T'); //从尾部一次只能插入一个元素 cout<<strOne.c_str()<<endl; strOne.assign(10,'T'); //分配元素 cout<<strOne.c_str()<<endl; strOne.assign("I Love misaka!"); cout<<strOne.c_str()<<endl; strOne.assign("I Love Hina!",6); cout<<strOne.c_str()<<endl; string strThree("I Asuna!"); cout<<strThree.c_str()<<endl; strThree.insert(strThree.begin()+2,3,'H');//插入元素 cout<<strThree.c_str()<<endl; strThree.insert(strThree.begin()+2,'H'); cout<<strThree.c_str()<<endl; strThree.assign("I Asuna!"); strThree.insert(2,1,'H'); cout<<strThree.c_str()<<endl; strThree.assign("I Asuna!"); strThree.insert(2,"Love"); cout<<strThree.c_str()<<endl; strThree.assign("I Asuna!"); strThree.insert(2,"Kiss and Love",4); cout<<strThree.c_str()<<endl; strThree.erase(strThree.begin()+7); cout<<strThree.c_str()<<endl; strThree.erase(7,4); cout<<strThree.c_str()<<endl; strThree.erase(2); cout<<strThree.c_str()<<endl; strThree.assign("I Love Asuna!"); //replace替代 strThree.replace(strThree.begin()+7,strThree.end()-1,"Misaka",6); cout<<strThree.c_str()<<endl; strThree.replace(strThree.begin()+7,strThree.end()-1,"黑雪姬"); cout<<strThree.c_str()<<endl; strThree.replace(7,5,5,'H'); cout<<strThree.c_str()<<endl; string strFour("I Love Hina!"); strFour.swap(strThree); //循环测试一个字符串是不是一个数字 while (true) { cout<<"--------判断一个字符串是不是一个数字-----------"<<endl; cout<<"----------请输入一个字符串---------------------"<<endl; string strFive; getline(cin,strFive); if (IsStringNum(strFive)) { cout<<"----------strFive是一个数字----------"<<endl; } else { cout<<"----------strFive不是一个数字--------"<<endl; } } cin.get(); cin.get(); return 0; } //判断一个字符串是不是一个数字 bool IsStringNum(string strNum) { for (string::iterator iter = strNum.begin();iter != strNum.end(); ++iter) { //判断首字符是不是正负号 if ((iter == strNum.begin()) && ((*iter == '+')||(*iter == '-'))) { continue; } //判断字符串中是不是数字或者小数点 if (!isdigit(*iter) && *iter != '.') { return false; } } //判断小数点是不是只有一个,并且收尾都不是小数点 if ((strNum.find('.')!= strNum.rfind('.')) || (strNum.front() == '.') || (strNum.back() == '.')) { return false; } return true; }2.string与wstring之间的关系
①string与wstring的区别
string是对char*的管理,一个字符只占一个字节大小。一个汉字占两个字节,ASCII编码。
wstring是对wchar_t*的管理,一个字符占两个字节大小,一个汉字占两个字节,Unicode编码。
wstring的使用方法跟string类似,区别主要在于函数参数char*与函数参数wchar_t*
②string与wstring的转换
第一种方法:
调用Windows的API函数:WideCharToMultiByte()函数和MultiByteToWideChar()函数。
第二种方法:
使用ATL的CA2W类与CW2A类。或使用A2W宏与W2A宏。
第三种方法:
跨平台的方法,使用CRT库的mbstowcs()函数和wcstombs()函数,需设定locale。
#include <string> #include <locale.h> using namespace std; //wstring转成string string ws2s(const wstring &ws) { string curLocale = setlocale(LC_ALL,NULL); //curLocale="C"; setlocale(LC_ALL,"chs"); const wchar_t * _Source=ws.c_str(); size_t _Dsize=2*ws.size()+1; char * _Dest = new char[_Dsize]; memset(_Dest,0,_Dsize); wcstombs(_Dest,_Source,_Dsize); string result = _Dest; delete[] _Dest; setlocale(LC_ALL,curLocale.c_str()); return result; } //string转成wstring wstring s2ws(const string &s) { string curLocale = setlocale(LC_ALL,NULL); //curLocale = "C" setlocale(LC_ALL, "chs"); const char *_Source = s.c_str(); size_t _Dsize = s.size()+1; wchar_t *_Dest = new wchar_t[_Dsize]; wmemset(_Dest,0,_Dsize); mbstowcs(_Dest,_Source,_Dsize); wstring result = _Dest; delete[] _Dest; setlocale(LC_ALL, curLocale.c_str()); return result; }
③编码统一化,编写单一源代码
如果我们想建立两个版本的程序,一个处理ASCII字符串,另一个处理Unicode字符串,最好的解决办法是编写出既能按ASCII编译又能按Unicode编译的单一源代码。
把以下代码加入到程序中,只要修改一个宏就能满足我们的要求。
#ifdef _UNICODE typedef wstring tstring; typedef wchar_t tchar; #define _T(x) L ## x #else typedef string tstring; typedef char tchar; #define _T(x) x #endif
3.string类中data()和c_str()的区别
偶尔看到这两个成员函数,有点奇怪,为什么给了两个相近函数,一定是有差别的。查了一下,结果如下:
定义:
const value_type *c_str( ) const;
const value_type *data( ) const;
1. c_str()返回的相当与const char * ,而data()返回的是数组;
2.c_str()返回的字符串带有”\0″, data()的数组没有;
3.c_str()返回的长度应该是整个长度, 而data()返回的是不含结束符的长度, 当然,如果用size()和length()求是一样的。
4. c_str()返回的是一个安全C标准串,data()返回的内容中可能没有traits::eos(), 但实际测试,发现data()没有无结束符的,但据说不是所有的stl都这样支持。
摘抄了其他人总结的一些相关内容,感觉挺有用的。
// c_str()源码,比较奇怪那个terminate()这不是异常的最终处理吗,难道是检测了异常??
———————————————————————————————
const charT* c_str () const
{
if (length () == 0)
return “”;
terminate ();
return data ();
}
原来c_str()的流程是:先调用terminate(),然后在返回data()。因此如果你对效率要求比较高,而且你的处理又不一定需要以\0的方式结束,你最好选择data()。但是对于一般的C函数中,需要以const char*为输入参数,你就要使用c_str()函数。
对于c_str() data()函数,返回的数组都是由string本身拥有,千万不可修改其内容。其原因是许多string实现的时候采用了引用机制,也就是说,有可能几个string使用同一个字符存储空间。而且你不能使用sizeof(string)来查看其大小。详细的解释和实现查看Effective STL的条款15:小心string实现的多样性。
另外在你的程序中,只在需要时才使用c_str()或者data()得到字符串,每调用一次,下次再使用就会失效,如:
string strinfo(“this is Winter”);
…
//最好的方式是:
foo(strinfo.c_str());
//也可以这么用:
const char* pstr=strinfo.c_str();
foo(pstr);
//不要再使用了pstr了, 下面的操作已经使pstr无效了。
strinfo += ” Hello!”;
foo(pstr);//错误!
会遇到什么错误?当你幸运的时候pstr可能只是指向”this is Winter Hello!”的字符串,如果不幸运,就会导致程序出现其他问题,总会有一些不可遇见的错误。总之不会是你预期的那个结果。
相关文章推荐
- c++使用 STL string 实现split,trim和replace方法
- 【学习笔记】《STL使用入门教程》第一讲:STL的string类型的使用方法
- STL string使用方法
- STL:string常用函数方法使用介绍
- JAVA String.format 方法使用介绍
- qs.parse()、qs.stringify()、JSON.parse()、JSON.stringify()使用方法
- (第三季)101-字符串类string基础使用102-字符串类string更多的方法103-字符串类StringBuilder的构造 104-string和StringBuilder的区别105-St
- JSON.parse()和JSON.stringify的介绍和使用方法
- memmove(),memcopy(),memset()对std::string的影响,以及它们在c/c++中正确的使用方法。
- [Zlib]_[初级]_[使用zlib库压缩和解压字符串STL string]
- C++ STL--stack/queue 的使用方法
- C++ stringstream介绍,使用方法与例子
- NSMutableAttributedString 的使用方法,设置格式
- String.Format使用方法
- node.js中的querystring.parse方法使用说明
- C++STL map介绍与使用方法
- System.String.Split的几种使用方法
- STL:使用string、vector、complex和limits
- C++ stringstream介绍,使用方法与例子
- c++ switch/case 使用 string的方法