文档章节

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

idreamo
 idreamo
发布于 2016/08/29 06:19
字数 1514
阅读 43
收藏 0

数字即能以字符串形式也能 以数字形式存储。以字符串形式存储数字就是存储数字字符。例如,数字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])。

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

我们包含了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()函数的例子。函数原型如下:

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

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

程序清单 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()函数来完成这些功能 。

© 著作权归作者所有

idreamo
粉丝 18
博文 139
码字总数 224743
作品 0
青岛
产品经理
私信 提问
关东升的《从零开始学Swift》第2版已经出版

关东升的《从零开始学Swift》第2版已经出版 大家好: 苹果2015WWDC大会发布了Swift2.0,它较之前的版本Swift1.x有很大的变化,所以我即将出版《从零开始学Swift》 《从零开始学Swift》将在《...

tony关东升
2016/02/24
0
0
C Primer Plus 第11章 11.7 ctype.h字符函数和字符串

第7章“C控制语句 分支和跳转”介绍了ctype.h系列字符相关的函数。这些函数不能被 应用于整个字符串,但是可以被应用于字符串中的个别字符。程序清单11.26定义了一个函数,它把toupper( )函数...

idreamo
2016/08/27
52
0
关东升的《从零开始学Swift》3月9日已经上架

大家一直期盼的《从零开始学Swift》于3月9日已经上架,它是关东升老师历时8个月的呕心沥血所编著,全书600多页,此本书基于Swift 2.x,通过大量案例全面介绍苹果平台的应用开发。全书共分5 部...

智捷课堂
2016/03/11
46
0
C Primer Plus 第11章 字符串和字符串函数 11.3 字符串输出

11.3.1 puts( )函数 puts( )函数的使用很简单,只需要给出字符串参数的地址。程序清单11.8列出了输出字符串的多种方式。 程序清单11.8 put_out.c程序 输出如下: 注意,每个字符串都单行显示...

idreamo
2016/08/19
20
0
关东升的《从零开始学Swift》3月9日已经上架

大家一直期盼的《从零开始学Swift》于3月9日已经上架,它是关东升老师历时8个月的呕心沥血所编著,全书600多页,此本书基于Swift 2.x,通过大量案例全面介绍苹果平台的应用开发。全书共分5 部...

tony关东升
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

postman批量测试

postman批量调用: 先单个调用,成功了 再save为collection 再点击三角形,点击run 设置1000次,run就可以 见《postman批量测试.docx》

Danni3
12分钟前
3
0
js 对象操作 js 对象和对象赋值 去除关联性 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象

当我们在项目需要 复制一个对象到另一个对象并且 被复制的对象不能受复制后的对象的影响。 我先总结下 我们哪些方法可以复制对象 // 直接赋值var obj1 = { a: 1 };var obj2 = obj1;...

xiaogg
13分钟前
1
0
Go微服务全链路跟踪详解

在微服务架构中,调用链是漫长而复杂的,要了解其中的每个环节及其性能,你需要全链路跟踪。 它的原理很简单,你可以在每个请求开始时生成一个唯一的ID,并将其传递到整个调用链。 该ID称为C...

倚天码农
27分钟前
1
0
QML笔记-对QML中信号与槽的基本认识

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq78442761/article/details/90753986 目录 基本概念 演示...

shzwork
34分钟前
2
0
SSH安全加强两步走

从 OpenSSH 6.2 开始已经支持 SSH 多因素认证,本文就来讲讲如何在 OpenSSH 下启用该特性。 OpenSSH 6.2 以后的版本多了一个配置项 AuthenticationMethods。该配置项可以让 OpenSSH 同时指定...

xiangyunyan
52分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部