您的位置:首页 > 其它

STL第一章-string的使用方法

2014-03-01 21:57 369 查看
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!”的字符串,如果不幸运,就会导致程序出现其他问题,总会有一些不可遇见的错误。总之不会是你预期的那个结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息