接口:static const char *parse_number(cJSON *item,const char *num)
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
if (*num=='-') sign=-1,num++; /* Has sign? */
if (*num=='0') num++; /* is zero */
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
if (*num=='e' || *num=='E') /* Exponent? */
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
}
//<math.h>;double pow(double x,double y);返回x的y次方的值
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
return num;
}
int main(){
const char *num = "31.4e-2";
char * jsonStr =NULL;
cJSON * pTest = cJSON_CreateObject();
parse_number(pTest,num);
jsonStr = cJSON_Print(pTest);
cJSON_Delete(pTest);
printf("jsonStr: %s\n",jsonStr);
free(jsonStr);//千万注意释放
return 0;
}
输出:jsonStr: 0.314000
接口:static int pow2gt (int x)
//返回比x大的最小的2的N次方数,运行后相当于二进制从最左边第一个非零的数开始,往右都为1,然后再加上1
static int pow2gt (int x) { --x; x|=x>>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; return x+1; }
int main(){
printf("Test CJson: %d\n",pow2gt(-10));
return 0;
}
输出:0
printbuffer和ensure,从Cjson代码看printbuffer一直赋的NULL,也就是未实际使用
typedef struct {char *buffer; int length; int offset; } printbuffer;
static char* ensure(printbuffer *p,int needed)
{
char *newbuffer;int newsize;
if (!p || !p->buffer) return 0; // 判断p是否存在
needed+=p->offset; // 所需空间 = 输入大小+偏移量(已使用)
if (needed<=p->length) return p->buffer+p->offset; // 所需小于容量,p中空间充足
// 所需大于容量时,重新分配空间:
newsize=pow2gt(needed);
newbuffer=(char*)cJSON_malloc(newsize); // 创建一个新buffer
if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;} // 创建失败
if (newbuffer) memcpy(newbuffer,p->buffer,p->length); // 创建成功
cJSON_free(p->buffer); // 释放老buffer并将其新的作为当前可用buffer p
p->length=newsize;
p->buffer=newbuffer;
return newbuffer+p->offset;
}
//使item中的数值巧妙的转换为字符串
static char *print_number(cJSON *item,printbuffer *p)
{
char *str=0;
double d=item->valuedouble;
if (d==0) //对应数值为0
{
if (p) str=ensure(p,2);
else str=(char*)cJSON_malloc(2); /* special case for 0. */
if (str) strcpy(str,"0");//将0赋值给字符串str
}
//DBL_EPSILON: 2.220446049250313080847e-16
//#define INT_MAX 2147483647 #define INT_MIN (-INT_MAX - 1)
//这里没有简单地将INT_MIN赋值成-2147483647,是因为-2147483648对于编译器而言是个表达式,而2147483648对于32-bit整数是无法表示的,
//所以经过这个表达式的结果是未定义的。在GCC上直接写-2147483648后,编译器给出了警告,说结果是unsigned。
// 若int型数据和double型数据差别足够小且数据大小在INT_MAX INT_MIN之间
else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)//C 库函数 double fabs(double x) 返回 x 的绝对值
{
if (p) str=ensure(p,21);
else str=(char*)cJSON_malloc(21); /* 2^64[18,446,744,073,709,551,616] +1[结束符] can be represented in 21 chars. */
if (str) sprintf(str,"%d",item->valueint);
}
//对编程人员来说,double 和 float 的区别是 double 精度高,算上符号位有效数字 16 位[指的小数点后10进制数的个数],float 精度 7 位。
//但 double 消耗内存是 float 的两倍,double 的运算速度比 float 慢得多,C 语言中数学函数名称 double 和 float 不同,不要写错,
//能用单精度时不要用双精度(以省内存,加快运算速度)
//float 是 32位, 其中有23位用于存放尾数, 带有一个固定隐含符号位.. 所以float的有24个二进制有效位位数,
//2^24共有8个十进制位. 所以有些编译器 float的有效数字位是 8位 , 有些有效数字位是 7位.(注意不是小数的位数, 是有效数字位)
//double也一样,是64位, 其中有52位用于存放尾数, 一个固定隐含位. 共有 53个二进制有效位位数.
//2^53次方有15个十进制位, 所以有些编译器double的有效数字位是15位, 有些是16位
else
{
if (p) str=ensure(p,64);
else str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
if (str)
{
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
else sprintf(str,"%f",d);
}
}
return str;
}
int main(){
cJSON * testCJson = cJSON_CreateNumber(12.257902012398878);
printf("testCJson: %s \n",print_number(testCJson,0));
float a=12.257902612398877;
double b=12.257902612398877;
printf("float a= %f\n",a);
printf("double b= %lf\n",b);
return 0;
}
输出结果:
testCJson: 12.257902
float a= 12.257902
double b= 12.257903
parse_hex4:将4个字符的字符串转变为两个字节的数字:
static unsigned parse_hex4(const char *str)
{
unsigned h=0;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
return h;
}
int main(){
char* a="abcd";
printf("parse_hex4 = %x\n",parse_hex4(a));
return 0;
}
输出:float = abcd