Skip to content

Instantly share code, notes, and snippets.

@weaponwang
Created July 9, 2020 07:46
Show Gist options
  • Save weaponwang/a84da8d3f415b884db6a64a29f0045be to your computer and use it in GitHub Desktop.
Save weaponwang/a84da8d3f415b884db6a64a29f0045be to your computer and use it in GitHub Desktop.
std::stoll() : very simple research

函数签名:

long long stoll (const string&  str, size_t* idx = 0, int base = 10);
// linux 环境下应该很少能用到
long long stoll (const wstring& str, size_t* idx = 0, int base = 10); 

功能:

根据指定base, 将str内容解释成 long long int

具体过程:

  1. 过滤str中的前导space
  2. 从第一个合法的字符(由base决定)开始,尽可能多的取出合法字符进行解释
  3. 将idx指向2中最后一个合法字符的下一个位置

参数说明:

  • str: 表示整数的一个 std::string 变量

  • idx: 如果传入的idx不空, 函数会把该指针指向 串中 已经解释为long long int的子串的后一个位置(后面例子更直观)

  • base: 指定串的解释方式(默认为10)

base 决定的解释规则如下:

1. base == 0: 怎么解释由 【串自己 】决定

串可以包括

【可选】+/- (正负号)

【可选】base前缀(0 => 八进制,0x或0X => 十六进制)

【必须】十进制数字串(如果没有base前缀的话), 八进制串(0开头),十六进制串(0x或0X开头)

2. base >=2 && base <= 36: 怎么解释由 【base】决定

串中可能有

【可选】+/- (正负号)

【可选(特殊)】如果base == 16,可以有前导0x或0X

【必须】对应base的任意字符

如 base == 36, 串中合法字符为 '0'==>'9', 'a' ==> 'z'(不区分大小写)

Code demo:

// stoll example
#include <iostream>   // std::cout
#include <string>     // std::string, std::stoll

int main ()
{
  std::string str = "8246821 0xffff 020";

  std::string::size_type sz = 0;   // alias of size_t

  while (!str.empty()) {
    long long ll = std::stoll (str,&sz,0);
    std::cout << str.substr(0,sz) << " interpreted as " << ll << '\n';
    str = str.substr(sz);
  }

  return 0;
}

Output:

8246821 interpreted as 8246821
0xffff interpreted as 65535
0x20 interpreted as 32

时间复杂度:

与串中字符数量线性相关

与std::strtoll()对比:

  1. 函数签名
long long int strtoll (const char* str, char** endptr, int base);
  1. 是否抛出异常:

    • std::strtoll() 不抛出异常, 如果str 不是C-string, 或endptr无效,导致未定义行为
    • std::stoll()
      • 如果没有实施转换,抛出 invalid_argument 异常
      • 转换后的值溢出long long int, 抛出 out_of_range 异常
      • 如果idx 无效,导致未定义行为
  2. 返回值

    • std::strtoll() ,

      • 转换成功,返回实际 long long 值;
    • 没有实施转换,返回0LL;

    • 溢出,返回LLONG_MAX or LLONG_MIN (defined in ), errno 设成 ERANGE

    • std::stoll()

      只在转换并且成功的时候返回转换后的值,否则抛异常

  3. 联系

    std::stoll() 底层调用 strtoll (or wcstoll) 做转换

结论:

std::stoll() 应该是对 std::strtoll() 做了一层封装

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment