qey

Atitude is Everything.-- 关注C/C++,关注Linux(Unix) ,关注网络。 Better Late Than Never.
随笔 - 4, 文章 - 13, 评论 - 7, 引用 - 0
数据加载中……

stdlib.h 中常用函数[2]数字字符处理


基本信息// joen.hong#gmain.com
// 可任意转载,但请注明连接;
// 本文为巩固基础学习之用;
// 2009年10月09日
// 本文内容来源于C库头文件和Linux manual

在stdlib.h中主要包含数字字符处理的函数有 atoi(), atof(), strtol(), strtod(),eccvt()等函数及其扩展函数。
他们之间的共同点以及区别在下面功能描述中有说明,要详细了解需看手册和源代码实现。

函数原型:int atoi(const char *nptr);
          long atol(const char *nptr);
          long long atoll(const char *nptr);
          long long atoq(const char *nptr);
功能描述:atoi() 函数将指针nptr 指向开始的字符转换成int 类型。行为与 strtol(nptr, (char **) NULL, 10)相同;
          只是atoi() 不检测错误。atol() atoll() 和atoi() 有相同动作。只是转换类型有所不同,atoq()是atoll()的过时名。
返 回 值:返回转换的值。
参考函数:atof(3), strtod(3), strtol(3), strtoul(3)

函数原型:double atof(const char *nptr);
功能描述:atof() 函数将指针nptr 指向开始的字符转换成double 类型。行为与 strtod(nptr, (char **) NULL)相同;
          只是atof() 不检测错误。
返 回 值:返回转换的值。
参考函数:atoi(3), atol(3), strtod(3), strtol(3), strtoul(3)

函数原型:long int strtol(const char *nptr, char **endptr, int base);
          long long int strtoll(const char *nptr, char **endptr, int base);
功能描述:strtol() 函数根据base 给的进制将nptr 指向的开始的字符串转换为长整数值,base 必须在2-36之间,或特殊值0.
          字符串可能以任意空格为开始,后跟一个‘+’或‘-’的单个选择符。如果base 为0或16,string 可能包含“0x” 前缀,
          那么数字将被以16进制读入;base为0被当作10进制,除非符号后下一个字符为‘0’,这种情形被当作8进制。
          字符串被显示转换为长整形值,直到遇到第一个基于base 不合法的字符(base 大于10,那么A表示10...Z表示35)。
          如果endptr 不为NULL,strtol() 将第一个不合法字符的地址保存在*endptr中。如果根本没有数字,strtol()将字符
          串地址,也就是nptr 初始值保存到 *endptr,并返回0。特别的,如果*nptr不是'\0',但在返回时 **endptr是'\0',
          整个字符串是合法的。
          strtoll() 函数类似strtol(),但返回是long long 整型值。
返 回 值:strtol() 函数返回转换的结果,除非向下溢出(underflow)或向上溢出(overflow)。如果向下溢出,返回LONG_MIN。
          如果向上溢出返回LONG_MAX。两种情况的errno都会被设置为ERANGE。也可能返回0,在base 包含不被支持值时。
          strtoll()也一样(不过LLONG_MIN 和LLONG_MAX 替代LONG_MIN 和LONG_MAX)。
参考函数:atof(3), atoi(3), atol(3), strtod(3), strtoul(3)
          strtoul() 和strtol基本类似,只是返回无符号长整型。
例外说明:这些函数还有本地相关的类型。例如strtol_l(), strtoul_l() 等等。

函数原型:double strtod(const char *nptr, char **endptr);
          float strtof(const char *nptr, char **endptr);
          long double strtold(const char *nptr, char **endptr);
功能描述:strtod(), strtof(), 和strtold() 函数将nptr 指向开始的字符串转换成double,float 和long double 类型
          字符串期望格式开始于sispace() 可辨认的空格,可选正符‘+’号或负符号‘-’,然后是小数,或16进制小数,
          无限值(infinity),或NAN(not-a-number)。
          小数包含非空系列十进制数字,可能包含一个基数字符(小数点,和本地环境有关,通常为'.'),然后跟着十进制
          指数(exponent)。十进制指数包含一个'E'或'e',跟着正负号,非空十进制数字序列,乘幂为10。
          十六进制小数包含"0x"或"0X",跟着非空16进制小数数字系列,可能包含一个基数字符(同上),然后跟着二进制
          指数。二进制指数包含'P'或'p',跟着可选正负号,跟着非空数字(decimal digits)系列,乘幂为2。最少有一个
          基数字符和二进制指数出现。
          无限表示为"INF" 或"INFINITY"。为忽略类型。
          "NAN" 也是忽略类型,跟着'(',一系列字符,跟着')'。字符串指定和系统实现NAN的方式有关。
