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