字符数字转换 atoi 与 strtol
原文:http://www.cnblogs.com/JefferyZhou/archive/2010/07/01/1769555.html
在很多时候我们都很清楚 atoX 系列函数: atoi , atol , atof
新来的一系列函数: strtol, strtoul, strtod
通常有如下的关系:
1. 对应关系其中:
atoi (把字符串转到整形) --对应-- strtol (把字符串转到长整形)
atol (把字符串转到长整形) --对应-- strtol (把字符串转到长整形)
atof (把字符串转到浮点数) --对应-- strtod (把字符串转到浮点数)
2. atoX 系列是 三十年前的函数 strtoX 系列是后十年产品
3. atoX 系列接口,没有成功失败的区别(标准实现中), strtoX 系列接口,有成功失败的区别
比如:int i_atoi_lfs = atoi(""); 与 int i_atoi_rfs = atoi("0"); 两个得到的是一样的,没有任何区别
而: int i_atoi_lfs = strtol ("", NULL,10); 与 int i_atoi_rfs = strtol ("0", NULL,10); 得到的结果都是0,但是左边会置失败标志位。
4. msvcr80.dll 的具体实现:
|
1
2
3
4
5
|
int __cdecl atoi(__in_z const char *_Str){ return _tstoi(_Str); } int __cdecl _tstoi( const _TCHAR *nptr ){ return (int)_tstol(nptr);}int __cdecl _tstoi( const _TCHAR *nptr ){ return (int)_tstol(nptr);}long __cdecl _tstol(const _TCHAR *nptr){return _tcstol(nptr, NULL, 10);}#define _tcstol strtol |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<pre class="brush:cpp">extern "C" long __cdecl strtol ( const char *nptr, char **endptr, int ibase ){ if (__locale_changed == 0) { return (long) strtoxl(&__initiallocalestructinfo, nptr, (const char **)endptr, ibase, 0); } else { return (long) strtoxl(NULL, nptr, (const char **)endptr, ibase, 0); }}</pre> |
|
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
static unsigned long __cdecl strtoxl ( _locale_t plocinfo, const char *nptr, const char **endptr, int ibase, int flags ){ const char *p; char c; unsigned long number; unsigned digval; unsigned long maxval; _LocaleUpdate _loc_update(plocinfo); /* validation section */ if (endptr != NULL) { /* store beginning of string in endptr */ *endptr = (char *)nptr; } _VALIDATE_RETURN(nptr != NULL, EINVAL, 0L); _VALIDATE_RETURN(ibase == 0 || (2 <= ibase && ibase <= 36), EINVAL, 0L); p = nptr; /* p is our scanning pointer */ number = 0; /* start with zero *///1. 这里关注到,函数没有检查传入的原字符指针是否为空, 如果传递了一个空的就崩了.... c = *p++; /* read char */ while ( _isspace_l((int)(unsigned char)c, _loc_update.GetLocaleT()) ) c = *p++; /* skip whitespace *///2. 不要期望能够 转换负负得正的字符串, 注意 "--100" 得到 0 , "-100" 得到 -100 if (c == '-') { flags |= FL_NEG; /* remember minus sign */ c = *p++; } else if (c == '+') c = *p++; /* skip sign *///3. 基数是 2 到 36 的闭区间 , [2, 36] if (ibase < 0 || ibase == 1 || ibase > 36) { /* bad base! */ if (endptr) /* store beginning of string in endptr */ *endptr = nptr; return 0L; /* return 0 */ }//4. 如果转换的时候基数输入是0, 则基数取决于原字符的前面两个字符, // 以非0开头的是 10进制字符串, // 以0x或者0X开头的是 16进制字符串, // 而仅仅以 0开头的是 8进制 else if (ibase == 0) { /* determine base free-lance, based on first two chars of string */ if (c != '0') ibase = 10; else if (*p == 'x' || *p == 'X') ibase = 16; else ibase = 8; }// {{{ 源码里面,这个地方 有这么一段 暂时不知道是干嘛的, 在我看来貌似是多余的 if (ibase == 0) { /* determine base free-lance, based on first two chars of string */ if (c != '0') ibase = 10; else if (*p == 'x' || *p == 'X') ibase = 16; else ibase = 8; }//}}}// 5. 如果是 16 进制,则跳过0x 或者 0X 的前缀 if (ibase == 16) { /* we might have 0x in front of number; remove if there */ if (c == '0' && (*p == 'x' || *p == 'X')) { ++p; c = *p++; /* advance past prefix */ } }// 6. 下面就是读取字符串,然后按照 local 解析应用的数值, 如果在转换过程中出现各种情况都会对标志位flags 进行标记 /* if our number exceeds this, we will overflow on multiply */ maxval = ULONG_MAX / ibase; for (;;) { /* exit in middle of loop */ /* convert c to value */ if ( __ascii_isdigit_l((int)(unsigned char)c, _loc_update.GetLocaleT()) ) digval = c - '0'; else if ( __ascii_isalpha_l((int)(unsigned char)c, _loc_update.GetLocaleT()) ) digval = __ascii_toupper(c) - 'A' + 10; else break; if (digval >= (unsigned)ibase) break; /* exit loop if bad digit found */ /* record the fact we have read one digit */ flags |= FL_READDIGIT; /* we now need to compute number = number * base + digval, but we need to know if overflow occured. This requires a tricky pre-check. */ if (number < maxval || (number == maxval && (unsigned long)digval <= ULONG_MAX % ibase)) { /* we won't overflow, go ahead and multiply */ number = number * ibase + digval; } else { /* we would have overflowed -- set the overflow flag */ flags |= FL_OVERFLOW; if (endptr == NULL) { /* no need to keep on parsing if we don't have to return the endptr. */ break; } } c = *p++; /* read next digit */ } --p; /* point to place that stopped scan */ if (!(flags & FL_READDIGIT)) { /* no number there; return 0 and point to beginning of string */ if (endptr) /* store beginning of string in endptr later on */ p = nptr; number = 0L; /* return 0 */ } else if ( (flags & FL_OVERFLOW) || ( !(flags & FL_UNSIGNED) && ( ( (flags & FL_NEG) && (number > -LONG_MIN) ) || ( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) ) { /* overflow or signed overflow occurred */ errno = ERANGE; //(老的实现方式和新的实现方式区别主要在这里, 新版友记录转换过程) if ( flags & FL_UNSIGNED ) number = ULONG_MAX; else if ( flags & FL_NEG ) number = (unsigned long)(-LONG_MIN); else number = LONG_MAX; } if (endptr != NULL) /* store pointer to char that stopped the scan */ *endptr = p; if (flags & FL_NEG) /* negate result if there was a neg sign */ number = (unsigned long)(-(long)number); return number; /* done. */} |
所以 atoi 已经等同于strtol
Sign, Clown , 2010.07.01 . 23:32 . HDPY
[本文原创,转载请注明出处,在文章末尾提供原文链接http://www.cnblogs.com/JefferyZhou/,否则一旦发现,将按字节每人民币收费,绝不论价]
字符数字转换 atoi 与 strtol的更多相关文章
- 比较java与c语言中数字转换成字符的不同
java java中将数字转换成字符非常方便,只要用一个"+"然后在跟一个空格行了.比如,你输入一个122 ,就会变成"122 ". import java.u ...
- Halcon中循环读取文件的实现以及数字与字符的转换
在循环读取文件的位置时,常用到数字与字符的转换. 数字与字符的转换 将字符转换为数字 tuple_number(StringImageIndex,IntImageIndex)` 1 2 1 2 将数字 ...
- js将数字转换成货币形式的字符
因为UI图上有的地方需要将数字转成货币形式的,例如:1234567转成 1,234,567 这样的,不过之前没弄过,然后在网上搜了下方法,参考了下面这篇文章 参考文章:JS将数字转成货币形式的简单 ...
- c语言字符串 数字转换函数大全
最近学数据结构老是做实验 常用到字符串和数字的转换 想找却发现网上的资料太散 所以搜集整理一下 方便以后再用 atof(将字符串转换成浮点型数) atoi(将字符串转换成整型数) atol(将字符串转 ...
- iconv字符编码转换
转自 http://blog.csdn.net/langresser_king/article/details/7459367 iconv(http://www.gnu.org/software/li ...
- unicode编码、字符的转换和得到汉字的区位码
一:unicode编码.字符的转换截图 二:unicode编码.字符的转换代码 using System; using System.Collections.Generic; using System ...
- 编码问题 php字符编码转换类
各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求. php 字符编码转换类,支持ANSI.Unicode.Unicode big endian.UTF-8.UTF-8+Bom ...
- js字符串转换成数字与数字转换成字符串的实现方法
转载:点击查看地址 js字符串转换成数字 将字符串转换成数字,得用到parseInt函数.parseInt(string) : 函数从string的开始解析,返回一个整数. 举例:parseInt(' ...
- js字符串转换成数字,数字转换成字符串
转自网络,忘记出处了. js字符串转换成数字 将字符串转换成数字,得用到parseInt函数. parseInt(string) : 函数从string的开始解析,返回一个整数. 举例:parseIn ...
随机推荐
- vue中npm run dev 不能自动打开浏览器运行项目
最近用vue2.0 + webpack搭建了环境创建新的项目.出现一个很蹩脚的问题: 在终端输入 npm run dev 的时候,不能自动打开浏览器运行项目. 这段话的意思是:你的应用程序运行地址是: ...
- 使用Appium-Desktop捕获APP元素控件实现自动化控制
使用Appium捕获APP的元素控件 实现自动化控制 我是用的是华为P20手机进行测试,为了映射出它的adb端口,需再去官网下载安装一个华为手机助手,然后将手机调成开发者模式,连接时选择传输文件模式. ...
- hey-cli初使用
当前项目负责人打算用hey-cli ,初步接触了hey-cli 是一款比vue-cli使用还要简单的脚手架 1. 先全局安装hey-cli npm install -g hey-cli 2. 初 ...
- es与hive整合
在hive classpath中添加elasticsearch-hadoop.jar,以下方法任一种均可: 1.启动hiveserver2 前,在hive-site.xml文件中更改hive.aux. ...
- C语言中malloc函数与free函数
- malloc函数 全称是memory allocation,中文叫动态内存分配,用于申请一块连续的.指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑 ...
- 用代码如何检测一个android程序是否在运行
/** * 检测一个android程序是否在运行 * @param context * @param PackageName * @return */ public static boolean is ...
- 说说移动端web开发中的点击穿透问题
最近一直在忙于一个无线端的项目,由于之前主要工作都是在桌面端,移动端接触的比较少,所以中间遇到了很多的坑,做一个简单的记录. 问题背景 需求中有这样的一个功能,点击取件信息的时候会弹出一个地址列表的浮 ...
- Handling of asynchronous events---reference
http://www.win.tue.nl/~aeb/linux/lk/lk-12.html 12. Handling of asynchronous events One wants to be n ...
- 利用git工具命令简单的从github上拷贝和上传代码
第一:从github上拷贝项目到本地 1.在github上建立一个项目名为:MygitTest 2.在我们本地电脑上把这个项目拷贝下来:直接选择一个文件夹,右键选择git Bash here 直接 ...
- TypeLoadException: Could not load type 'Microsoft.AspNetCore.Mvc.Internal.IHttpResponseStreamWriterFactory' from assembly 'Microsoft.AspNetCore.Mvc.Core, Version=2.1.2.0 ...
今天调试 asp.net core 2.0 项目时遇到了如下错误: TypeLoadException: Could not load type 'Microsoft.AspNetCore.Mvc.I ...