在数字和字符串类型之间转换

在数字和字符串类型之间进行转换是无处不在的操作。在C ++ 11之前,几乎不支持将数字转换为字符串并转回,并且开发人员不得不主要诉诸于类型不安全的函数,并且通常编写自己的实用程序函数,以避免重复编写相同的代码。 使用C ++ 11,标准库提供了用于在数字和字符串之间进行转换的实用程序函数。 在本系列文章中,您将学习如何在数字和字符串之间进行转换,以及如何使用现代C ++标准函数进行另一种方法。

做好准备

此系列文章中提到的所有实用程序功能都可以在标准头文件中找到。

怎么做……

需要在数字和字符串之间进行转换时,请使用以下标准转换函数:

  • 要将整数或浮点类型转换为字符串类型,请使用std::to_string()或std::to_wstring(),如以下代码片段所示:
auto si = std::to_string(42);      // si="42" 
auto sl = std::to_string(42l);     // sl="42" 
auto su = std::to_string(42u);     // su="42" 
auto sd = std::to_wstring(42.0);   // sd=L"42.000000" 
auto sld = std::to_wstring(42.0l); // sld=L"42.000000"
  • 要将字符串类型转换为整数类型,请使用std::stoi(),std::stol(),std::stoll(),std::stoul()或std::stoull(); 请参考以下代码段:
auto i1 = std::stoi("42");                 // i1 = 42 
auto i2 = std::stoi("101010", nullptr, 2); // i2 = 42 
auto i3 = std::stoi("052", nullptr, 8);    // i3 = 42 
auto i4 = std::stoi("0x2A", nullptr, 16);  // i4 = 42
  • 要将字符串类型转换为浮点类型,请使用std::stof(),std::stod()或std::stold(),如以下代码片段所示:
// d1 = 123.45000000000000 
auto d1 = std::stod("123.45"); 
// d2 = 123.45000000000000 
auto d2 = std::stod("1.2345e+2"); 
// d3 = 123.44999980926514 
auto d3 = std::stod("0xF.6E6666p3");

这个如何起作用……

要将整数或浮点类型转换为字符串类型,可以使用std::to_string()或std::to_wstring()函数。这些函数在标准头文件中可以找到,并且对于有符号和无符号整数以及实数类型都有重载。当使用每种类型的适当格式说明符进行调用时,它们产生的结果与std::sprintf()和std::swprintf()产生的结果相同。以下代码片段列出了这两个函数的所有重载。

std::string to_string(int value); 
std::string to_string(long value); 
std::string to_string(long long value); 
std::string to_string(unsigned value); 
std::string to_string(unsigned long value); 
std::string to_string(unsigned long long value); 
std::string to_string(float value); 
std::string to_string(double value); 
std::string to_string(long double value); 
std::wstring to_wstring(int value); 
std::wstring to_wstring(long value); 
std::wstring to_wstring(long long value); 
std::wstring to_wstring(unsigned value); 
std::wstring to_wstring(unsigned long value); 
std::wstring to_wstring(unsigned long long value); 
std::wstring to_wstring(float value); 
std::wstring to_wstring(double value); 
std::wstring to_wstring(long double value);

进行反向转换时,有一整套函数的名称以ston(字符串到数字)的格式表示,其中n代表i(integer),l(long),ll(long long),ul (unsigned long)或ull(unsigned long long)。 下面的清单显示了所有这些函数,每个函数都有两个重载,一个重载std::string,另一个重载std::wstring作为第一个参数:

字符串到整数类型函数的工作方式是:丢弃非空格字符之前的所有空格,然后采用尽可能多的字符来形成有符号或无符号数字(取决于大小写),然后将其转换为请求的数字 整数类型(stoi()将返回整数,stoul()将返回无符号long,依此类推)。 在以下所有示例中,结果均为整数42,但最后一个示例的结果为-42:

auto i1 = std::stoi("42");             // i1 = 42 
auto i2 = std::stoi("   42");          // i2 = 42 
auto i3 = std::stoi("   42fortytwo");  // i3 = 42 
auto i4 = std::stoi("+42");            // i4 = 42 
auto i5 = std::stoi("-42");            // i5 = -42

有效的整数可以由以下部分组成:

  • 加号(+)或减号(-)(可选)。
  • 前缀0表示八进制(可选)。
  • 前缀0x或0X表示十六进制(可选)。
  • 一系列数字。

仅当指定的底数为8或0时才应用可选的前缀0(八进制)。类似地,仅当指定的底数是16或0时才应用可选的前缀0x或0X(对于十六进制)。

