atol实现【转】

 1 int my_atoi(const char *str)  
 2 {  
 3     assert(str != NULL);  
 4     int flag = 1;  
 5     int result = 0;  
 6     while(*str == ' ' || *str == '\n' || *str == '\t')  
 7     {  
 8         ++str;  
 9     }  
10     if(*str == '-')  
11     {  
12         flag = -1;  
13         ++str;  
14     }  
15     else if(*str == '+')  
16     {  
17         ++str;  
18     }  
19     while(*str != '\0')  
20     {  
21         if(*str >= '0' && *str <= '9')  
22         {  
23             result = result*10 + *str - '0';  
24         }  
25         else  
26         {  
27             return flag * result;  
28         }  
29         ++str;  
30     }  
31     return flag * result;  
32 }  

 

转载于:https://www.cnblogs.com/zzb-Dream-90Time/p/6829452.html

<think>我们正在讨论C/C++中的atol函数,它用于将字符串换为长整型数值。根据引用[1]和[2],atol函数的声明在stdlib.h头文件中,其函数原型为: ```c long atol(const char *nptr); ``` 该函数接受一个指向字符串的指针(nptr),然后尝试将字符串中的字符序列解释为一个长整型数。换过程会跳过前面的空白字符(例如空格、制表符等),直到遇到第一个非空白字符。然后,从这个字符开始,尽可能多地换可以形成长整数的字符序列,直到遇到非数字字符或字符串结束符('\0')为止。 ### 使用步骤 1. **包含头文件**:在程序中包含`<stdlib.h>`(在C++中也可以使用`<cstdlib>`)。 2. **调用函数**:将需要换的字符串(C风格字符串,以'\0'结尾)作为参数传递给`atol`函数。 3. **处理返回值**:函数返回换后的长整型数值。如果字符串无法换为有效的长整型数,则返回0。 ### 示例代码 ```c #include <stdio.h> #include <stdlib.h> // 包含atol函数 int main() { const char *str1 = "12345"; // 合法的数字字符串 const char *str2 = " -67890"; // 前面有空格,然后是负数 const char *str3 = "abc123"; // 以非数字开头,无法换 const char *str4 = "123abc"; // 数字开头,后面有非数字,只换前面的数字 long num1 = atol(str1); long num2 = atol(str2); long num3 = atol(str3); long num4 = atol(str4); printf("'%s' -> %ld\n", str1, num1); printf("'%s' -> %ld\n", str2, num2); printf("'%s' -> %ld\n", str3, num3); // 无法换,返回0 printf("'%s' -> %ld\n", str4, num4); // 只换前面的123 return 0; } ``` 运行结果: ``` '12345' -> 12345 ' -67890' -> -67890 'abc123' -> 0 '123abc' -> 123 ``` ### 注意事项 1. **错误处理**:`atol`函数在换失败时会返回0,但无法区分是真正的0还是换失败。例如,字符串"0"和"abc"都会返回0。因此,如果需要对换错误进行严格处理,应该使用更健壮的函数`strtol`(引用[3]中提到的函数),它提供了错误检测机制。 2. **溢出问题**:如果换的数值超出了`long`类型能够表示的范围,其行为是未定义的(可能返回一个溢出的值,具体由编译器实现决定)。同样,`strtol`函数可以检测溢出。 3. **前导空白字符**:函数会自动跳过字符串前面的空白字符(通过isspace函数判断)。 4. **有效字符**:换从第一个非空白字符开始,如果第一个非空白字符不是数字或正负号,则换失败。如果是正负号,则后面必须紧跟数字,否则也失败。 ### 替代函数:strtol 根据引用[3],`strtol`函数提供了更强大的换功能,包括指定进制和错误检测。其函数原型为: ```c long strtol(const char *nptr, char **endptr, int base); ``` - `base`参数指定进制(2~36),或者0(表示自动检测,根据字符串的前缀:0x表示16进制,0表示8进制,否则为10进制)。 - `endptr`参数用于返回换结束的位置,如果换失败,`endptr`指向原始字符串的起始位置;如果换成功,则指向换结束后的第一个字符(即未换部分的开头)。通过检查`endptr`,我们可以知道整个字符串是否都被换,或者是否有部分换。 ### 示例:使用strtol ```c #include <stdio.h> #include <stdlib.h> int main() { const char *str = "123abc"; char *end; long num = strtol(str, &end, 10); if (str == end) { printf("No digits were found.\n"); } else if (*end != '\0') { printf("Partial conversion: %ld, stopped at: '%s'\n", num, end); } else { printf("Full conversion: %ld\n", num); } return 0; } ``` 运行结果: ``` Partial conversion: 123, stopped at: 'abc' ``` ### 总结 - 对于简单的换且不需要错误处理的场景,可以使用`atol`函数。 - 在需要检测换错误、处理不同进制或部分换的情况下,应使用`strtol`函数。 §§相关问题§§ 1. `atol`函数和`strtol`函数的主要区别是什么? 2. 在C++中,是否有更推荐的方法将字符串换为整数? 3. 如何安全地处理字符串换整数时的溢出问题?</think>### atol函数详解 `atol`是C/C++标准库中用于将字符串换为长整型(`long`)的函数,定义在`<stdlib.h>`头文件中。 #### 函数原型 ```c long atol(const char *nptr); ``` #### 核心功能 1. **参数**:`nptr` - 指向待换的C风格字符串(以`\0`结尾) 2. **返回值**: - 成功:返回换后的长整型数值 - 失败:返回0(无法识别为数字的字符串) 3. **换规则**: - 跳过字符串开头的空白字符(空格、制表符等) - 识别可选的正负号(`+`或`-`) - 解析连续的数字字符(0-9),遇到非数字字符时停止 - 自动忽略数字后面的非数字字符(不会报错) #### 使用示例 ```c #include <stdio.h> #include <stdlib.h> // 必须包含此头文件 int main() { // 基本换 printf("%ld\n", atol("12345")); // 输出: 12345 printf("%ld\n", atol("-6789")); // 输出: -6789 // 带空格的处理 printf("%ld\n", atol(" 42")); // 输出: 42 // 部分数字换 printf("%ld\n", atol("99bottles")); // 输出: 99(遇到'b'停止) // 换失败 printf("%ld\n", atol("abc123")); // 输出: 0(首字符非数字) printf("%ld\n", atol("")); // 输出: 0(空字符串) return 0; } ``` #### 重要注意事项 1. **错误处理局限**:无法区分"0"和无效输入(都返回0),需额外验证 ```c if (nptr[0] < '0' || nptr[0] > '9') { // 手动处理无效输入 } ``` 2. **溢出风险**:当数值超过`LONG_MIN`~`LONG_MAX`范围时,行为未定义 - Windows/Linux 32位:$[-2^{31}, 2^{31}-1]$(约±21亿) - 64位系统:$[-2^{63}, 2^{63}-1]$ 3. **替代方案**:更安全的`strtol`函数可检测错误和溢出 ```c char *endptr; long value = strtol(str, &endptr, 10); if (endptr == str || *endptr != '\0') { // 处理换错误 } ``` #### 与相关函数的区别 | 函数 | 返回类型 | 特点 | |------------|--------------|-------------------------| | `atoi()` | `int` | 换到基本整型 | | `atol()` | `long` | 换到长整型 | | `atoll()` | `long long` | 换到64位整型(C99) | | `strtol()` | `long` | 可检测错误和溢出 | > 实际应用:常用于处理命令行参数、配置文件读取等场景,如`./program 1024`中解析"1024"[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值