C++ 整数和字符串转换函数总结
·
C++ 整数和字符串转换函数总结
一、C++11 及以后的标准库方法
1. 整数转字符串
// 1. std::to_string() - 最常用
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(float value);
std::string to_string(double value);
// 示例
std::string s1 = std::to_string(42); // "42"
std::string s2 = std::to_string(3.14159); // "3.141590"
2. 字符串转整数
// 带错误处理的转换函数
int std::stoi(const std::string& str, size_t* pos = 0, int base = 10); //2/8/10/16
long std::stol(const std::string& str, size_t* pos = 0, int base = 10); //2/8/10/16
long long std::stoll(const std::string& str, size_t* pos = 0, int base = 10); //2/8/10/16
unsigned long std::stoul(const std::string& str, size_t* pos = 0, int base = 10); //2/8/10/16
unsigned long long stoull(const std::string& str, size_t* pos = 0, int base = 10); //2/8/10/16
float stof(const string& str, size_t* pos = nullptr); //仅十进制
double stod(const string& str, size_t* pos = nullptr); //仅十进制
// 示例
std::string s = "123abc";
size_t pos;
int num = std::stoi(s, &pos); // num = 123, pos = 3
参数详细说明
str(必需参数)
- 类型:
const std::string&(常量引用) - 含义: 要转换的输入字符串
- 说明: 包含数字表示的字符串,函数会解析其内容
pos(可选参数)
- 类型:
size_t*(指向size_t类型的指针) - 默认值:
0(即nullptr) - 含义: 存储第一个未转换字符的位置索引
- 作用:
- 如果提供非空指针,函数会将第一个无法转换的字符的索引存入
*pos - 可用于检查转换是否消耗了整个字符串
- 如果为
nullptr,则忽略此信息
- 如果提供非空指针,函数会将第一个无法转换的字符的索引存入
base(可选参数)
- 类型:
int - 默认值:
10 - 含义: 数字的进制基数
- 取值范围:
0或2到36base = 0: 自动检测进制(类似C语言的规则)0x或0X开头 → 十六进制(base 16)0开头 → 八进制(base 8)- 其他 → 十进制(base 10)
base = 2~36: 使用指定进制
详细示例
- 示例1:基本用法
#include <iostream>
#include <string>
std::string str = "123abc";
size_t pos;
int num = std::stoi(str, &pos); // pos = 3
std::cout << "数值: " << num << std::endl; // 123
std::cout << "未转换位置: " << pos << std::endl; // 3
std::cout << "剩余字符串: " << str.substr(pos) << std::endl; // "abc"
- 示例2:不同进制
std::string str;
// 十进制(默认)
str = "255";
int dec = std::stoi(str); // 255
int dec2 = std::stoi(str, nullptr, 10); // 255
// 十六进制
str = "FF";
int hex = std::stoi(str, nullptr, 16); // 255
// 八进制
str = "377";
int oct = std::stoi(str, nullptr, 8); // 255
// 二进制(base=2)
str = "11111111";
int bin = std::stoi(str, nullptr, 2); // 255
// 自动检测(base=0)
str = "0xFF";
int auto1 = std::stoi(str, nullptr, 0); // 255(自动识别十六进制)
str = "0377";
int auto2 = std::stoi(str, nullptr, 0); // 255(自动识别八进制)
str = "255";
int auto3 = std::stoi(str, nullptr, 0); // 255(十进制)
- 示例3:完整转换检查
#include <iostream>
#include <string>
void parseNumber(const std::string& input) {
size_t pos;
try {
long long num = std::stoll(input, &pos);
std::cout << "输入: \"" << input << "\"" << std::endl;
std::cout << "转换数值: " << num << std::endl;
std::cout << "已转换字符数: " << pos << std::endl;
if (pos == input.length()) {
std::cout << "✓ 整个字符串都被转换" << std::endl;
} else {
std::cout << "✗ 部分转换,剩余: \""
<< input.substr(pos) << "\"" << std::endl;
}
} catch (const std::invalid_argument& e) {
std::cout << "✗ 无效参数: 无法转换为数字" << std::endl;
} catch (const std::out_of_range& e) {
std::cout << "✗ 数值超出范围" << std::endl;
}
std::cout << std::endl;
}
int main() {
parseNumber("123"); // 完全转换
parseNumber("123abc"); // 部分转换,剩余"abc"
parseNumber(" 456"); // 注意:会自动跳过前导空白
parseNumber("abc123"); // 无效参数(以非数字开头)
parseNumber("99999999999999999999"); // 超出范围
return 0;
}
- 示例4:处理空格和空白
std::string str = " 123 ";
size_t pos;
// stoi 会自动跳过前导空白字符(空格、制表符等)
int num = std::stoi(str, &pos);
std::cout << num << std::endl; // 123
std::cout << pos << std::endl; // 5 (第一个'3'后面的空格位置)
- 示例5:stoi vs stoll 的区别
// stoi: 返回 int (通常是32位)
std::string large = "3000000000"; // 30亿
try {
int small = std::stoi(large); // 可能溢出(取决于平台)
} catch (const std::out_of_range& e) {
std::cout << "int 太小,无法存储" << std::endl;
}
// stoll: 返回 long long (至少64位)
long long big = std::stoll(large); // 成功,3000000000
重要特性
| 特性 | 说明 |
|---|---|
| 前导空白 | 自动跳过(空格、制表符、换行符等) |
| 正负号 | 支持 + 和 - 前缀 |
| 进制前缀 | base=0 时识别 0x/0X(十六进制) 和 0(八进制) |
| 停止条件 | 遇到非数字字符时停止(根据进制) |
| 异常 | std::invalid_argument:无有效转换std::out_of_range:超出范围 |
常见用法模式
// 模式1:只转换,不关心剩余部分
int value = std::stoi("123abc"); // value = 123
// 模式2:检查是否完全转换
size_t pos;
int value = std::stoi("123", &pos);
if (pos == str.length()) {
// 完全转换成功
}
// 模式3:解析带单位的值
std::string data = "1024MB";
size_t pos;
int num = std::stoi(data, &pos); // num = 1024
std::string unit = data.substr(pos); // unit = "MB"
// 模式4:十六进制解析
std::string hexColor = "0xFF0000";
int red = std::stoi(hexColor, nullptr, 0); // 自动识别十六进制
性能提示
- 使用
pos参数可避免不必要的字符串拷贝 - 对于性能敏感代码,考虑使用
std::from_chars(C++17) - 如果需要转换C风格字符串,直接用
std::strtol可能更高效
二、字符串流方法(通用但较慢)
#include <sstream>
// 任意类型转字符串
std::ostringstream oss;
oss << 123;
std::string s = oss.str();
// 字符串转整数
std::istringstream iss("456");
int n;
iss >> n;
三、C++20 新增
// std::format (C++20) - 类似Python的format
#include <format>
std::string s = std::format("{:d}", 42); // "42"
std::string s = std::format("{:#x}", 255); // "0xff"
四、性能对比和使用建议
| 方法 | 性能 | 适用场景 |
|---|---|---|
to_string/stoi |
中等 | 一般用途,代码简洁 |
stringstream |
较慢 | 复杂格式化或多种类型组合 |
sprintf |
较快 | C风格代码,需注意缓冲区安全 |
format (C++20) |
中等 | 需要复杂格式化时 |
五、完整示例
#include <iostream>
#include <string>
#include <charconv>
#include <format>
int main() {
// 整数转字符串
std::string s1 = std::to_string(12345);
std::cout << "to_string: " << s1 << std::endl;
// 字符串转整数(带错误处理)
try {
std::string s2 = "123abc";
int num = std::stoi(s2);
std::cout << "stoi: " << num << std::endl;
} catch (const std::invalid_argument& e) {
std::cout << "Invalid argument" << std::endl;
} catch (const std::out_of_range& e) {
std::cout << "Out of range" << std::endl;
}
// from_chars (C++17)
std::string s3 = "999";
int value;
auto result = std::from_chars(s3.data(), s3.data() + s3.size(), value);
if (result.ec == std::errc()) {
std::cout << "from_chars: " << value << std::endl;
}
// C++20 format
#if __cplusplus > 201703L
std::string s4 = std::format("Hex: {:#x}", 255);
std::cout << s4 << std::endl; // "Hex: 0xff"
#endif
return 0;
}
六、常见陷阱
stoi不会跳过空白字符,但会抛出异常- 进制问题:默认十进制,可通过base参数指定
from_chars不会跳过空白,效率最高但要求严格匹配- 浮点数转换:
stod/to_string可能产生精度问题
推荐:一般场景用 std::to_string 和 std::stoi;性能关键场景用 std::from_chars 和自定义缓冲区的 to_chars。
更多推荐


所有评论(0)