您的位置:首页 > 编程语言 > C语言/C++

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

2011-12-16 14:45 465 查看
以前一门心思搞算法,这个东西觉得自己写个函数就能实现的事,但是到了公司后才发现同事写的代码里面,调用各种库函数、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[b]使用现成Windows API将10进制字符串转换为数值[/b]

所属头文件<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进制字符串转换为数值(不支持浮点类型,[b]不支持64位整数)[/b]

所属头文件<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了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: