工具类库系列(一)-StringTool

好久没写了,最近闲了下来,把这段时间的代码整理整理,将常用的代码按功能整理成一些静态库,便于以后复用


今天是第一个库:libtool,其实就是一些工具类的集合


第一个工具类:StringTool


std::string已经很强大了,但是在实际项目中,还是会遇到一些需求,需要用string提供的接口组装一些字符串相关的功能,整理如下


(PS,本系列所有代码,均不同程度的需要boost库支持,本人使用的是boost1.55.0)


1:将一个字符串的首字母大写

这个功能很简单的,就是如果第一个字符'a' - 'z' 则换成 ‘A' - 'Z'


2:去除字符串中的所有制表符:空格,'\t','\r','\n'

这里就是遍历字符串,将相应的字符过滤掉

主要用于读文件之后的初步处理


3:将字符串中所有的字符串A替换成字符串B

这里用到string的find,查找字符串A的位置

仅遍历一遍,已处理过的部分不再处理,即如果字符串“1222”,需要将 “12”替换成“1”,则结果是“122”,不是“1”

该函数目前大部分情况还是用在文件路径中的windows下的"\\"替换成windows/linux兼容的“/”


补充增加 正则表达式替换:

这里用到了一个boost库提供的功能:boost::regex正则表达式regex_replace


4:将字符串按指定分隔符进行分割,分隔符可以是一个字符串

同上,分割后的结果存成一个std::vector返回


5:判断字符串是否是一个合法的数字:int,uint,float

这里用到了一个boost库提供的功能:boost::regex正则表达式regex_match


6:判断字符串是否是合法的Utf8编码

也是遍历,按Utf8的编码规则校验


7:Unicode和Utf8互转

这里仅处理了UCS-2,也是按Utf8的编码规则去压缩/解压缩


8:单宽字节互转

为了windows和linux的兼容,这里用的是mbstowcs/wcstombs


9:Gbk和Utf8互转

有了7和8,这个就是上两项功能的组合 Gbk <-> Unicode <-> Utf8


2017/1/9 修正Utf8ToGbk/GbkToUtf8分别在windows/linux下不同的locale设置


2017/12/6 修正Utf8ToUnicode中下标越界的bug

2017/12/6 增加字符串转时间戳的功能


最后上代码

StringTool.h

#ifndef __StringTool_h__
#define __StringTool_h__

#include <string>
#include <vector>

namespace common{
	namespace tool{

		class StringTool
		{
		public:
			// 字符串首字母大写
			static std::string UpperCaseFirstChar(const std::string& str);
			static std::string LowerCaseFirstChar(const std::string& str);

			// 字符串全字母大/小写
			static std::string UpperCase(const std::string& str);
			static std::string LowerCase(const std::string& str);

			// 去除字符串str中的所有制表符:' ','\t','\r','\n'
			static std::string TrimAll(const std::string& str);

			// 将字符串str中所有的字符串src替换成字符串des
			static std::string ReplaceAll(const std::string& str, const std::string& src, const std::string& des);
			// 将字符串str中所有符合src格式(正则表达式)的字符串替换成字符串des
			static std::string ReplaceReg(const std::string& str, const std::string& src, const std::string& des);

			// 对字符串按指定分隔符进行分割,返回分割后的内容列表
			static bool SplitStr2List(const std::string& str, const std::string& split, std::vector<std::string>& values);
			static bool SplitStr2List(const std::string& str, const std::string& split, std::vector<unsigned int>& values);
			static bool SplitStr2List(const std::string& str, const std::string& split, std::vector<int>& values);
			static bool SplitStr2List(const std::string& str, const std::string& split, std::vector<float>& values);
			
