9-2 字符串与其他数值类型的转换

1. 字符串类型如何转换为其他类型(例如 int,double 等)?

        可以使用 atof,atoi,atol,atoll,_atoi64 将字符串分别转化为 double,int,long,long long,__int64 类型的数据。源码如下:

        试验 atoi() 函数,可以发现该函数会忽略开头的空格,遇见字符不能转化为数字的会直接停止,且不能转换十六进制的数:atoi("0x10") 结果为 0

#include <stdio.h>
#include <stdlib.h>

int main() {

  printf("%d\n", atoi("1234"));   // 1234
  printf("%d\n", atoi("-1234"));  // -1234
  printf("%d\n", atoi("  12 34abcd12"));  // 12
  printf("%d\n", atoi("0x10"));   // 0
  printf("%d\n", atoi("  a1234abcd12"));  // 0  

  return 0;
}

        试验 atof 函数:会忽略开头的空格,且遇见字符不能转化为数字的会直接停止。此外,atof() 函数可以转化 16 进制字符。但仅 msvc 编译器支持。 gcc 编译器下,atof 函数没有该功能 ,即 atof("0x10")) 和 atof("0x10p3.9")) 的输出结果仍旧为 0.000000。

// msvc 编译器的结果
printf("%f\n", atof("1234"));           // 1234.000000
printf("%f\n", atof("-12e34"));         // -120000000000000007304085773727301632.000000
printf("%f\n", atof("  12 34abcd12"));  // 12.000000
printf("%f\n", atof("  a1234abcd12"));  // 0.000000
printf("%f\n", atof("0x10"));           // 16.000000

// 16进制数仿照十进制使用科学计数法(a*10^n)的例子
// 0x10就是a,而后面p跟着的不是10^n,是2^n,n必须为整数,所以这里n=3.9会自动被当为n=3,16*8=128
printf("%f\n", atof("0x10p3.9"));       // 128.000000

2. 字符串类型如何转换为其他类型(非 atoi() 系列函数)?

        和 atoi() 系列函数类似的有 strtol() 系列函数。注意,strtoi() 函数是没有的。strtol() 系列函数大致如下:

3. atoX 函数和 strtoX 的区别

        atoX 函数使用简单, strtoX 使用复杂。但 strtoX 有更多的功能:

        1)当字符串转化为数字类型失败时,strtoX 可以用 errno(error number) 来获取转化失败的数值代码,并会返回待转换类型对应的边界值

        2)strtoX 可以指定转换为多少进制的整数;

        3)strtoX 允许一个字符多次转换,这符合一个字符串中包含多个数字需要解析的场景。不同于 atoX 遇到不能解析的字符直接停止("a123" 这种类型的字符,atoi() 函数会返回 0,但strtoX 函数可以返回 123)。

4. strtoX 函数的具体使用

        strtol() 函数,接收三个参数,字符起始地址(start),一个字符指针的指针(end),以及进制(10)。大致使用流程为:首先 start 位于起始地址,然后去读取字符,读到不能转换数字的字符为止,并将此处的地址赋值给 end。读取的字符处理后,将 end 赋值给 start,重复上述操作。一旦函数使用后,end 值未发生变化,说明字符读取结束。

#include <stdio.h>
#include <stdlib.h>

int main() {

  char const *const KInput = "1 200000000000000000000000000000000000 3 -4 5abcd bye 122";

  printf("%s", KInput);

  char const *start = KInput;
  char *end; // 注意,这里不用赋值,函数内部会修改 end 的值

  while(1){

    // 从start位置开始,读取到end位置,然后继续end位置。读取进制为10进制
    long value = strtol(start, &end, 10);

    // 如果 strtol() 使用后,end指针位置不变,说明能读取的都读取了
    if(start == end){
      break;
    }

    // 读出来的内容打印看下
    printf("\n内容:%ld", value);

    // 读取一个后,以end作为起始点
    start = end;
  }

  return 0;
}

        代码结果如下。可以发现,对于中间过长的 200...而言,strtol() 函数返回了 long 类型的边界值,2147483647 (2^31-1)。此外,bye 后面的 122 数字无法读取,因为 end 在 abcd 处就无法前进了。

深入理解 char *, char **, char a[ ], char *a[ ] 的区别:https://blog.csdn.net/liusicheng2008_liu/article/details/80412586

strtol()详解:https://blog.csdn.net/zxx2096/article/details/81127858

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值