1. atoi函数
1.1 函数的声明
int atoi (const char * str);
1.2 函数的作用
- 将字符串转化为int类型的数据。
- 转化string字符串里面的涉及到可以转化为int类型的数字,然后作为返回值返回。
- 该函数会从str地址开始,跳过所有空白字符,直到遇到第一个非空白的字符。然后从这个字符开始,判断是正号还是负号通过10为基准,将字符转化为int数据。
- 字符串可以在组成整数的字符之后包含其他字符,这些字符将被忽略,并且对此函数的行为没有影响。
- 如果str中的第一个非空白字符序列不是一个有效的整数,或者因为str为空或者它只包含空白字符而不存在这样的序列,则不执行转换。
- 如果成功,该函数将转换后的整数作为整型值返回。如果转换后的值超出了int可表示值的范围,则会导致未定义的行为。如果有可能,请参阅strtol以获得更健壮的跨平台替代方案。
1.3 函数的使用
int main() { char arr[] = " 1234a000"; int i = atoi(arr); printf("%d", i); return 0; }
2. 模拟实现atoi函数
2.1 整理思路
- 根据atoi函数的声明,我们知道了函数应该怎么定义。
int atoi (const char * str);
- 第一点:我们得对str指针进行非空判断。
//空指针 assert(str);
- 第二点:对传入来的str指针指向的数据不能是一个空字符串,也就是不能为"\0"。
//空字符串 if (*str == '\0') return 0;
- 第三点:该函数会从str地址开始,跳过所有空白字符,直到遇到第一个非空白的字符。
//跳过空白字符 //例如:“ 12345”,跳过前面的空格 while (isspace(*str)) { str++; }
- 第四点:判断遇到的第一个字符是正号还是负号。
//flag:+ - 来表示 int flag = 1;//1表示正号,-1表示负号 if (*str == '+') { flag = 1; str++; } else if (*str == '-') { flag = -1; str++; }
- 第五点:判断是不是字符数字,然后转换为int类型
//为了方便 long long r = 0;//因为r可能会超过INT_MAX或者低于INT_MIN,所以要想将r设置为long long类型 while (*str) { //判断是否为数字字符 if (isdigit(*str)) { //数字字符在字符表中都是按顺序排放的,所以‘1’-‘0’= 1 //r * 10是为了保证前一位能进一位,例如字符串“12”,为了保证1到十位,所以要乘以10 r = r * 10 + flag * (*str - '0'); if (r > INT_MAX || r < INT_MIN) { if (flag == 1)//判断正负号 return INT_MAX; else return INT_MIN; } str++; } else { return (int)r; } }
- 第六点:因为需要判断my_atoi函数是合法转化还是非法转化,设置了一个枚举类型来作为标记。
enum State { VALID,//0 INVALID//1 }sta = INVALID;//默认设置为非法
2.2 整份代码
enum State { VALID,//0 INVALID//1 }sta = INVALID;//默认设置为非法 int my_atoi(const char* str) { //空指针 assert(str); //空字符串 if (*str == '\0') return 0; //跳过空白字符 //例如:“ 12345”,跳过前面的空格 while (isspace(*str)) { str++; } //flag:+ - 来表示 int flag = 1;//1表示正号,-1表示负号 if (*str == '+') { flag = 1; str++; } else if (*str == '-') { flag = -1; str++; } //为了方便 long long r = 0;//因为r可能会超过INT_MAX或者低于INT_MIN,所以要想将r设置为long long类型 while (*str) { //判断是否为数字字符 if (isdigit(*str)) { //数字字符在字符表中都是按顺序排放的,所以‘1’-‘0’= 1 //r * 10是为了保证前一位能进一位,例如字符串“12”,为了保证1到十位,所以要乘以10 r = r * 10 + flag * (*str - '0'); if (r > INT_MAX || r < INT_MIN) { if (flag == 1)//判断正负号 return INT_MAX; else return INT_MIN; } str++; } else { return (int)r; } } sta = VALID; return (int)r; } int main() { char arr[] = " 1234a0000000000000000000000"; int ret = my_atoi(arr); if (sta == VALID) printf("合法的转换:%d\n", ret); else printf("非法的转换:%d\n", ret); }