			// 判断字符串是否是一个合法的无符号数
			static bool IsUInt(const std::string& str);
			// 判断字符串是否是一个合法的数字
			static bool IsInt(const std::string& str);
			// 判断字符串是否是一个合法的浮点数
			static bool IsFloat(const std::string& str);
			// 判断字符串是否是一个符合“YYYY-MM-DD hh-mm-ss”格式的时间
			static bool IsDateTime(const std::string& str);
			// 判断字符串是否是一个符合“hh-mm(-ss)”格式的时间
			static bool IsTime(const std::string& str);
			// 判断字符串是否是一个符合“int-int”格式的区间范围
			static bool IsRang(const std::string& str);

			// 将符合“YYYY-MM-DD hh-mm-ss”格式的字符串转换成距离1970-1-1 00:00:00经过的秒数
			static bool String2DateTime(const std::string& str, time_t& datetime);
			// 将符合“hh-mm-ss”格式的字符串转换成距离当天00:00:00经过的秒数
			static bool String2Time(const std::string& str, time_t& time);
			// 将符合“int-int”格式的区间转换成区间的起始值 和 终止值
			static bool String2Rang(const std::string& str, int (&rang)[2]);

			// 返回一个字符串是否是合法的utf8编码
			static bool IsUtf8(const std::string& str);

			// Gbk和Utf8互转,返回转换后的字符串
			static std::string GbkToUtf8(const std::string& gbk);
			static std::string Utf8ToGbk(const std::string& utf8);

			// Unicode和Utf8互转,返回转换后的字符串
			static void UnicodeToUtf8(std::string& utf8, const std::wstring& unicode);
			static void Utf8ToUnicode(std::wstring& unicode, const std::string& utf8);

			// 单宽字节互转
#ifdef UNICODE
			static std::wstring MbStrToWcStr(const std::string& mbs, const wchar_t* language);
			static std::string WcStrToMbStr(const std::wstring& wcs, const wchar_t* language);
#else
			static std::wstring MbStrToWcStr(const std::string& mbs, const char* language);
			static std::string WcStrToMbStr(const std::wstring& wcs, const char* language);
#endif

		private:
			// Unicode和Utf8互转,获取转换后的字符数
			static size_t UnicodeToUtf8Length(const std::wstring& unicode);
			static size_t Utf8ToUnicodeLength(const std::string& utf8);
		};

	}
}

#endif


StringTool.cpp

#include "StringTool.h"

#include <string>
#include <vector>

#include <regex>

using namespace common::tool;

using namespace std;

string StringTool::UpperCaseFirstChar(const string& str)
{
	string temp = str;

	if (temp.length() > 0)
	{
		if ('a' <= temp[0] && temp[0] <= 'z')
		{
			temp[0] = temp[0] - ('a' - 'A');
		}
	}

	return temp;
}

string StringTool::LowerCaseFirstChar(const string& str)
{
	string temp = str;

	if (temp.length() > 0)
	{
		if ('A' <= temp[0] && temp[0] <= 'Z')
		{
			temp[0] = temp[0] + ('a' - 'A');
		}
	}

	return temp;
}

string StringTool::UpperCase(const string& str)
{
	string temp = str;

	for (unsigned int i = 0; i < temp.length(); i++)
	{
		if ('a' <= temp[i] && temp[i] <= 'z')
		{
			temp[i] = temp[i] - ('a' - 'A');
		}
	}

	return temp;
}

string StringTool::LowerCase(const string& str)
{
	string temp = str;

	for (unsigned int i = 0; i < temp.length(); i++)
	{
		if ('A' <= temp[i] && temp[i] <= 'Z')
		{
			temp[i] = temp[i] + ('a' - 'A');
		}
	}

	return temp;
}

string StringTool::TrimAll(const string& str)
{
	string temp;
	temp.reserve(str.size());

	for (size_t i = 0; i < str.length(); i++)
	{
		if (str[i] != ' ' &&
			str[i] != '\t' &&
			str[i] != '\r' &&
			str[i] != '\n')
		{
			temp += str[i];
		}
	}

	return temp;
}

