我在C中编写TCP套接字,以便为我正在处理的项目发送位置数据。
到目前为止,一切正常,但我正在努力解决这个看似简单的问题。我正在尝试构建一个将通过套接字发送的JSON字符串。我有一个字符数组(代表字符串)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
已正确定义,应该是大约5位小数的float
。
但是当我致电build_json();
时,38.925034}
是唯一被退回的东西。为什么会这样?看来,对sprintf
的调用覆盖了json
中已写入的内容。
感谢您的帮助!
答案 0 :(得分:10)
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] = '\0';
只要json
是调用snprintf
的函数可见的数组,即在堆栈中的该函数中分配的数组,或全局的数组。如果它是你传递给函数的char*
,那么这将失败,所以要小心。
答案 1 :(得分:1)
最好只使用sprintf来避免多次操作。
const char* build_json(void) {
sprintf(json, "{\"latitude\":%0.5f}", latitude);
return json;
}
此外,如果您正在编写网络代码,最好在函数中分配字符串,而不是依赖于全局。通常,网络代码是以多线程方式完成的。
答案 2 :(得分:0)
快速&脏修复:
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);
答案 3 :(得分:0)
您可以在缓冲区中一次写入整个字符串:
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);
}
只需为缓冲区提供足够的空间,你需要在func之外分配你的json并在超出范围时释放它