zoukankan      html  css  js  c++  java
  • C语言的本质(26)——C标准库之数值字符串转换

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

    #include <stdlib.h>
    int atoi(const char *nptr);
    
    

    atoi把一个字符串开头可以识别成十进制整数的部分转换成int型。参数nptr字符串,如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符 ) 字符时停止转换,返回整型数。否则,返回零,

    例如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
    ",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
    ",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
    ",string);
             printf("strtod=%f
    ",x);
             printf("Stoppedscan at:%s
    ",stopstring);
             string="-10110134932This stopped it";
             l=strtol(string,&stopstring,10);
             printf("string=%s
    ",string);
             printf("strtol=%ld
    ",l);
             printf("Stopped scan at:%s
    ",stopstring);
             string="10110134932";
             printf("string=%s
    ",string);
             for(base=2;base<=8;base*=2)
             {
                       ul=strtoul(string,&stopstring,base);
                       printf("strtol=%ld(base%d)
    ",ul,base);
                       printf("Stoppedscan at:%s
    ",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]
    ", 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
    ");
                       exit(EXIT_FAILURE);
             }
     
             printf("strtol()returned %ld
    ", val);
     
             if(*endptr != '')  
                       printf("Furthercharacters after number: %s
    ", endptr);
     
             exit(EXIT_SUCCESS);
    }


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

    strtod()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,到出现非数字或字符串结束时('')才结束转换,并将结果返回。若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
    ", strtod(a,NULL) );
       printf( "b=%lf
    ", strtod(b,&endptr) );
       printf( "endptr=%s
    ", endptr );
       printf( "c=%lf
    ", strtod(c,NULL) );
             return0;
    }


  • 相关阅读:
    linux权限补充:rwt rwT rws rwS 特殊权限
    关于Linux操作系统下文件特殊权限的解释
    Java学习笔记——Java程序运行超时后退出或进行其他操作的实现
    Java实现 蓝桥杯 算法提高 判断名次
    Java实现 蓝桥杯 算法提高 判断名次
    Java实现 蓝桥杯 算法提高 日期计算
    Java实现 蓝桥杯 算法提高 日期计算
    Java实现 蓝桥杯 算法提高 概率计算
    Java实现 蓝桥杯 算法提高 概率计算
    Java实现 蓝桥杯 算法提高 复数四则运算
  • 原文地址:https://www.cnblogs.com/new0801/p/6177069.html
Copyright © 2011-2022 走看看