前言
网上有很多关于strtod()函数的文章,不过大部分都是用strtod()函数转换一个字符
char *str = "111.11";
char *target;
double ret;
ret = strtod(str, &target);
很少有转换字符串的这样的用法
char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz";
本文主要参考strtod()函数, 只是对其中的代码示例进行解释,当然我理解示例代码时遇到了一点问题,在StackOverflow提问了以下,结果Barmar大神直接把代码解释了一遍,很佩服这位大神,StackOverflow版链接
代码分析
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
int main(void)
{
// parsing with error handling
const char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz";
printf("Parsing '%s':\n", p);
char *end;
for (double f = strtod(p, &end); p != end; f = strtod(p, &end))
{
printf("'%.*s' -> ", (int)(end-p), p);
p = end;
if (errno == ERANGE){
printf("range error, got ");
errno = 0;
}
printf("%f\n", f);
}
// parsing without error handling
printf("\" -0.0000000123junk\" --> %g\n", strtod(" -0.0000000123junk", NULL));
printf("\"junk\" --> %g\n", strtod("junk", NULL));
}
问题 1:
p = end //这条语句是干什么用的?
strtod()函数的参数:
double strtod( const char *str, char **str_end );
str
s
t
r
指向字符串的指针
end_str
e
n
d
_
s
t
r
指向指针的指针
在未调用strtod()函数前,打印字符串指针p
以及end
的地址
printf("%p\n", p);
printf("%p\n", end);
运行结果
0000000000408000
000000000000002D
接下来在执行循环时,打印p
和end
的地址
for (f = strtod(p, &end); p != end; f = strtod(p, &end))
{
printf("p addr = %p\n", p);
printf("end addr = %p\n", end);
printf("'%.*s' -> ", (int)(end-p), p);
p = end;
if (errno == ERANGE){
printf("range error, got ");
errno = 0;
}
//printf("%f\n", f);
}
输出
p addr = 0000000000408000
end addr = 0000000000408006
'111.11' -> 111.110000
p addr = 0000000000408006
end addr = 000000000040800C
' -2.22' -> -2.220000
p addr = 000000000040800C
end addr = 0000000000408010
' Nan' -> 1.#QNAN0
p addr = 0000000000408010
end addr = 0000000000408017
' nan(2)' -> 1.#SNAN0
p addr = 0000000000408017
end addr = 000000000040801B
' inF' -> 1.#INF00
p addr = 000000000040801B
end addr = 0000000000408030
' 0X1.BC70A3D70A3D7P+6' -> 111.110000
p addr = 0000000000408030
end addr = 000000000040803F
可以发现end
指针总会指向当前字符串中某一个字符的下一个字符,p
指针会指向当前字符串中某一个字符
因此p = end
这条语句实现了对字符串中的所有字符进行strtod()操作,而当for (f = strtod(p, &end); p != end; f = strtod(p, &end))
语句中的p = end
时,也即是没有字符需要进行strtod()操作了,就可以退出循环
问题2:
printf("'%.*s' -> ", (int)(end-p), p);
打印出的为什么是一系列字符,如:
'111.11'
' -2.22'
' Nan'
' nan(2)'
' inF'
' 0X1.BC70A3D70A3D7P+6'
' 1.18973e+4932'
(int)(end - p)
计算长度, %.*s
中的*
代表长度,也即是从当前字符串中选取多少个字符进行打印
示例代码:
#include<stdio.h>
int main ()
{
char *p = "Hello World!";
printf("length = 2 str = %.2s\n", p);
printf("length = 3 str = %.3s\n", p);
}
输出
length = 2 str = He
length = 3 str = Hel