现在的位置: 首页 > 综合 > 正文

C++数值与字符串相互转换的那些事(一)字符串转数值(转载请注明)

2013年12月08日 ⁄ 综合 ⁄ 共 3977字 ⁄ 字号 评论关闭

以前一门心思搞算法,这个东西觉得自己写个函数就能实现的事,但是到了公司后才发现同事写的代码里面,调用各种库函数、window API、流来实现。什么都不懂的我表示鸭梨很大,今天翻了翻资料了解了下各种方法的使用方法、区别以及适用范围,写成了这篇又长又臭又没条理的东西。

注:以下字符串均特指空终止的字符串(字符串以'\0‘(一个字节的0)结束,宽字符串(本文中指UTF-8不涉及UTF-16及其他)以‘\0’(两个字节的0))

1.字符串转换为数值

1.1使用现成c库函数将10进制字符串转换为数值(c库函数不提供其他进制转换

所属头文件<cstdlib>

atoi()、_wtoi()、atol()、_wtol()、atof()、_wtol()、_atoi64()、_wtoi64(),_w打头为相应宽字符版本不逐一介绍。

atoi()函数原型如下,将字符串转换为int类型

int   atoi(   const   char   *string);

_wtoi()函数原型如下,将宽字符串转换为int类型

int _wtoi(const wchar_t *);

atol()函数原型如下,将字符串转化为long

 long  atol(const char *);

atof()函数原型如下,将字符串转化为doulbe

double atof(const char *);

_atoi64()函数原型如下,将字符串转化为__int64(long long int)

__int64 _atoi64(const char *);

例如:

#include <windows.h>
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
	
	char szBuff[100]="1000.2121";
	int iTest = 0;
	double dTest = 0.0;
	long lTest = 0;
	__int64 i64Test = 0;
	iTest = atoi(szBuff);
	dTest = atof(szBuff);
	lTest = atol(szBuff);
	i64Test = _atoi64(szBuff);
        printf("iTest = %d\n",iTest);
	printf("lTest = %ld\n",lTest);
	printf("dTest = %lf\n",dTest);
	printf("i64Test = %I64d\n",i64Test);
	return 0;
}

输出结果:

iTest = 1000
lTest = 1000
dTest = 1000.212100
i64Test = 1000

1.2使用现成Windows API将字符串转换为数值(Windows API 不提供浮点类型的转换,不支持64位整数

1.2.1使用现成Windows API将10进制字符串转换为数值

所属头文件<shlwapi.h>

注:使用时注意引入"shlwapi.lib"

 StrToInt()(Widows一个兼容的函数,当定义了UNICODE时表示StrToIntW,否则表示StrToIntA,以下不一一列举)、StrToLong

 StrToInt()函数原型如下,将字符串转换为int(以下均一ANSI字符串为例,UNICODE不再列举)

int    StrToIntA(LPCSTR lpSrc);

StrToLong()函数原型如下,将字符串转换为long(其实Windows 32位机器int和long没区别)

#define StrToLong               StrToInt

1.2.1使用现成Windows API将10或者16进制字符串转换为数值(不支持浮点类型,不支持64位整数

所属头文件<shlwapi.h>

注:使用时注意引入"shlwapi.lib"

StrToIntEx。(注:无StrToLongEx

StrToIntEx函数原型如下,将任意进制字符串转换为int类型,转换成功返回TRUE,否则为FALSE

BOOL    StrToIntExA(LPCSTR pszString, DWORD dwFlags, int FAR * piRet);

第一个参数表示待转换的字符串,第二个字符串用来表示待转换的字符串是16进制还是10进制,当dwFlags为STIF_DEFAULT表示10进制,当dwFlags为

STIF_SUPPORT_HEX时表示10进制。第三个参数代表一个指向int的指针(指向转换后的值)

例如:

#include <windows.h>
#include <iostream>
#include <cstdlib>
#include <shlwapi.h>
using namespace std;

#pragma comment(lib,"shlwapi.lib")

int main()
{
	
	int   value;
	char szHex[100] = "0xFF";
        StrToIntExA(szHex,STIF_SUPPORT_HEX,&value);
	printf("%d\n",value);
	return 0;
}

输出结果为:

255

1.3使用流将字符串转换为数值(64位流操作不支持,支持10进制,16进制,8进制)以ANSI为例

所属头文件<sstream>

预定义以下宏

#define MY_OCT 1  //8进制
#define MY_DEC 2  //10进制
#define MY_HEX 3 //16进制

通过自定义函数来说明:myStrToIntExA()、myStrToLongExA()、myStrToDoubleA()。(double类型仅支持10进制

myStrToIntExA()函数如下,将字符串转int

int myStrToIntExA(char *s,const int &iFlags = MY_DEC)
{   
	int num;
	stringstream ss(s);
	switch (iFlags)
	{
	case MY_OCT:
		ss>>std::oct>>num;//8进制
		break;
	case MY_DEC:
		ss>>std::dec>>num;//10
		break;
	case MY_HEX:
		ss>>std::hex>>num;
		break;
	default:
		break;
	}
	return num;
}

myStrToLongExA()函数如下,将字符串转long

long myStrToLongExA(char *s,const int &iFlags = MY_DEC)
{
	long num;
	stringstream ss(s);
	switch (iFlags)
	{
	case MY_OCT:
		ss>>std::oct>>num;//8进制
		break;
	case MY_DEC:
		ss>>std::dec>>num;//10
		break;
	case MY_HEX:
		ss>>std::hex>>num;
		break;
	default:
		break;
	}
	return num;
}

myStrToDoubleA()函数如下,将字符串转double

double myStrToDoulbeA(char *s)
{   
	double num;
	stringstream ss(s);
	ss>>num;
	return num;
}

例如:

#include <sstream>
#include <iostream>
using namespace std;
#define MY_OCT 1  //8进制
#define MY_DEC 2  //10进制
#define MY_HEX 3 //16进制

int myStrToIntExA(char *s,const int &iFlags = MY_DEC)
{   
	int num;
	stringstream ss(s);
	switch (iFlags)
	{
	case MY_OCT:
		ss>>std::oct>>num;//8进制
		break;
	case MY_DEC:
		ss>>std::dec>>num;//10
		break;
	case MY_HEX:
		ss>>std::hex>>num;
		break;
	default:
		break;
	}
	return num;
}
double myStrToDoulbeA(char *s)
{   
	double num;
	stringstream ss(s);
	ss>>num;
	return num;
}
long myStrToLongExA(char *s,const int &iFlags = MY_DEC)
{
	long num;
	stringstream ss(s);
	switch (iFlags)
	{
	case MY_OCT:
		ss>>std::oct>>num;//8进制
		break;
	case MY_DEC:
		ss>>std::dec>>num;//10
		break;
	case MY_HEX:
		ss>>std::hex>>num;
		break;
	default:
		break;
	}
	return num;
}

int main()
{
         char str[] = "11";  
	 int  iTest = myStrToIntExA(str,MY_HEX);
	 long lTest = myStrToLongExA(str,MY_HEX);
	 double dTest = myStrToDoulbeA(str);
         printf("%d\n",iTest);
	 printf("%ld\n",lTest);
	 printf("%lf\n",dTest);
	 return 0;
}

输出结果:

17
17
11.000000

3种方法的优劣如下表所示

  64位整数 浮点数 2进制 宽字符 8进制 10进制 16进制 特点
库函数 支持 支持 不支持 支持 不支持 支持 不支持 效率高
windows API 不支持 不支持 不支持 支持 不支持 支持 支持 效率较高
不支持 仅支持10进制 不支持 支持 支持 支持 支持 效率较低

总体来说

库函数唯一支持64位整数,效率高,

windows API 兼容性好,效率较高

流 支持进制多且支持10进制浮点转换,但是效率不高。

如果想支持非10进制的64位整数和浮点数,只能乖乖自己实现了,建议用第一种方式进行进制转换就OK了









 
      





 



抱歉!评论已关闭.