预计阅读本页时间:-
数字既能以字符串形式也能以数字形式存储。以字符串形式存储数字就是存储数字字符。例如,数字213能以数字‘2’、‘1’、‘3’、‘\0’的形式存储在一个字符串数组中。以数字形式存储213意味着把它存储为一个int数值。
对于数字运算(比如加法运算和比较运算)C要求数字形式。但是在屏幕上显示数字却要求字符串形式,这是因为屏幕显示的是字符。printf()和sprintf()函数通过%d或其他说明符把数字形式转换为字符串形式或者相反。C还有一些函数专门用于把字符串形式转换为数字形式。
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
例如,假定您想编写一个使用数字命令行参数的程序。很不巧的是,命令行参数是以字符串形式被读取的。因此,要想使用数字值,就必须先把字符串转换为数字。如果数字是个整数,那就可以使用atoi() (代表alphanumeric to integer)函数。atoi()函数以字符串为参数,返回相应的整数值。程序清单11.28就是个例子。
程序清单11.28 hello.c程序
下面是一个运行示例:
%是UNIX提示符。命令行参数3以字符串“3\0”的形式存放。atoi()函数把这个字符串转换为整数3,然后把3赋给times。这样就决定了for循环执行的次数。
如果运行程序时没有提供命令行参数,argc<2判断就会中断程序并给出一个提示信息。如果times为0或为负,也会发生同样的情况。C的逻辑运算符的运算顺序规则确保:如果argc<2,就不再运算atoi(argv[1])。
如果字符串只是以一个整数作为开头,atoi()函数仍然可以工作。在这种情况下,atoi()函数在遇到非整数部分之前一直转换字符。例如,atoi(”42regular”)返回整数42。如果命令行类似hello what,又会出现什么情况呢?在我们使用的C实现上,如果参数不能识别为数字,atoi()函数返回一个0值。但ANSI标准规定,上述情况下的行为是未定义的。稍后我们将简要介绍的strtol()函数可以提供更可靠的错误检测。
我们包含了stdlib.h头文件,这是因为在ANSI C中这个文件包含了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()函数的例子。函数原型如下:
在这里,nptr是一个指向您希望转换的字符串的指针,endptr是指向标志输入数字的结束字符的指针的地址,base是数字的基数。程序清单11.29中的例子更清楚地表明了这些。
程序清单11.29 strcnvt.c程序
下面是一些输出示例:
首先请注意:如果基数是10,字符串“10”就被转换为10;如果基数是16,字符串“10”就被转换为16。还要注意,如果end指向一个字符,那么*end就是一个字符。因此,第一次转换在遇到空字符时结束,这样end就指向空字符。如果输出end,会显示一个空字符串,如果用%d格式输出*end,就会显示空字符的ASCII码。
对于输入的第二个字符串(以10为基数进行解释),end是‘a’字符的地址。因此,输出end显示的是字符串“atom”,输出*end显示的则是‘a’字符的ASCII码。但是,如果基值变为16,‘a’字符就会被识别为一个有效的十六进制数字,函数会把十六进制数10a转换为十进制的266。
strtol()函数最多可以有三十六进制,使用一直到‘z’的字母作为数字。strtoul()函数也一样,但它转换的是无符号值。strtod()函数只按照十进制进行转换,因此它只使用两个参数。
很多实现中都用itoa()和ftoa()函数把整数和浮点数转换为字符串。但是,这两个函数并不是ANSI C库里的函数;如果要求兼容性更好,可以使用sprintf()函数来完成这些功能。