关键词搜索

源码搜索 ×
×

C语言的本质(26)——C标准库之数值字符串转换

发布2014-07-17浏览2670次

详情内容

C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串

  1. #include <stdlib.h>
  2. 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用起来更简便,所以也很常用。

  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. int main(void)
  4. {
  5. floatn;
  6. char*str="12345.67";
  7. n= atoi(str);
  8. printf("string=%s integer=%f\n",str,n);
  9. return0;
  10. }

 
#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可以。

  1. #include<stdlib.h>
  2. int main()
  3. {
  4. char*a = "-100.23";
  5. char*b = "https://cdn.jxasp.com:9143/image/200e-2";
  6. doublec;
  7. c= atof(a) + atof(b);
  8. printf("c=%.2lf\n",c);
  9. return0;
  10. }


  1. #include <stdlib.h>
  2. 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。

 

  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. int main(void)
  4. {
  5. char*string,*stopstring;
  6. doublex;
  7. intbase;
  8. longl;
  9. unsignedlong ul;
  10. string="3.1415926This stopped it";
  11. x=strtod(string,&stopstring);
  12. printf("string=%s\n",string);
  13. printf("strtod=%f\n",x);
  14. printf("Stoppedscan at:%s\n",stopstring);
  15. string="-10110134932This stopped it";
  16. l=strtol(string,&stopstring,10);
  17. printf("string=%s\n",string);
  18. printf("strtol=%ld\n",l);
  19. printf("Stopped scan at:%s\n",stopstring);
  20. string="10110134932";
  21. printf("string=%s\n",string);
  22. for(base=2;base<=8;base*=2)
  23. {
  24. ul=strtoul(string,&stopstring,base);
  25. printf("strtol=%ld(base%d)\n",ul,base);
  26. printf("Stoppedscan at:%s\n",stopstring);
  27. }
  28. return0;
  29. }

 

回想一下使用fopen的套路if ( (fp = fopen(...)) == NULL) { 读取errno },fopen在出错时会返回NULL,因此我们知道需要读errno,但strtol在成功调用时也可能返回0x7fffffff,我们如何知道需要读errno呢?最严谨的做法是首先把errno置0,再调用strtol,再查看errno是否变成了错误码。ManPage上有一个很好的例子:

strtol的出错处理:

  1. #include <stdlib.h>
  2. #include <limits.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. int main(int argc, char *argv[])
  6. {
  7. intbase;
  8. char*endptr, *str;
  9. longval;
  10. if(argc < 2) {
  11. fprintf(stderr,"Usage: %s str [base]\n", argv[0]);
  12. exit(EXIT_FAILURE);
  13. }
  14. str= argv[1];
  15. base= (argc > 2) ? atoi(argv[2]) : 10;
  16. errno= 0;
  17. val= strtol(str, &endptr, base);
  18. if((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
  19. || (errno != 0 && val == 0)) {
  20. perror("strtol");
  21. exit(EXIT_FAILURE);
  22. }
  23. if(endptr == str) {
  24. fprintf(stderr,"No digits were found\n");
  25. exit(EXIT_FAILURE);
  26. }
  27. printf("strtol()returned %ld\n", val);
  28. if(*endptr != '\0')
  29. printf("Furthercharacters after number: %s\n", endptr);
  30. exit(EXIT_SUCCESS);
  31. }


  1. #include <stdlib.h>
  2. double strtod(const char *nptr, char **endptr);

strtod()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,到出现非数字或字符串结束时('\0')才结束转换,并将结果返回。若endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr传回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分。如123.456或123e-2。

  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. int main(void)
  4. {
  5. char *endptr;
  6. char a[] = "12345.6789";
  7. char b[] = "1234.567qwer";
  8. char c[] = "-232.23e4";
  9. printf( "a=%lf\n", strtod(a,NULL) );
  10. printf( "b=%lf\n", strtod(b,&endptr) );
  11. printf( "endptr=%s\n", endptr );
  12. printf( "c=%lf\n", strtod(c,NULL) );
  13. return0;
  14. }


 

相关技术文章

最新源码

下载排行榜

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载