将浮点值复制到 char 数组
Copying float values into char array
我正在用 C 编写一个 TCP 套接字来发送我正在处理的项目的位置数据。
到目前为止,一切正常,但我正在努力解决这个看似简单的问题。我正在尝试构建一个将通过套接字发送的 JSON 字符串。我有一个字符数组(代表String)json
定义为:
char json[1024];
有一个方法原型:
const char* build_json(void);
和方法体:
const char* build_json(void) {
strcpy(json, "{");
strcat(json, "\"latitude\":");
sprintf(json, "%0.5f", latitude);
strcat(json, "}");
return json;
}
我知道 latitude
定义正确,应该是 float
大约有 5 位小数。
但是当我调用 build_json();
时,38.925034}
是唯一返回的内容。为什么会这样?似乎对 sprintf
的调用正在覆盖 json
.
中已经写入的内容
感谢您的帮助!
sprintf
不会附加到您的字符串;相反,它将覆盖那里的任何内容。你可以这样做:
sprintf(json + strlen(json), "%0.5f", 213.33f);
但是,老实说,这是一个更好的解决方案:
sprintf(json, "{\"latitude\":%0.5f}", location);
而这个解决方案仍然更好:
snprintf(json, sizeof(json), "{\"latitude\":%0.5f}", location);
json[sizeof(json) - 1] = '[=12=]';
只要 json
是调用 snprintf
的函数可见的数组,即分配在堆栈上的该函数中,或全局分配。如果传递给函数的是 char*
,这将失败得很惨,所以要小心。
最好只用sprintf来做,避免多次操作。
const char* build_json(void) {
sprintf(json, "{\"latitude\":%0.5f}", latitude);
return json;
}
此外,如果你正在编写网络代码,你最好在你的函数中分配你的字符串,而不是依赖于全局。通常,网络代码是以多线程的方式完成的。
快速修复:
char* cptr = json;
...
strcpy(cptr, "{");
cptr += sizeof("{") - 1;
strcat(cptr, "\"latitude\":");
cptr += sizeof("\"latitude\":") - 1;
sprintf(cptr, "%0.5f", latitude);
正确的解决方案是将字符串文字及其大小放在常量变量中而不是上面的。
char* cptr = json;
...
strcpy(cptr, STR_START_BRACE);
cptr += STR_START_BRACE_LEN;
strcat(cptr, STR_LATITUDE);
cptr += STR_LATITUDE_LEN;
sprintf(cptr, "%0.5f", latitude);
您可以一次将整个字符串写入缓冲区:
const void build_json(char * json, size_t *len)
{
char buff[50];
sprintf(buff, "{\"latitude\":%0.5f}", latitude);
*len = strlen(buff);
strncpy(json, buff, *len);
}
只需提供足够的 space 缓冲区,您需要在 func 之外分配 json 并在超出范围时释放它
我正在用 C 编写一个 TCP 套接字来发送我正在处理的项目的位置数据。
到目前为止,一切正常,但我正在努力解决这个看似简单的问题。我正在尝试构建一个将通过套接字发送的 JSON 字符串。我有一个字符数组(代表String)json
定义为:
char json[1024];
有一个方法原型:
const char* build_json(void);
和方法体:
const char* build_json(void) {
strcpy(json, "{");
strcat(json, "\"latitude\":");
sprintf(json, "%0.5f", latitude);
strcat(json, "}");
return json;
}
我知道 latitude
定义正确,应该是 float
大约有 5 位小数。
但是当我调用 build_json();
时,38.925034}
是唯一返回的内容。为什么会这样?似乎对 sprintf
的调用正在覆盖 json
.
感谢您的帮助!
sprintf
不会附加到您的字符串;相反,它将覆盖那里的任何内容。你可以这样做:
sprintf(json + strlen(json), "%0.5f", 213.33f);
但是,老实说,这是一个更好的解决方案:
sprintf(json, "{\"latitude\":%0.5f}", location);
而这个解决方案仍然更好:
snprintf(json, sizeof(json), "{\"latitude\":%0.5f}", location);
json[sizeof(json) - 1] = '[=12=]';
只要 json
是调用 snprintf
的函数可见的数组,即分配在堆栈上的该函数中,或全局分配。如果传递给函数的是 char*
,这将失败得很惨,所以要小心。
最好只用sprintf来做,避免多次操作。
const char* build_json(void) {
sprintf(json, "{\"latitude\":%0.5f}", latitude);
return json;
}
此外,如果你正在编写网络代码,你最好在你的函数中分配你的字符串,而不是依赖于全局。通常,网络代码是以多线程的方式完成的。
快速修复:
char* cptr = json;
...
strcpy(cptr, "{");
cptr += sizeof("{") - 1;
strcat(cptr, "\"latitude\":");
cptr += sizeof("\"latitude\":") - 1;
sprintf(cptr, "%0.5f", latitude);
正确的解决方案是将字符串文字及其大小放在常量变量中而不是上面的。
char* cptr = json;
...
strcpy(cptr, STR_START_BRACE);
cptr += STR_START_BRACE_LEN;
strcat(cptr, STR_LATITUDE);
cptr += STR_LATITUDE_LEN;
sprintf(cptr, "%0.5f", latitude);
您可以一次将整个字符串写入缓冲区:
const void build_json(char * json, size_t *len)
{
char buff[50];
sprintf(buff, "{\"latitude\":%0.5f}", latitude);
*len = strlen(buff);
strncpy(json, buff, *len);
}
只需提供足够的 space 缓冲区,您需要在 func 之外分配 json 并在超出范围时释放它