C++ std::stoi 详解:轻松搞懂字符串转整数

在 C++ 标准库中,std::stoi 是一个常用的字符串转换函数,它能够将 std::stringstd::wstring 转换为 int 类型的整数。尽管我们经常使用 std::stoi,但它的内部实现往往被忽略。本文将从使用方法、异常处理到源码解析,深入剖析 std::stoi,帮助你更好地理解它的工作原理。


1. std::stoi 的基本介绍

std::stoi 定义在 <string> 头文件中,并位于 std 命名空间下。它的主要功能是将字符串转换为 int 类型的整数,并且支持不同进制的转换(如二进制、十进制、十六进制等)。

1.1 std::stoi 的函数原型

int stoi(const std::string& str, size_t* pos = nullptr, int base = 10);
int stoi(const std::wstring& str, size_t* pos = nullptr, int base = 10);

1.2 参数解析

  • str:要转换的字符串,必须是有效的整数格式。
  • pos(可选):如果提供 posstoi 会在 *pos 中存储转换结束的位置(即最后一个转换的字符的下一个位置)。
  • base(可选):表示字符串所使用的进制,默认值为 10(十进制),支持 236 进制。

1.3 返回值

  • 成功:返回转换后的 int 类型整数。
  • 失败:如果字符串不是有效的数字或超出了 int 类型的范围,会抛出异常。

2. std::stoi 的实现原理

在 GCC 标准库的 string 头文件中,std::stoi 实际上是基于 std::strtol 实现的,它的实现如下:

inline int
stoi(const string& __str, size_t* __idx = 0, int __base = 10)
{ 
    return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(), __idx, __base); 
}

2.1 解析实现代码

  • 调用 std::strtol
    std::strtol(String to Long)是 C 语言中的标准函数,它可以将 C 风格的字符串转换为 long 类型的整数,同时支持进制转换。
  • 使用 __gnu_cxx::__stoa 进行封装
    这个函数的作用是将 long 转换为 int,并进行错误检查。
  • __str.c_str()
    std::string.c_str() 方法返回一个 const char*,将 std::string 转换为 C 风格字符串,以便 std::strtol 解析。

3. std::stoi 的实际用法

3.1 基础示例

#include <iostream>
#include <string>

int main() {
    std::string str = "12345";
    int num = std::stoi(str);  // 默认10进制
    std::cout << "转换结果: " << num << std::endl;
    return 0;
}

输出:

转换结果: 12345

3.2 使用 pos 参数记录转换结束的位置

#include <iostream>
#include <string>

int main() {
    std::string str = "123xyz";
    std::size_t pos;
    int num = std::stoi(str, &pos);
    
    std::cout << "转换结果: " << num << std::endl;
    std::cout << "转换结束位置: " << pos << std::endl;
    
    return 0;
}

输出:

转换结果: 123
转换结束位置: 3

解析:

  • stoi 解析 "123" 后遇到 "xyz",停止转换,并将 pos 设为 3

3.3 处理不同进制的转换

#include <iostream>
#include <string>

int main() {
    std::string str = "1A";  // 16进制
    int num = std::stoi(str, nullptr, 16);  // 以16进制解析
    std::cout << "转换结果: " << num << std::endl;
    
    return 0;
}

输出:

转换结果: 26

解析:

  • 1A 在十六进制中等于 26,所以 stoi 返回 26

其他进制示例

std::stoi("1010", nullptr, 2);  // 以二进制解析,返回 10
std::stoi("75", nullptr, 8);    // 以八进制解析,返回 61
std::stoi("1F", nullptr, 16);   // 以十六进制解析,返回 31

4. 处理异常情况

4.1 输入不是有效的数字

如果 str 不是有效的整数格式,std::stoi 会抛出 std::invalid_argument 异常:

#include <iostream>
#include <string>
#include <stdexcept>

int main() {
    try {
        std::string str = "abc";  
        int num = std::stoi(str);
        std::cout << "转换结果: " << num << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cerr << "错误: 无效的数字字符串 -> " << e.what() << std::endl;
    }

    return 0;
}

输出:

错误: 无效的数字字符串 -> stoi

4.2 数值超出 int 范围

如果字符串表示的数值超出 int 的范围,std::stoi 会抛出 std::out_of_range 异常:

#include <iostream>
#include <string>
#include <climits>

int main() {
    try {
        std::string str = "9999999999";  
        int num = std::stoi(str);
        std::cout << "转换结果: " << num << std::endl;
    } catch (const std::out_of_range& e) {
        std::cerr << "错误: 数值超出范围 -> " << e.what() << std::endl;
    }

    return 0;
}

输出:

错误: 数值超出范围 -> stoi

5. std::stoi 相关函数

函数作用返回类型
std::stoi转换为 intint
std::stol转换为 longlong
std::stoll转换为 long longlong long
std::stoul转换为 unsigned longunsigned long
std::stof转换为 floatfloat
std::stod转换为 doubledouble

6. 结论

  • std::stoistd::strtol 的封装,支持进制转换。
  • 提供 pos 参数记录转换位置。
  • 可能抛出 std::invalid_argumentstd::out_of_range 异常。
  • 适用于整数解析,若数值可能超大,建议使用 std::stolstd::stoll

学会 std::stoi,可以让你的 C++ 代码更加高效、健壮!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客晨风

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值