数据类型转换 小总结

提问:将一个字符串转换成一个整型数有多少种方式?

C语言的课堂上,可能会采取以下算法:

将字符串中的每一个字符提取出来,然后进行计算,然后将会得到你所想要的整型数。当然在这个函数中还要考虑字符串中的数字的进制问题,例如将字符串“0x1234abcd”转换成整型数则首先还要考虑它是十六进制的数。当然也还要考虑其他的问题,一共有一下几类:

1.       非法字符问题

2.       进制问题,用户可以指定任何进制

3.       整型数的越界问题

其他类型之间的转换需要注意的问题更多。

 

其实在C的标准库中已经给出了用于数据类型转换的函数,如下所示:

atof(将字符串转换成浮点型数)

atoi(将字符串转换成整型数)

atol(将字符串转换成长整型数)
gcvt
(将浮点型数转换为字符串,取四舍五入)

strtod(将字符串转换成浮点数)

strtol(将字符串转换成长整型数)

strtoul(将字符串转换成无符号长整型数)

toascii(将整型数转换成合法的ASCII 码字符)

tolower(将大写字母转换成小写字母)

toupper(将小写字母转换成大写字母)

sscanf (将字符串转换成任何类型)

sprintf  (将任意类型转换成字符串)

 

函数说明:

1.       字符串转换成整型或者浮点数atofatoiatolstrtod strtolstrtoul

这六个函数是将字符串转换成整型或者浮点数的函数。

前三个只是简单的转换,扫描参数中的字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('')才结束转换,并将结果返回。并不区分进制,也不返回错误。当遇到非法字符后函数返回因此无法判断是否含有非法字符,也无法判断是否越界。因此用户调用这三个函数之前需要自己去解决这些问题。

后三个函数会帮我们解决这些问题,以strtol为例:

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

a.       在该函数中nptr为待转换的字符串,endptr保存字符串中的第一个非法字符,base则决定进制。如 base值为10则采用10进制,若base值为16则采用16进制等。当base值为0时则是采用10进制做转换,但遇到如'0x'前置字符则会使用 16进制做转换。

b.       一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('')结束转换,并将结果返回。

c.       如果字符串中有非法字符则endptr指向第一个非法字符,如果没有非法字符则endptr指向字符串的结尾’/0’。判断**endptr的值可以判断是否有非法字符。

d.       如果该字符串所表示的数据上越界则返回LONG_MAX,下越界则返回LONG_MIN,并返回这两个值。鉴于无论正常结束转换还是越界都有可能返回这两个临界值,当越界时该函数会设置errnoERANGE。所以通过判断errno可以判断是否越界。(在调用前需要将errno设置为0

e.       当字符串中没有任何字符时将会返回0,鉴于无论正常结束转换还是没有任何数字都有可能返回0,当返回0时该函数会设置errnoEINVAL。所以通过判断errno可以判断是否真的是0

strtodstrtoulstrtol的用法类似。

例子:

#include <stdlib.h>

 #include <stdio.h>

 #include <errno.h>

 #include <string.h>

 int arg_strtol(char *arg, long int *arg_long);

  

 int main(int argc, char **argv)

 {

      char *arg = "0x1234";

      long arg_long;

      int ret = arg_strtol(argv[1], &arg_long);

      if (ret == -1)

          printf("%s bad arg/n", argv[1]);

      else if (ret == -2)

          printf("out of range/n");

      else

          printf("%d/n", arg_long);

      return 1;

  }

  

  int arg_strtol(char *arg, long int *arg_long)

  {

          char *endarg = 0;// = malloc(sizeof(char) * (strlen(arg) + 1));

          errno = 0;

          *arg_long = strtol(arg, &endarg, 0);

          if (*endarg != '/0')

              return -1;

          if (errno == 0)

              return 0;

          else

              return -2;

  }

2.       另一种将字符串转换成任意类型的函数:sscanf的妙用

sscanf() - 从一个字符串中读进与指定格式相符的数据.通过它可以得到任何你想要的数据类型。举一个最简单的例子

int main(int argc, char **argv)

 {

      long arg_long;

      int ret = sscanf(argv[1], "%d", &arg_long);

         printf("%d/n", arg_long);

      return 1;

  }

当运行时输入1234时,argv[1]即为字符串”1234”Sscanf将从这个字符串中读取一个格式为%d的数据,保存在arg_long中,即arg_long=1234;但是当运行输入123456789时明显越界,此时arg_long的值未定义即随机。

因此sscanf可以转换字符串为任意格式的数据,但是却不保证判断越界、以及进制的问题。

3.       其他类型的数据转换成字符串----gcvtecvtfcvt

将其他类型的数据转换成字符串相对而言比字符串转换成其他类型数据简单,因为不需要考虑到进制、越界等问题。用法如下

char *gcvt(double numbersize_t ndigitschar *buf);

函数说明:gcvt()用来将参数number转换成ASCII码字符串,参数ndigits表示显示的位数。gcvt()ecvt()fcvt()不同的地方在于,gcvt()所转换后的字符串包含小数点或正负符号。若转换成功,转换后的字符串会放在参数buf指针所指的空间。

返回值 :返回一字符串指针,此地址即为buf指针。

4.       另一种将其他类型的数据转换成字符串的方法----sprintf函数的妙用

sprintf 是个变参函数,定义如下:

int sprintf( char *buffer, const char *format [, argument] ... );

除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:格式化字符串上。

使用方法:

//把整数123 打印成一个字符串保存在s 中。

sprintf(s, "%d", 123); //产生"123"。即将整数123转换成了”123”

可以指定宽度,不足的左边补空格:

sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"

当然也可以左对齐:

sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"

它的所有的格式和printf相同。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值