C++:字符串string转成整型int
一、atoi
atoi
是 C 标准库中的一个函数,全称是 ASCII to Integer,用于将字符串转换为整数。
函数定义
int atoi(const char *str);
- 参数:
str
是一个指向以'\0'
结尾的字符串的指针。 - 返回值:返回字符串转换后的整数。如果字符串中不包含有效的数字,返回 0。
工作原理
atoi
从字符串的开头部分开始,逐字符地读取,忽略前导空格,然后将连续的数字字符转换为对应的整数值。当遇到第一个非数字字符时,转换停止。
- 合法输入:
atoi
只处理合法的数字字符,数字前可以带一个可选的正负号 (+
或-
)。 - 错误处理:如果字符串中没有有效的数字,
atoi
返回0
。此外,它没有提供错误检测机制,也无法检测数字溢出(即超过int
类型的范围)。
示例
#include <stdio.h>
#include <stdlib.h>
int main() {
const char *str1 = "123";
const char *str2 = " -456";
const char *str3 = "abc123";
const char *str4 = "789abc";
printf("String: %s, Integer: %d\n", str1, atoi(str1)); // 输出: 123
printf("String: %s, Integer: %d\n", str2, atoi(str2)); // 输出: -456
printf("String: %s, Integer: %d\n", str3, atoi(str3)); // 输出: 0 (无效数字)
printf("String: %s, Integer: %d\n", str4, atoi(str4)); // 输出: 789 (数字到非数字处停止)
return 0;
}
输出:
String: 123, Integer: 123
String: -456, Integer: -456
String: abc123, Integer: 0
String: 789abc, Integer: 789
注意
atoi
不处理错误情况,如果输入字符串无效或转换过程中发生溢出,它不会提示错误。因此,推荐使用更安全的函数,例如strtol
或sscanf
。strtol
替代:相比于atoi
,strtol
可以提供更好的错误处理功能,例如处理溢出和检测无效输入。
二、strtol
strtol
是 C/C++ 标准库中的一个函数,用于将字符串转换为长整型数(long int
),同时能够处理不同的数制(如二进制、八进制、十进制、十六进制)并检测转换错误。
函数定义
long int strtol(const char *str, char **endptr, int base);
参数
str
:指向一个以'\0'
结尾的 C 字符串,这个字符串将被转换为长整型数。endptr
:指向一个字符指针的地址。该指针将被设置为指向str
中第一个未能转换为数值的字符。如果你不关心这个信息,可以传NULL
。base
:表示使用的进制。常见值:10
:十进制8
:八进制16
:十六进制0
:自动检测进制(如0x
开头表示十六进制,0
开头表示八进制,其余默认为十进制)
返回值
- 成功时:返回转换后的
long int
数值。 - 失败时:如果字符串中没有有效的数字部分,返回
0
;如果数值超出long
的范围,返回LONG_MAX
或LONG_MIN
,并设置errno
为ERANGE
。
工作原理
strtol
先跳过字符串开头的空白符(如空格、换行符等),然后尝试将字符串中的字符转换为 long
型数值,直到遇到一个非数字字符为止。
示例
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int main() {
const char *str = "123abc";
char *endptr;
long value;
errno = 0; // 清除 errno 以捕捉任何潜在错误
value = strtol(str, &endptr, 10); // 将字符串转换为 long 类型的十进制数
// 检查转换后的结果
if (errno == ERANGE) {
// 处理范围错误,超出 LONG_MAX 或 LONG_MIN
printf("Error: number out of range.\n");
} else if (endptr == str) {
// 没有任何字符被转换
printf("No digits were found.\n");
} else {
// 成功转换了部分字符串
printf("Converted value: %ld\n", value);
printf("Non-converted part: %s\n", endptr);
}
return 0;
}
输出:
Converted value: 123
Non-converted part: abc
详细解释
endptr
:指向未转换部分的第一个字符。在本例中,转换的是"123"
,转换停止时endptr
指向"abc"
。- 错误处理:
- 如果转换后的数值超出了
long
的范围,strtol
将返回LONG_MAX
或LONG_MIN
,并将errno
设置为ERANGE
。 - 如果字符串中没有可以转换的数字字符,
strtol
返回0
,并将endptr
设置为str
。
- 如果转换后的数值超出了
使用 base
参数
strtol
可以转换不同进制的字符串。base
参数控制如何解释字符串中的数字:
- 十六进制:
base = 16
long value = strtol("0xFF", NULL, 16); // 转换为 255
-
八进制:
base = 8
long value = strtol("077", NULL, 8); // 转换为 63
-
二进制:
base = 2
long value = strtol("101", NULL, 2); // 转换为 5
-
自动检测进制:
base = 0
- 自动检测字符串的进制:如果字符串以
"0x"
开头,表示十六进制;以"0"
开头,表示八进制;否则为十进制。
- 自动检测字符串的进制:如果字符串以
long value1 = strtol("0xFF", NULL, 0); // 自动识别为 16 进制,转换为 255
long value2 = strtol("077", NULL, 0); // 自动识别为 8 进制,转换为 63
long value3 = strtol("123", NULL, 0); // 自动识别为 10 进制,转换为 123
错误处理
- 检查转换结果:使用
errno
来检查溢出错误,例如,当转换值超出long
类型的范围时,errno
会被设置为ERANGE
。 - 检查没有转换的情况:如果没有任何字符被转换,
endptr
会指向原始字符串的开头,这时应当处理这种情况。
适用场景
- 配置文件解析:将字符串转换为数字参数,例如程序启动时读取配置文件。
- 用户输入处理:处理用户输入的数值并转换为整数。
- 解析不同进制的数字:可以灵活处理二进制、八进制、十进制、十六进制的数字输入。
相比于 atoi
,strtol
更加灵活和安全,特别是在处理错误和支持不同进制方面。