将逗号分隔的双精度字符串转为数组:如何保持精度?
JSON-C v0.11 保留双精度数字原始格式输出的解决方案
问题描述
使用JSON-C Library v0.11生成JSON时,需要将逗号分隔的双精度数字字符串转为数组输出。现有字符串:
const char* doubles = "0.1234, 0.5678, 1.1234, 1.5678";
期望输出的JSON数组为:
"doubles": [0.1234, 0.5678, 1.1234, 1.5678]
但使用json_object_new_double时,库会自动为数字添加尾随零,无法保留原始格式。现有处理代码如下:
char *token = strtok(doubles, ","); while (token != NULL) { double current = atof(token); json_object_array_add(my_array, json_object_new_double(current)); token = strtok(NULL, ","); } // Add the key-value pair as an array json_object_object_add(root_obj, "my_array", my_array);
解决方案
方法1:直接解析原始数字字符串为JSON对象
将字符串转为double时会丢失原始格式信息,甚至可能引入精度误差。可以跳过atof转换,直接将修剪后的数字字符串解析为JSON数字对象:
#include <string.h> #include <ctype.h> #include <json/json.h> // 去除字符串两端空格的辅助函数 char* trim_whitespace(char* str) { while (isspace((unsigned char)*str)) str++; if (*str == 0) return str; char* end = str + strlen(str) - 1; while (end > str && isspace((unsigned char)*end)) end--; end[1] = '\0'; return str; } // 核心处理逻辑 char *token = strtok((char*)doubles, ","); while (token != NULL) { char* trimmed = trim_whitespace(token); // 直接解析原始字符串为JSON数字对象 json_object* num_obj = json_object_parse(trimmed); if (num_obj != NULL) { json_object_array_add(my_array, num_obj); } token = strtok(NULL, ","); } json_object_object_add(root_obj, "doubles", my_array);
此方法生成的JSON数组会严格保留原始数字的格式,不会添加多余的尾随零。
方法2:自定义double类型序列化函数
如果必须先将字符串转为double类型,可以通过自定义序列化函数控制输出格式,需要提前保存每个数字的原始字符串:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <json/json.h> // 自定义序列化函数:使用原始字符串输出数字 int custom_double_serialize(struct json_object* obj, struct json_object_serializer* ser, struct json_object* jso, int depth) { const char* original_str = json_object_get_userdata(obj); if (original_str) { return json_object_serializer_string(ser, original_str, strlen(original_str)); } // 若获取不到原始字符串,使用默认序列化逻辑 return json_object_double_serialize(obj, ser, jso, depth); } // 去除字符串两端空格的辅助函数 char* trim_whitespace(char* str) { while (isspace((unsigned char)*str)) str++; if (*str == 0) return str; char* end = str + strlen(str) - 1; while (end > str && isspace((unsigned char)*end)) end--; end[1] = '\0'; return str; } // 核心处理逻辑 char *token = strtok((char*)doubles, ","); while (token != NULL) { char* trimmed = trim_whitespace(token); double current = atof(trimmed); json_object* num_obj = json_object_new_double(current); // 将原始字符串保存到JSON对象的userdata中 json_object_set_userdata(num_obj, strdup(trimmed)); // 设置自定义序列化函数 json_object_set_serializer(num_obj, custom_double_serialize, NULL, NULL); json_object_array_add(my_array, num_obj); token = strtok(NULL, ","); } json_object_object_add(root_obj, "doubles", my_array); // 注意:需手动释放userdata中的字符串,避免内存泄漏 int array_len = json_object_array_length(my_array); for (int i = 0; i < array_len; i++) { json_object* elem = json_object_array_get_idx(my_array, i); free((void*)json_object_get_userdata(elem)); }
内容的提问来源于stack exchange,提问作者spiderwebdev
相关产品推荐
相关产品推荐

