STL第一章-string的使用方法

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!”的字符串,如果不幸运,就会导致程序出现其他问题,总会有一些不可遇见的错误。总之不会是你预期的那个结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值