C语言的本质(26)——C标准库之数值字符串转换
C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串。
#include <stdlib.h>
int atoi(const char *nptr);
atoi把一个字符串开头可以识别成十进制整数的部分转换成int型。参数nptr字符串,如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。否则,返回零,
例如atoi("123abc")的返回值是123,字符串开头可以有若干空格,例如atoi(" -90.6-")的返回值是-90。如果字符串开头没有可识别的整数,例如atoi("asdf"),则返回0,而atoi("0***")也返回0,根据返回值并不能区分这两种情况,所以使用atoi函数不能检查出错的情况。下面要讲的strtol函数可以设置errno,因此可以检查出错的情况,在严格的场合下应该用strtol,而atoi用起来更简便,所以也很常用。
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
floatn;
char*str="12345.67";
n= atoi(str);
printf("string=%s integer=%f\n",str,n);
return0;
}
#include <stdlib.h>double atof(const char *nptr);
atof把一个字符串开头可以识别成浮点数的部分转换成double型,相当于下面要讲的strtod(nptr, (char **) NULL);。字符串开头可以识别的浮点数格式和C语言的浮点数常量相同,例如atof("31.4")的返回值是31.4,atof("3.14e+1AB")的返回值也是31.4。atof也不能检查出错的情况,而strtod可以。
#include<stdlib.h>
int main()
{
char*a = "-100.23";
char*b = "200e-2";
doublec;
c= atof(a) + atof(b);
printf("c=%.2lf\n",c);
return0;
}
#include <stdlib.h>
long int strtol(const char *nptr, char**endptr, int base);
返回值:转换结果,出错时设置errnostrtol是atoi的增强版,主要体现在这几方面:
不仅可以识别十进制整数,还可以识别其它进制的整数,取决于base参数,比如strtol("0XDEADbeE~~", NULL, 16)返回0xdeadbee的值,strtol("0777~~",NULL, 8)返回0777的值。
endptr是一个传出参数,函数返回时指向后面未被识别的第一个字符。例如char *pos; strtol("123abc", &pos, 10);,strtol返回123,pos指向字符串中的字母a。如果字符串开头没有可识别的整数,例如char *pos; strtol("ABCabc", &pos, 10);,则strtol返回0,pos指向字符串开头,可以据此判断这种出错的情况,而这是atoi处理不了的。
如果字符串中的整数值超出long int的表示范围(上溢或下溢),则strtol返回它所能表示的最大(或最小)整数,并设置errno为ERANGE,例如strtol("0XDEADbeef~~", NULL, 16)返回0x7fffffff并设置errno为ERANGE。
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
char*string,*stopstring;
doublex;
intbase;
longl;
unsignedlong ul;
string="3.1415926This stopped it";
x=strtod(string,&stopstring);
printf("string=%s\n",string);
printf("strtod=%f\n",x);
printf("Stoppedscan at:%s\n",stopstring);
string="-10110134932This stopped it";
l=strtol(string,&stopstring,10);
printf("string=%s\n",string);
printf("strtol=%ld\n",l);
printf("Stopped scan at:%s\n",stopstring);
string="10110134932";
printf("string=%s\n",string);
for(base=2;base<=8;base*=2)
{
ul=strtoul(string,&stopstring,base);
printf("strtol=%ld(base%d)\n",ul,base);
printf("Stoppedscan at:%s\n",stopstring);
}
return0;
}
回想一下使用fopen的套路if ( (fp = fopen(...)) == NULL) { 读取errno },fopen在出错时会返回NULL,因此我们知道需要读errno,但strtol在成功调用时也可能返回0x7fffffff,我们如何知道需要读errno呢?最严谨的做法是首先把errno置0,再调用strtol,再查看errno是否变成了错误码。ManPage上有一个很好的例子:
strtol的出错处理:
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <errno.h> int main(int argc, char *argv[])
{
intbase;
char*endptr, *str;
longval; 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); 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);
} printf("strtol()returned %ld\n", val); if(*endptr != '\0')
printf("Furthercharacters after number: %s\n", endptr); exit(EXIT_SUCCESS);
}
#include <stdlib.h>
double strtod(const char *nptr, char **endptr);
strtod()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,到出现非数字或字符串结束时('\0')才结束转换,并将结果返回。若endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr传回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分。如123.456或123e-2。
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
char *endptr;
char a[] = "12345.6789";
char b[] = "1234.567qwer";
char c[] = "-232.23e4";
printf( "a=%lf\n", strtod(a,NULL) );
printf( "b=%lf\n", strtod(b,&endptr) );
printf( "endptr=%s\n", endptr );
printf( "c=%lf\n", strtod(c,NULL) );
return0;
}
C语言的本质(26)——C标准库之数值字符串转换的更多相关文章
- C标准库-数值字符串转换与内存分配函数
原文链接:http://www.orlion.ga/977/ 一.数值字符串转换函数 #include <stdlib.h> int atoi(const char *nptr); dou ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 标准库
C++ 标准库可以分为两部分: 标准函数库: 这个库是由通用的.独立的.不属于任何类的函数组成的.函数库继承自 C 语言. 面向对象类库: 这个库是类及其相关函数的集合. C++ 标准库包含了所有的 ...
- [C/C++标准库]_[初级]_[转换UTC时间到local本地时间]
场景 1.如果有面向全球用户的网站, 一般在存储时间数据时存储的是UTC格式的时间, 这样时间是统一的, 并可以根据当地时区来进行准确的转换. 2.存储本地时间的问题就在于如果换了时区, 那么显示的时 ...
- Go语言实现:【剑指offer】把字符串转换成整数
该题目来源于牛客网<剑指offer>专题. 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 输入描述: 输入一个字符串,包括数字字母符号,可以为空. 输出描述: 如果是合 ...
- C++标准库的数值极限numeric_limits
包含头文件:#include<limits> 它是一个模板类,它主要是把C++当中的一些内建型别进行了封装,比如说numeric_limits<int>是一个特化后的类,从这个 ...
- C 标准库 中 操作 字符串 的 代码
1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度 ...
- 【C语言】编写函数实现库函数atoi,把字符串转换成整形
//编写函数实现库函数atoi.把字符串转换成整形 #include <stdio.h> #include <string.h> int my_atoi(const char ...
- Boost程序库完全开发指南——深入C++“准”标准库(第3版)
内容简介 · · · · · · Boost 是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉. Boost 由C++标准委员会部分成员所设立的Bo ...
- Python标准库、第三方库和外部工具汇总
导读:Python数据工具箱涵盖从数据源到数据可视化的完整流程中涉及到的常用库.函数和外部工具.其中既有Python内置函数和标准库,又有第三方库和工具. 这些库可用于文件读写.网络抓取和解析.数据连 ...
随机推荐
- 运行时数据区即内存分配管理——JVM之六
内存分配结构,请参考: http://iamzhongyong.iteye.com/blog/1333100
- 用来控制 XML 序列化的属性
通过将下表中的属性应用于类和类成员,可以控制 XmlSerializer 序列化或反序列化该类的实例的方式.若要了解这些属性如何控制 XML 序列化,请参见使用属性控制 XML 序列化. 这些属性还可 ...
- curl 浏览器模拟请求实战
1,curl 常用选项
- 总结FormsAuthentication的使用
一.先看一下使用FormsAuthentication做登录认证的用法 用法一: FormsAuthentication.SetAuthCookie(username, isPersistent); ...
- 执行此安装程序之前,必须安装 32 位 Windows 映像处理组件(WIC)解决的方法
我们在Windows Service 2003上安装 Microsoft .NET Framework4.0时常常出现以下的报错 执行此安装程序之前,必须安装 32 位 Windows 映像处理组件( ...
- dom4j解析XML的CURD操作
在开发JavaWeb项目中通常是利用XML配置文件来提高应用程序的访问效率,而在配置XML的同时,更多时候是对XML进行解析. 一.解析XML配置文件有两种机制: DOM和SAX的机制: DOM是将整 ...
- Velocity.js发布:更快的动画切换速度
Velocity.js是一款动画切换的jQuery插件,它重新实现了jQuery的$.animate()方法从而加快动画切换的速度.Velocity.js只有7k的大小,它不仅包含了$.animate ...
- 由闭包引起的对javascript代码可维护性的思考
在最近的编程实践中由闭包的使用引起了我对javascript代码可维护性的思考.面向对象的其中一个特性封装性通过封装可以降低类与类之间或模块与模块之间耦合性从而使我们的设计更加高内聚低耦合,在大规模的 ...
- 登陆权限验证Session和Cookie用法及BasePage类使用
最近在做ASP.NET的项目时,接触到了登陆权限模块,所有总结了一下登陆时用到的知识和方法技巧. 如图说明:实现的效果如图,由于验证码验证比较简单这里就不介绍了 首先用代码生成器生成项目,以三层为例进 ...
- <runtime> 的 <assemblyIdentity> 元素和<bindingRedirect> 元素
1.<assemblyIdentity> 元素 包含关于该程序集的标识信息. <assemblyIdentity name="assembly name" pub ...