C Primer Plus 第11章 11.9 把字符串转换为数字

数字即能以字符串形式也能 以数字形式存储。以字符串形式存储数字就是存储数字字符。例如,数字213即能以数字'2'、‘1’、‘3’、‘\0’的形式存储在一个字符串数组中。以数字形式存储213意味着把字存储为 一个int数值。对于数字运算C要求数字形式。可是在屏幕上显示数字却要求字符串形式,这是由于屏幕显示的字符。printf()和sprintf()函数经过%d或其余说明符把数字形式转换为字符串形式或者相反。C还有一些函数专门用于把字符串形式转换为数字形式。
假如,您想编写一个使用数字命令程序。很不巧的是,命令行参数是以字符串形式被读取的。所以,要想使用数字值,就必须先把字符串转换为数字。若是数字是个整数,那就可使用atoi()(表明alphanumeric to integer)。atoi()函数以字符串为参数,返回相应的整数值。
程序清单11.28 hello.c程序
 数组

/*hello.c  把命令行参数转换成数字*/
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
    int i,times;

    if(argc<2 || (times = atoi(argv[1]))<1)
        printf("Usage: %s positive-number\n",argv[0]);
    else
    for(i=0;i<times;i++)
        puts("Hello,good looking!");
    
    return 0;
}

下面是一个运行示例:
% hello 3
Hello,good looking!
Hello,good looking!
Hello,good looking!
%是UNIX提示符。命令行参数3以字符串"3\0"的形式存放。atoi()函数把这个字符串转换为整数3.而后把3赋给times。这样就决定了for循环执行的次数。函数

若是运行程序时没有提供命令行参数,argc<2判断就会中断程序并给出一个提示信息。若是times为0或为负,也会发生一样的状况。C的逻辑运算符的运算顺序确保:若是argc<2,就再也不运算atoi(argv[1])。ui

若是字符串只是以一个整数开头,atoi()函数仍然能够工做。这种状况下,atoi()函数遇到非整数部分以前一直转换字符。例如,atoi("42regular")返回整数42。若是命令行相似hello what,又会出现什么状况呢?在咱们使用的C的实现上,若是参数不能识别为数字,atoi()函数返回一个0值。但ANSI标准规定,上述状况下的行为是未定义的。稍后咱们将介绍strtol()函数能够提供更可靠的错误检测。atom

咱们包含了stdlib.h头文件,这是由于在ANSI中这个文件包含了atoi()函数的声明。此外,这个头文件还包含了atof()和atol()函数的声明。atof()函数把一个字符串转换为double类型的值,atol()函数则把字符串转换为long类型的值。它们的做用和atoi()相似,所以分别为double和long类型。命令行

ANSI C 提供了这些函数的更复杂版本:strtol()、strtoul()和strtod()。其中,strtol()函数把一个字符串转换为long值,strtoul()把一个字符串转换为unsigned long型值,strtod()函数把一个字符串转换为double型值。这些函数的复杂性在于它们还能够识别并报告字符串中非数字部分的第一个字符。strtol()和strtoul()函数还容许您指定数字的基数。指针

下面看一个涉及strtol()函数的例子。函数原型以下:code

long strtol(const char *nptr, char **endptr, int base);字符串

在这里,nptr是一个指向您但愿转换的字符串的指针endptr是指向标志输入数字的结束字符的指针的地址,base是数字的基数。get

程序清单 11.29 strcnvt.c程序原型

/*strcnvt.c  尝试使用strtol()函数*/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char number[30];
    char *end;
    long value;

    puts("Enter a number(empty line to quit): ");
    while(gets(number) && number[0]!='\0')
    {
        value=strtol(number,&end,10);
        printf("value:%ld, stopped at %s(%d) \n",
               value,end,*end);
        value=strtol(number,&end,16);  /*基于16*/
        printf("value:%ld, stopped at %s(%d) \n",
               value,end,*end);
        puts("Next number: ");
    }
    puts("Bye!\n");

    return 0;
}

下面是一些输出示例:
Enter a number(empty line to quit):
10
value:10, stopped at (0)
value:16, stopped at (0)
Next number:
10atom
value:10, stopped at atom(97)
value:266, stopped at tom(116)
Next number:
    
Bye!

首先请注意:若是基数是10,字符串“10”就被转换为10;若是基数是16,字符串”10“就被转换为16。还要注意,若是end指向一个字符,那么*end就是一个字符。所以,第一次转换在遇到空字符时结束,这样end就指向空字符。若是输出end,会显示一个空字符,若是用%d格式输出*end,就会显示空字符的ASCII 码。

对于输入的第二个字符串(以10为基数进行解释),end是'a'字符的地址所以,输出end显示的是字符串"atom"输出*end显示的则是'a'字符的ASCII码。可是,若是基数是16,'a'字符就会被识别为一个有效的十六进制数字,函数会把16进制10a转换为十进制的266。

strtol()函数最多能够有三十六进制,使用一直到'z'的字母做为数字。strtoul()函数也同样,但它转换的是无符号值。strtod()函数只按照十进制进行转换,所以它只使用两个参数。

不少实现中都使用itoa()和ftoa()函数把整点和浮点数转换为字符串。可是这两个函数并非ANSI C库里的函数;若是要求兼容性更好,可使用sprintf()函数来完成这些功能 。

相关文章
相关标签/搜索