将字符串转换为整数的函数具有三个参数:

  • 输入字符串。
  • 一个指针,当不为null时,它将接收已处理的字符数,并且可以包括任何被丢弃的前导空白,符号和基数前缀,因此不应将其与整数值所具有的位数混淆 。
  • 表示底数的数字; 默认情况下是10。

输入字符串中的有效数字取决于底数。对于基数2,唯一的有效数字是0和1;对于基数5,有效数字是01234。对于基数11,有效数字是0-9和字符A和a。 对于技术36,有效字符为0-9、A-Z和a-z的基数36。

以下是字符串的更多示例,这些字符串具有将各种基数的数字转换为十进制整数。 同样,在所有情况下,结果均为42或-42:

auto i6 = std::stoi("052", nullptr, 8); 
auto i7 = std::stoi("052", nullptr, 0); 
auto i8 = std::stoi("0x2A", nullptr, 16); 
auto i9 = std::stoi("0x2A", nullptr, 0); 
auto i10 = std::stoi("101010", nullptr, 2); 
auto i11 = std::stoi("22", nullptr, 20); 
auto i12 = std::stoi("-22", nullptr, 20); 

auto pos = size_t{ 0 }; 
auto i13 = std::stoi("42", &pos);      // pos = 2 
auto i14 = std::stoi("-42", &pos);     // pos = 3 
auto i15 = std::stoi("  +42dec", &pos);// pos = 5

需要注意的重要一点是,如果转换失败,这些转换函数将抛出。 可以抛出两个异常:

  • std::invalid_argument:若转换无法执行:
try 
{ 
   auto i16 = std::stoi(""); 
} 
catch (std::exception const & e) 
{ 
   // prints "invalid stoi argument" 
   std::cout << e.what() << std::endl; 
}
  • std::out_of_range:如果转换后的值超出结果类型的范围(或者基础函数将errno设置为ERANGE):
try 
{ 
   // OK
   auto i17 = std::stoll("12345678901234");  
   // throws std::out_of_range 
   auto i18 = std::stoi("12345678901234"); 
} 
catch (std::exception const & e) 
{ 
   // prints "stoi argument out of range"
   std::cout << e.what() << std::endl; 
}

将字符串转换为浮点类型的另一组函数非常相似,只是它们没有数字基数的参数。有效的浮点值在输入字符串中可以具有不同的表示形式:

  • 十进制浮点表达式(可选符号,带可选点的十进制数字序列,可选e或E,后跟带有可选符号的指数)。
  • 二进制浮点表达式(可选符号,0x或0X前缀,带有可选点的十六进制数字序列,可选p或P,后跟带有可选符号的指数)。
  • 无限表达式(可选符号,后跟不区分大小写的INF或INFINITY)。
  • 非数字表达式(可选符号,后跟不区分大小写的NAN和其他字母数字字符)。

以下是将字符串转换为双精度型的各种示例:

auto d1 = std::stod("123.45");         // d1 =  123.45000000000000 
auto d2 = std::stod("+123.45");        // d2 =  123.45000000000000 
auto d3 = std::stod("-123.45");        // d3 = -123.45000000000000 
auto d4 = std::stod("  123.45");       // d4 =  123.45000000000000 
auto d5 = std::stod("  -123.45abc");   // d5 = -123.45000000000000 
auto d6 = std::stod("1.2345e+2");      // d6 =  123.45000000000000 
auto d7 = std::stod("0xF.6E6666p3");   // d7 =  123.44999980926514 

auto d8 = std::stod("INF");            // d8 = inf 
auto d9 = std::stod("-infinity");      // d9 = -inf 
auto d10 = std::stod("NAN");           // d10 = nan 
auto d11 = std::stod("-nanabc");       // d11 = -nan

前面以0xF.6E6666p3的形式看到的浮点以2为底的科学计数法不是本系列文章的主题。 但是,为清楚起见,提供了简短的描述。 不过,建议您查看其他参考资料以了解详细信息。 以2为底的科学计数法中的浮点常数由以下几部分组成:

  • 十六进制前缀0x。
  • 整数部分,在此示例中为F,十进制为15。
  • 小数部分,在此示例中为6E6666或二进制格式的011011100110011001100110。 要将其转换为十进制,我们需要添加以2位地的反幂:1/4 + 1/8 + 1/32 + 1/64 + 1/128 +…。
  • 后缀,代表2的幂; 在此示例中,p3表示以2为底3的幂。

十进制等效值是通过将有效位数(由整数和小数部分组成)与基数乘以指数幂来确定的。 对于给定的十六进制以2为底浮点表示法,有效位数为15.4312499 …(请注意,第七位之后的数字未显示),基数为2,指数为3。因此,结果为15.4212499 … * 8,即123.44999980926514。

参见

数值类型的限制和其他属性

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据