1.一些常用的使用方法,我还是觉得自己用代码打出来更适合自己的记忆。所以再简单的程序我都是要码字,调试的。
在下面的程序中,我列举了几乎所有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!”的字符串,如果不幸运,就会导致程序出现其他问题,总会有一些不可遇见的错误。总之不会是你预期的那个结果。