string StringTool::ReplaceAll(const string& str, const string& src, const string& des)
{
	string temp;
	temp.reserve(str.size());

	if (0 < src.length())
	{
		size_t pos = str.find(src);
		size_t lastpos = 0;
		while (pos != string::npos)
		{
			temp += str.substr(lastpos, pos - lastpos);
			temp += des;
			lastpos = pos + src.length();
			pos = str.find(src, lastpos);
		}
		if (lastpos != str.length())
		{
			temp += str.substr(lastpos, str.length() - lastpos);
		}
	}

	return temp;
}

string StringTool::ReplaceReg(const string& str, const string& src, const string& des)
{
	regex reg(src);
	return regex_replace(str, reg, des);
}

bool StringTool::SplitStr2List(const string& str, const string& split, vector<string>& values)
{
	size_t currPos = str.find(split);
	size_t lastPos = 0;
	while (currPos != string::npos)
	{
		values.push_back(str.substr(lastPos, currPos - lastPos));
		lastPos = currPos + split.length();
		currPos = str.find(split, lastPos);
	}
	values.push_back(str.substr(lastPos, str.length() - lastPos));

	return true;
}

bool StringTool::SplitStr2List(const string& str, const string& split, vector<unsigned int>& values)
{
	string temp = str;
	TrimAll(temp);

	size_t currPos = temp.find(split);
	size_t lastPos = 0;
	while (currPos != string::npos)
	{
		string strUInt = temp.substr(lastPos, currPos - lastPos);
		if (IsUInt(strUInt))
		{
			values.push_back(static_cast<unsigned int>(atoi(strUInt.c_str())));
		}
		else
		{
			return false;
		}
		lastPos = currPos + split.length();
		currPos = temp.find(split, lastPos);
	}
	string strUInt = temp.substr(lastPos, temp.length() - lastPos);
	if (IsUInt(strUInt))
	{
		values.push_back(static_cast<unsigned int>(atoi(strUInt.c_str())));
	}
	else
	{
		return false;
	}

	return true;
}

bool StringTool::SplitStr2List(const string& str, const string& split, vector<int>& values)
{
	string temp = str;
	TrimAll(temp);

	size_t currPos = temp.find(split);
	size_t lastPos = 0;
	while (currPos != string::npos)
	{
		string strInt = temp.substr(lastPos, currPos - lastPos);
		if (IsInt(strInt))
		{
			values.push_back(atoi(strInt.c_str()));
		}
		else
		{
			return false;
		}
		lastPos = currPos + split.length();
		currPos = temp.find(split, lastPos);
	}
	string strInt = temp.substr(lastPos, temp.length() - lastPos);
	if (IsInt(strInt))
	{
		values.push_back(atoi(strInt.c_str()));
	}
	else
	{
		return false;
	}

	return true;
}

bool StringTool::SplitStr2List(const string& str, const string& split, vector<float>& values)
{
	string temp = str;
	TrimAll(temp);

	size_t currPos = temp.find(split);
	size_t lastPos = 0;
	while (currPos != string::npos)
	{
		string strFloat = temp.substr(lastPos, currPos - lastPos);
		if (IsFloat(strFloat))
		{
			values.push_back(static_cast<float>(atof(strFloat.c_str())));
		}
		else
		{
			return false;
		}
		lastPos = currPos + split.length();
		currPos = temp.find(split, lastPos);
	}
	string strFloat = temp.substr(lastPos, temp.length() - lastPos);
	if (IsFloat(strFloat))
	{
		values.push_back(static_cast<float>(atof(strFloat.c_str())));
	}
	else
	{
		return false;
	}

	return true;
}

bool StringTool::IsUInt(const string& str)
{
	regex reg("(0)|([1-9][0-9]*)"); // 0 或者 1-9开头后面若干个0-9的数字
	return regex_match(str, reg);
}

bool StringTool::IsInt(const string& str)
{
	regex reg("(0)|([-]?[1-9][0-9]*)"); // 0 或者 正负1-9开头后面若干个0-9的数字
	return regex_match(str, reg);
}

