strtol 指向原始字符串

问题描述

#include <cinttypes>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
uint64_t descendingOrder(uint64_t a)
{
   string str = to_string(a);
   sort(str.begin(),str.end(),[](unsigned char a,unsigned char b) { return a>b;}); 

   cout<<"sorted string:" <<str<<endl;
   cout<<"value        :"<<strtol(str.c_str(),nullptr,10)<<endl;
   return strtol(str.c_str(),10);
}

int main()
{
  descendingOrder(9223372036854775807L);
}

sorted string:9887777655433322200
value        :9223372036854775807

为什么 sorted string:value: 不同?即使在排序之后,似乎 value: 也以某种方式获取了原始字符串。错误在哪里?是UB吗?

代码Online code

解决方法

9887777655433322200 超出您架构上的 long 范围。

这就是为什么将 errno 设置为 ERANGE 并返回 LONG_MAX(恰好是您的输入)的原因。请注意,实现还可以使用 LLONG_MINLLONG_MIN 甚至 LONG_MIN。您需要检查 errno 以了解 strtol 的转换是否有效。

如果您使用 std::stol,您最终会得到 std::out_of_range 异常。是否要使用异常取决于您,但同时,对 unsigned long long 使用 std::strtoull(并检查 errno)或使用 std::stoull(并记住可能的异常).

有关详细信息,请参阅 C++ 标准中的 [string.conversions] 或上面指向 cppreference.com 的链接。