Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5707852
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: C/C++

2006-10-12 21:46:19

转变一个字符串到数字类型

问题

我们有字符串格式的数字,但是我们需要转换它们到一个数值类型,比如intfloat

解决方案

有两种方法,使用标准库函数或者使用boost库的lexcial_cast类。标准库函数的实现方法是笨重和不安全的,但是它们是标准的,大多时候,我们还是需要他们,而lexical_cast是更安全,更简单并且更流行的。

函数strtolstrtodstrtoul在标准头文件中定义。转变一个空终结符字符串到long int,doubleunsigned long类型。你可以使用它们转换任意基数数字字符串到数值。下面的程序转变十六进制数字字符串到long类型。

Example 3-1. Converting number strings to numbers

#include

#include

#include

using namespace std;

long hex2int(const string& hexStr) {

   char *offset;

   if (hexStr.length( ) > 2) {

      if (hexStr[0] == '0' && hexStr[1] == 'x') {

//字符串以“0x”开头,第三个参数为0

         return strtol(hexStr.c_str( ), &offset, 0);      }

   }

//如果字符串不以“0x”开头,第三个参数为16

   return strtol(hexStr.c_str( ), &offset, 16); }

int main( ) {

   string str1 = "0x12AB";

   cout << hex2int(str1) << endl;

   string str2 = "12AB";

   cout << hex2int(str2) << endl;

   string str3 = "QAFG";

   cout << hex2int(str3) << endl;

}

程序的输出:

4779

4779

0

头两个字符串都包含十六进制数字12AB。其中,第一个又包含0x前缀,而第二个没有。第三个字符串不包含有效的十六进制数字;函数只是简单的返回0

讨论

一些人可能倾向于写他们自己的十六进制数字转换为整数的函数。为什么要重复发明轮子呢?标准库已经提供了这个功能函数。提供了一个简单的strtol函数的封装。strtol函数其实是从老的C库函数中来的,她需要你提供一个终结符符字符串指针,和另一个字符的指针;这个后面的字符提供一个终结字符。然而在C++人们更倾向于使用更强大的String类。因而,这个hex2int函数使用了string类作为参数。

strtol函数允许使用两种方式指定基数16;你可以输入16作为这个函数的第三个参数,或者你可以传入0当你的字符串包含0x(就像你在代码中指定十六进制一样)。

程序 允许使用另一种方法。如果你输入的字符串类似0x12AB,函数将侦测到0x然后以正确的方式以0作为第三参数调用strtol。否则函数以16作为第三个参数。

strtolstrtoul的工作方式是一样的;只是返回类型不通。strtod更简单,没有第三个参数指定基数。

这些老的C函数不是转换字符串到数字的唯一方法。Boost项目还提供了一个lexical_cast类来完成相同的任务将字符串转换成以十为基的数字。例子显示了他们是如何工作的。

Example 3-2. Using lexical_cast

#include

#include

#include

using namespace std;

int main( ) {

   string str1 = "750";

   string str2 = "2.71";

   string str3 = "0x7FFF";

   try {

      cout << boost::lexical_cast(str1) << endl;

      cout << boost::lexical_cast(str2) << endl;

      cout << boost::lexical_cast(str3) << endl;

   }

   catch (boost::bad_lexical_cast& e) {

      cerr << "Bad cast: " << e.what( ) << endl;

   }

}

的输出如下:

750

2.71

Bad cast: bad lexical cast: source type value could not be interpreted as target

我们能看到最后一个值str3引发了一个异常,它是一个十六进制数。如果你不得不转换十进制以外的数,那么你就不得不使用函数strtol

strtol函数还有宽字符版本。那个函数是wcstol,在头文件中声明。与函数strtodstrtoul对应的宽字符版本的函数是wcstodwcstoul。这些函数的使用完全一样,只是将窄字符char* 换成了宽字符wchar_t* 作为函数的参数。

阅读(3325) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~