bool StringTool::IsFloat(const string& str)
{
	regex reg(
				"("
					"0([.]0+)?" // 0 后面跟 小数点 再跟若干个0(如果有小数点,则后面的数字字符串长度必须大于0)
				")"
				"|"
				"("
					"[-]?0[.][0-9]*[1-9][0-9]*" // 正负 0 后面跟 小数点 再跟一个不为0的数字字符串
				")"
				"|"
				"("
					"[-]?([1-9][0-9]*)([.][0-9]+)?" // 正负 1-9开头后面若干个0-9的数字 后面跟 小数点 再跟数字字符串(如果有小数点,则后面的数字字符串长度必须大于0)
				")"
			);
	return regex_match(str, reg);
}

bool StringTool::IsDateTime(const string& str)
{
	regex reg(
				"[1-9][0-9]?[0-9]?[0-9]?" // 年,1-9开头,后面最多3个0-9的数字
				"[-]"
				"("
					"(0?[1-9])|(1[0-2])" // 月,01 - 09(十位的0可以没有),10 - 12
				")"
				"[-]"
				"("
					"(0?[1-9])|([1-2][0-9])|(3[0-1])" // 日,01 - 09(十位的0可以没有),10 - 29,30 - 31 
				")"
				"[ ]"
				"("
					"([0-1]?[0-9])|(2[0-3])" // 时,00 - 19(十位的0可以没有), 20 - 23
				")"
				"[:]"
				"[0-5]?[0-9]" // 分, 00 - 59(十位的0可以没有)
				"[:]"
				"[0-5]?[0-9]" // 秒, 00 - 59(十位的0可以没有)
			);
	return regex_match(str, reg);
}

bool StringTool::IsTime(const string& str)
{
	regex reg(	
				"("
					"([0-1]?[0-9])|(2[0-3])" // 时,00 - 19(十位的0可以没有), 20 - 23
				")"
				"[:]"
				"[0-5]?[0-9]" // 分, 00 - 59(十位的0可以没有)
				"("
					"[:]"
					"[0-5]?[0-9]" // 秒(可以没有), 00 - 59(十位的0可以没有)
				")?"
			);
	return regex_match(str, reg);
}

bool StringTool::IsRang(const std::string& str)
{
	regex reg(
				"("
					"(0)|([-]?[1-9][0-9]*)" // 0 或者 正负1-9开头后面若干个0-9的数字
				")"
				"[-]"
				"("
					"(0)|([-]?[1-9][0-9]*)" // 0 或者 正负1-9开头后面若干个0-9的数字
				")");
	return regex_match(str, reg);
}

