在C语言中,将字符串转换为整数是一个常见的操作,这可以通过使用标准库函数 atoi 实现。atoi 函数接收一个指向字符数组的指针作为参数,并返回一个整数,这个整数是通过解析指向的字符串得到的。以下是一个 atoi 函数的简单实现,它包括了处理正负号、前导空格和基本的溢出检查。
函数实现
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
int atoi(const char *str) {
int result = 0;
int sign = 1;
bool has_sign = false;
// 跳过前导空格
while (*str == ' ') {
str++;
}
// 处理正负号
if (*str == '+' || *str == '-') {
sign = (*str == '-') ? -1 : 1;
has_sign = true;
str++;
}
// 转换数字
while (*str >= '0' && *str <= '9') {
int digit = *str - '0';
// 检查是否溢出
if (result > (INT_MAX - digit) / 10) {
return (sign == 1) ? INT_MAX : INT_MIN;
}
result = result * 10 + digit;
str++;
}
return has_sign ? sign * result : result;
}
int main() {
const char *str = " -12345";
int num = atoi(str);
printf("The integer value of '%s' is %d\n", str, num);
return 0;
}
详细解释
跳过前导空格:
- 使用
while循环来跳过字符串前导的空格字符。这是为了确保我们不会在处理数字之前遇到无效的字符。
- 使用
处理正负号:
- 检查当前字符是否为正号
+或负号-。如果是,则设置sign变量以记录数字的符号,并标记has_sign为true。然后,移动指针str到下一个字符。
- 检查当前字符是否为正号
转换数字:
- 使用另一个
while循环来遍历字符串中的每个字符,直到遇到非数字字符。 - 在每次迭代中,从当前字符减去字符
'0'的ASCII值以获得数字的实际值。例如,字符'3'减去'0'将给出数字 3。 - 在将数字添加到
result之前,检查是否会超过int类型可以表示的最大或最小值。这是通过检查result是否大于(INT_MAX - digit) / 10来实现的,这可以确保没有溢出。
- 使用另一个
返回结果:
- 如果字符串以正号或负号开头,则根据
sign变量和has_sign标记计算最终的result。如果没有正负号,则直接返回result。
- 如果字符串以正号或负号开头,则根据
注意事项
- 这个实现没有处理非数字字符的情况,如果需要处理字符串中包含非数字字符的情况,你需要添加额外的错误检查。
- 当转换结果超过
int类型能表示的范围时,这个实现会返回INT_MAX或INT_MIN,这是一个有用的特性,但需要谨慎使用,因为如果期望的结果是一个正数,但函数返回了INT_MIN,这可能会引起混淆。 - 在使用
atoi函数时,最好确保传入的字符串只包含数字和可能的正负号。