返 回 值:如果有转换,就返回转换值。如果endptr 为非NULL,*endptr 指向最后一个被转换字符的后面。
          如果没有转换,返回0,nptr的值保存到*endptr(referenced by endptr)。
          如果正确值导致向上溢出,根据数值的符号返回正或负的HUGE_VAL(HUNGE_VALF, HUGE_VALL),errno被设置为ERANGE。
          如果导致相信溢出,返回0,errno 被设置为ERANGE。
参考函数:atof(3), atoi(3), atol(3), strtol(3), strtoul(3)

函数原型:char *ecvt(double number, int ndigits, int *decpt, int *sign);
          char *fcvt(double number, int ndigits, int *decpt, int *sign);
功能描述:ecvt() 函数将number 转换为一个包含ndigits个数字以null终止的字符串。并返回指向字符串的指针。高顺序位数字为非0,
          除非number 为0。字符串不包含小数点;但是小数点相对于字符串开始位置保存于*decpt 中。*decpt 为负值,意味着小数点
          位于字符串开始的左边。如果number的符号为负,*sign 被设置为非0, 否则设置成0;如果number 是0,不指定*decpt 是0 或1。
          fcvt() 与ecvt() 相同,只是ndigits 指定小数点后的数字数量。
返 回 值:返回一静态字符串指针,字符串为ASCII 表示的数字。不可以线程重入。
参考函数:ecvt_r(3), gcvt(3), qecvt(3), setlocale(3), sprintf(3)

函数原型:long a64l(char *str64);
          char *l64a(long value);
功能描述:这两个函数提供32-bit 长整型和little-endian 64进制的ASCII 字符串(长度从0到6)转换。
          如果str64 长度大于6,那只用前6字节。如果value大于32-bit,那只用value的低32位。a64l对结果符号扩展。
          '.' 代表0,'/'代表1,0-9 代表2-11,A-Z 代表12-37,a-z 代表38-63, 和网络版本的64-encode 不同。
          所以有123 = 59*64^0 + 1*64^1 = "v/"。
返 回 值:返回相应的值。



下面是一个Linux manual 中的example 代码:

       #include <stdlib.h>
       #include 
<limits.h>
       #include 
<stdio.h>
       #include 
<errno.h>

       
int main(int argc, char *argv[])
       {
           
int base;
           
char *endptr, *str;
           
long val;

           
if (argc < 2) {
               fprintf(stderr, 
"Usage: %s str [base]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           str 
= argv[1];
           
base = (argc > 2? atoi(argv[2]) : 10;

           errno 
= 0;    /* 为了区分调用是否成功 */
           val 
= strtol(str, &endptr, base);

           
/* 检测各种可能的错误,溢出或base 包含非法值 */
           
if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
                   
|| (errno != 0 && val == 0)) {
               perror(
"strtol");
               exit(EXIT_FAILURE);
           }

           
if (endptr == str) {
               fprintf(stderr, 
"No digits were found\n");
               exit(EXIT_FAILURE);
           }

           
/* 如果能达到这里,strtol 成功解析了一个数字 */
           printf(
"strtol() returned %ld\n", val);

           
if (*endptr != '\0')        /* Not necessarily an error */
               printf(
"Further characters after number: %s\n", endptr);

           exit(EXIT_SUCCESS);
       }

atoi() 和strtol() 函数调用的区别:
atoi() 没有错误检测。而strtol()是有错误检测的。
atoi() 不能指定进制基数,一定是10进制;strtol() 可以由base 指定其他进制的。

手册提供测试数据和结果            $ ./a.out 123
           strtol() returned 123
           $ ./a.out '    123'
           strtol() returned 123
           $ ./a.out 123abc
           strtol() returned 123
           Further characters after number: abc
           $ ./a.out 123abc 55
           strtol: Invalid argument
           $ ./a.out ''
           No digits were found
           $ ./a.out 4000000000
           strtol: Numerical result out of range



posted on 2009-10-09 21:07 无声无色 阅读(1292) 评论(0)  编辑 收藏 引用 所属分类: 语言基础


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理