bool StringTool::String2DateTime(const std::string& str, time_t& datetime)
{
	tm _tm;
	int year = 1900, month = 1, day = 0, hour = 0, minute = 0, second = 0;
	int ret = sscanf(str.c_str(), "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);
	if (ret != 6)
	{
		return false;
	}
	_tm.tm_year = year - 1900;
	_tm.tm_mon = month - 1;
	_tm.tm_mday = day;
	_tm.tm_hour = hour;
	_tm.tm_min = minute;
	_tm.tm_sec = second;
	_tm.tm_isdst = 0;
	datetime = mktime(&_tm);
	return true;
}

bool StringTool::String2Time(const std::string& str, time_t& time)
{
	int hour = 0, minute = 0, second = 0;
	int ret = sscanf(str.c_str(), "%d:%d:%d", &hour, &minute, &second);
	if (ret != 2 && ret != 3)
	{
		return false;
	}
	time = hour * 60 * 60 + minute * 60 + second;
	return true;
}

bool StringTool::String2Rang(const std::string& str, int(&rang)[2])
{
	int ret = sscanf(str.c_str(), "%d-%d", &(rang[0]), &(rang[1]));
	if (ret != 2)
	{
		return false;
	}
	return true;
}

bool StringTool::IsUtf8(const string& str)
{
	unsigned int nBytes = 0;
	bool bAllAscii = true;

	for (size_t i = 0; i < str.length(); i++)
	{
		unsigned char ch = str[i];

		// 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII一个字节用7位编码,最高位标记为0,0xxxxxxx
		if ((ch & 0x80) != 0)
		{
			bAllAscii = false;
		}

		// 如果不是ASCII码,计算字节数(校验是否符合UTF8规则)
		if (nBytes == 0)
		{
			if (ch >= 0x80)
			{
				if (ch >= 0xFC && ch <= 0xFD)
				{
					nBytes = 6;
				}
				else if (ch >= 0xF8)
				{
					nBytes = 5;
				}
				else if (ch >= 0xF0)
				{
					nBytes = 4;
				}
				else if (ch >= 0xE0)
				{
					nBytes = 3;
				}
				else if (ch >= 0xC0)
				{
					nBytes = 2;
				}
				else
				{
					return false;
				}
				nBytes--;
			}
		}
		// 多字节符的非首字节,应为10xxxxxx
		else
		{
			if ((ch & 0xC0) != 0x80)
			{
				return false;
			}
			nBytes--;
		}
	}

	if (nBytes > 0)
	{
		return false;
	}

	// 如果全部都是ASCII, 说明不是UTF-8
	if (bAllAscii)
	{
		return false;
	}

	return true;
}

string StringTool::GbkToUtf8(const string& gbk)
{
#ifdef WIN32
#ifdef UNICODE
	wstring unicode = MbStrToWcStr(gbk, L"chs");
#else // UNICODE
	wstring unicode = MbStrToWcStr(gbk, "chs");
#endif // UNICODE
#else // WIN32
#ifdef UNICODE
	wstring unicode = MbStrToWcStr(gbk, L"zh_CN.GB18030");
#else // UNICODE
	wstring unicode = MbStrToWcStr(gbk, "zh_CN.GB18030");
#endif // UNICODE
#endif // WIN32

	string utf8;
	UnicodeToUtf8(utf8, unicode);

	return utf8;
}

string StringTool::Utf8ToGbk(const string& utf8)
{
	wstring unicode;
	Utf8ToUnicode(unicode, utf8);

#ifdef WIN32
#ifdef UNICODE
	string gbk = WcStrToMbStr(unicode, L"chs");
#else // UNICODE
	string gbk = WcStrToMbStr(unicode, "chs");
#endif // UNICODE
#else // WIN32
#ifdef UNICODE
	string gbk = WcStrToMbStr(unicode, L"zh_CN.GB18030");
#else // UNICODE
	string gbk = WcStrToMbStr(unicode, "zh_CN.GB18030");
#endif // UNICODE
#endif // WIN32

	return gbk;
}

void StringTool::UnicodeToUtf8(string& utf8, const wstring& unicode)
{
	size_t mbLen = UnicodeToUtf8Length(unicode) + 1;
	if (1 < mbLen)
	{
		utf8.resize(mbLen);

		size_t utf8Pos = 0;
		size_t unicodePos = 0;

		size_t unicodeLen = unicode.length();
		while (unicodePos < unicodeLen)
		{
			unsigned short unicodeCh = unicode[unicodePos];

			// 0x0800 - 0xffff => 1110 XXXX, 10XX XXXX, 10XX XXXX
			if (0x0800 <= unicodeCh)
			{
				utf8[utf8Pos + 0] = ((unicodeCh >> 12) & 0x0F) | 0xE0;
				utf8[utf8Pos + 1] = ((unicodeCh >> 6) & 0x3F) | 0x80;
				utf8[utf8Pos + 2] = (unicodeCh & 0x3F) | 0x80;

				unicodePos += 1;
				utf8Pos += 3;
			}
			// 0x0080 - 0x07ff => 110X XXXX, 10XX XXXX
			else if (0x0080 <= unicodeCh && unicodeCh < 0x07FF)
			{
				utf8[utf8Pos + 0] = ((unicodeCh >> 6) & 0x1F) | 0xC0;
				utf8[utf8Pos + 1] = (unicodeCh & 0x3F) | 0x80;

				unicodePos += 1;
				utf8Pos += 2;
			}
			// unicodeCh < 0x0080 // 0x0000 - 0x007f => 0XXX XXXX
			else
			{
				utf8[utf8Pos + 0] = unicodeCh & 0x7F;

				unicodePos += 1;
				utf8Pos += 1;
			}
		}

		utf8[utf8Pos] = 0;
	}
}

void StringTool::Utf8ToUnicode(wstring& unicode, const string& utf8)
{
	size_t wcLen = Utf8ToUnicodeLength(utf8) + 1;
	if (1 < wcLen)
	{
		unicode.resize(wcLen);

		size_t utf8Pos = 0;
		size_t unicodePos = 0;

		size_t utf8Len = utf8.length();
		while (utf8Pos < utf8Len)
		{
			unsigned short utfCh0 = utf8[utf8Pos + 0] & 0xFF;

			// 1111 110X, 10XX XXXX, 10XX XXXX, 10XX XXXX, 10XX XXXX, 10XX XXXX
			// 1111 10XX, 10XX XXXX, 10XX XXXX, 10XX XXXX, 10XX XXXX
			// 1111 0XXX, 10XX XXXX, 10XX XXXX, 10XX XXXX 
			if (0xF0 <= utfCh0)
			{
				break; // 需要UCS-4,未处理
			}
			// 1110 XXXX, 10XX XXXX, 10XX XXXX
			else if (0xE0 <= utfCh0 && utfCh0 < 0xF0)
			{
				unsigned short utfCh1 = utf8[utf8Pos + 1] & 0xFF;
				unsigned short utfCh2 = utf8[utf8Pos + 2] & 0xFF;
				unicode[unicodePos] = ((((utfCh0 << 4) & 0xF0) + ((utfCh1 >> 2) & 0x0F)) << 8) + (((utfCh1 << 6) & 0xC0) + (utfCh2 & 0x3F));

				utf8Pos += 3;
				unicodePos += 1;
			}
			// 110X XXXX, 10XX XXXX
			else if (0xC0 <= utfCh0 && utfCh0 < 0xE0)
			{
				unsigned short utfCh1 = utf8[utf8Pos + 1] & 0xFF;
				unicode[unicodePos] = (((utfCh0 >> 2) & 0x07) << 8) + ((utfCh0 << 6) & 0xC0 + utfCh1 & 0x3F);

				utf8Pos += 2;
				unicodePos += 1;
			}
			// 10XX XXXX 
			else if (0x80 <= utfCh0 && utfCh0 < 0xC0)
			{
				break; // 非法情况,Utf8首字节不存在该种编码
			}
			// 0XXX XXXX
			else
			{
				unicode[unicodePos] = utfCh0;

				utf8Pos += 1;
				unicodePos += 1;
			}
		}

		unicode[unicodePos] = 0;
	}
}

size_t StringTool::UnicodeToUtf8Length(const wstring& unicode)
{
	size_t chars = 0;

	size_t unicodeLen = unicode.length();
	size_t unicodePos = 0;
	while (unicodePos < unicodeLen)
	{
		unsigned short unicodeCh = unicode[unicodePos];

		// 0x0800 - 0xffff => 1110 XXXX, 10XX XXXX, 10XX XXXX
		if (0x0800 <= unicodeCh)
		{
			unicodePos += 1;
			chars += 3;
		}
		// 0x0080 - 0x07ff => 110X XXXX, 10XX XXXX
		else if (0x0080 <= unicodeCh && unicodeCh < 0x07FF)
		{
			unicodePos += 1;
			chars += 2;
		}
		// unicodeCh < 0x0080 // 0x0000 - 0x007f => 0XXX XXXX
		else
		{
			unicodePos += 1;
			chars += 1;
		}
	}

	return chars;
}

size_t StringTool::Utf8ToUnicodeLength(const string& utf8)
{
	size_t wchars = 0;

	size_t utf8Len = utf8.length();
	size_t utf8Pos = 0;
	while (utf8Pos < utf8Len)
	{
		unsigned char utf8Ch = utf8[utf8Pos];

		// 1111 110X, 10XX XXXX, 10XX XXXX, 10XX XXXX, 10XX XXXX, 10XX XXXX
		// 1111 10XX, 10XX XXXX, 10XX XXXX, 10XX XXXX, 10XX XXXX
		// 1111 0XXX, 10XX XXXX, 10XX XXXX, 10XX XXXX 
		if (0xF0 <= utf8Ch)
		{
			return 0; // 需要UCS-4,未处理
		}
		// 1110 XXXX, 10XX XXXX, 10XX XXXX
		else if (0xE0 <= utf8Ch && utf8Ch < 0xF0)
		{
			utf8Pos += 3;
			wchars += 1;
		}
		// 110X XXXX, 10XX XXXX
		else if (0xC0 <= utf8Ch && utf8Ch < 0xE0)
		{
			utf8Pos += 2;
			wchars += 1;
		}
		// 10XX XXXX 
		else if (0x80 <= utf8Ch && utf8Ch < 0xC0)
		{
			return 0; // 非法情况,Utf8首字节不存在该种编码
		}
		// 0XXX XXXX
		else
		{
			utf8Pos += 1;
			wchars += 1;
		}
	}

	return wchars;
}

#ifdef UNICODE
wstring StringTool::MbStrToWcStr(const string& mbs, const wchar_t* language)
#else
wstring StringTool::MbStrToWcStr(const string& mbs, const char* language)
#endif
{
	wstring wcs;

#ifdef UNICODE
	wstring curLocale = _wsetlocale(LC_ALL, NULL);
	_wsetlocale(LC_ALL, language);
#else
	string curLocale = setlocale(LC_ALL, NULL);
	setlocale(LC_ALL, language);
#endif

	int wcLen = mbstowcs(NULL, mbs.c_str(), 0) + 1;
	if (1 < wcLen)
	{
		wchar_t* wcBuf = new wchar_t[wcLen];
		if (NULL != wcBuf)
		{
			wmemset(wcBuf, 0, wcLen);
			mbstowcs(wcBuf, mbs.c_str(), wcLen);
		}

		wcs = wcBuf;

		if (NULL != wcBuf)
		{
			delete[] wcBuf;
			wcBuf = NULL;
		}
	}

#ifdef UNICODE
	_wsetlocale(LC_ALL, curLocale.c_str());
#else
	setlocale(LC_ALL, curLocale.c_str());
#endif

	return wcs;
}

#ifdef UNICODE
string StringTool::WcStrToMbStr(const wstring& wcs, const wchar_t* language)
#else
string StringTool::WcStrToMbStr(const wstring& wcs, const char* language)
#endif
{
	string mbs;

#ifdef UNICODE
	wstring curLocale = _wsetlocale(LC_ALL, NULL);
	_wsetlocale(LC_ALL, language);
#else
	string curLocale = setlocale(LC_ALL, NULL);
	setlocale(LC_ALL, language);
#endif

	int mbLen = wcstombs(NULL, wcs.c_str(), 0) + 1;
	if (1 < mbLen)
	{
		char* mbBuf = new char[mbLen];
		if (NULL != mbBuf)
		{
			memset(mbBuf, 0, mbLen);
			wcstombs(mbBuf, wcs.c_str(), mbLen);
		}

		mbs = mbBuf;

		if (NULL != mbBuf)
		{
			delete[] mbBuf;
			mbBuf = NULL;
		}
	}

#ifdef UNICODE
	_wsetlocale(LC_ALL, curLocale.c_str());
#else
	setlocale(LC_ALL, curLocale.c_str());
#endif

	return mbs;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值