库函数 atoi 与 stoi
atoi (ASCII to Integer)
是一个常见的 C 语言库函数,用于将字符串转换为整数。stoi
是 C++标准库中的一个函数,也用于将字符串转换为整数类型。它们的函数原型如下:
1
2
3
4
5
6
7
|
int atoi(const char* str);
// str: 以 null 结尾的 C 风格字符串(字符数组)
int stoi(const string& str, size_t* pos = nullptr, int base = 10);
// str: 要转换的字符串
// pos(可选): 指向 size_t 类型的指针,用于存储转换后整数的位置
// base(可选): 整数,指定要使用的进制,默认是10进制。可以设置为2到36之间的值
|
使用案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#include <iostream>
#include <iomanip> // 包含 setw
using namespace std;
vector<string> test_case = {"123", "-123", "-0", "0",
"-00123", "00123",
"1111111111111", "-1111111111111",
" -10", " 10", " ", "",
"abc", "abc-1", " -100abc-1", "100 100",
};
int main() {
for (string s: test_case) {
cout << "atoi(\"" + s + "\"): " << std::setw(30) << std::left << atoi(s.c_str()) << '\t';
cout << "stoi(\"" + s + "\"): " ;
try {
cout << stoi(s);
} catch (const std::invalid_argument& e) {
cout << "[Invalid argument exception]: " << e.what();
} catch (const std::out_of_range& e) {
cout << "[Out of range exception]: " << e.what();
}
cout << endl;
}
return 0;
}
|
输出结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
atoi("123"): 123 stoi("123"): 123
atoi("-123"): -123 stoi("-123"): -123
atoi("-0"): 0 stoi("-0"): 0
atoi("0"): 0 stoi("0"): 0
atoi("-00123"): -123 stoi("-00123"): -123
atoi("00123"): 123 stoi("00123"): 123
atoi("1111111111111"): -1285418553 stoi("1111111111111"): [Out of range exception]: stoi: out of range
atoi("-1111111111111"): 1285418553 stoi("-1111111111111"): [Out of range exception]: stoi: out of range
atoi(" -10"): -10 stoi(" -10"): -10
atoi(" 10"): 10 stoi(" 10"): 10
atoi(" "): 0 stoi(" "): [Invalid argument exception]: stoi: no conversion
atoi(""): 0 stoi(""): [Invalid argument exception]: stoi: no conversion
atoi("abc"): 0 stoi("abc"): [Invalid argument exception]: stoi: no conversion
atoi("abc-1"): 0 stoi("abc-1"): [Invalid argument exception]: stoi: no conversion
atoi(" -100abc-1"): -100 stoi(" -100abc-1"): -100
atoi("100 100"): 100 stoi("100 100"): 100
|
两者差异
|
atoi |
stoi |
C++标准 |
C 标准库函数 |
C++标准库函数 |
参数 |
const char* str :C 风格字符数组指针 |
const string& str :字符串 size_t* pos = nullptr :转换后结果的存储位置 int base = 10 :整数的进制,默认 10 进制 |
错误处理 |
没有提供错误处理机制: - 字符串无法转换为整数,返回 0 - 转换后的值超出目标类型的范围,返回溢出值 |
提供错误处理机制: - 字符串无法转换为整数,抛出 invalid_argument 异常 - 转换后的值超出目标类型的范围,抛出 out_of_range 异常 |
atoi
与 stoi
对空格和非数字字符的处理类似:
- 忽略字符串开头的空格字符,遇到中间的空格或非数字字符会停止转换
- 当前的转换值非空则返回,若没有转换值
atoi
返回 0,stoi
抛出 invalid_argument
异常
建议使用 stoi
函数,因为它提供了更好的错误处理和更严格的转换规则,也包含更多功能。如果使用 C 语言,或者仅考虑简单的转换,atoi
函数也可以满足需求。
实现自己的 atoi
Leetcode:8. 字符串转换整数 (atoi)
需要考虑各种边界条件,面对溢出和非法字符返回 0 或抛出异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include <iostream>
using namespace std;
vector<string> test_case = {"123", "-123", "-0", "0",
"-00123", "00123",
"1111111111111", "-1111111111111",
" -10", " 10", " ", "",
"abc", "abc-1", " -100abc-1", "100 100",
};
// string 2 int [-2^31, 2^31-1] [-2147483648, 2147483647]
int myAtoi(const char* str) {
if (str == NULL) return 0;
int res = 0, sign = 1, i = 0;
// 忽略字符串开头空格
while (str[i] == ' ') i++;
// 整数符号判断
if (str[i] == '-' || str[i] == '+') {
sign = str[i++] == '-' ? -1 : 1;
}
// 没有有效转化数字
if (!(str[i] >= '0' && str[i] <= '9')) {
throw std::invalid_argument("no conversion");
// return 0;
}
// 计算数字
for (; str[i]; i++) {
// 非数字字符直接终止
if (!(str[i] >= '0' && str[i] <= '9')) {
return res * sign;
}
// 处理溢出
if (res > INT_MAX / 10 || (res == INT_MAX/10 && str[i] > '7')) {
throw std::out_of_range("out of range");
// return sign == 1 ? INT_MAX : INT_MIN;
}
res = res * 10 + str[i] - '0';
}
return res * sign;
}
int main() {
for (string s: test_case) {
cout << "string2int(\"" + s + "\"): ";
try {
cout << myAtoi(s.c_str());
} catch (const std::invalid_argument& e) {
cout << "[Invalid argument exception]: " << e.what();
} catch (const std::out_of_range& e) {
cout << "[Out of range exception]: " << e.what();
}
cout << endl;
}
return 0;
}
|
Reference