[英]encoding floats and integers in string
我正在编写一个C ++程序,该程序要求对字符串中的某些值进行编码(它必须是字符串)。 我决定使用sprintf将数据(一个无符号的int和两个双精度的)保存在char数组中。 问题是我在理解此功能的行为时遇到问题。 这是我正在使用的代码
char vel[1];
unsigned int n = 30;
std::sprintf(vel, "%u", n);
std::cout<< "packet sending: " << vel << std::endl;
std::cout<< "packet dim: " << sizeof(vel)<< std::endl;
这是初步测试。 由于unsigned int是4个字节,并且我仅分配1个char(字节)的数组,所以我期望出现分段错误。但是,我很惊讶(当然,对我来说)获得输出
packet sending: 30
packet dim: 4
其实我不明白为什么。 此外,目标是存储三个值,并使用scanf检索它们。 如果可能的话,这就是我想做的
char vel[1];
unsigned int n = 30;
std::sprintf(vel, "%u%f%f", n, 5.0,6.0);
std::cout<< "packet sending: " << vel << std::endl;
std::cout<< "packet dim: " << sizeof(vel)<< std::endl;
然后在另一个函数中,我发送了字符串
std::string s = vel.str();
我做
unsigned int i;
float g,h;
std::sscanf(s.c_str(), "%u%f%f",&i,&g,&h);
当然没有任何作用,请您能帮我吗? 我阅读了使用过的函数的文档,但是我不明白为什么这不起作用。 谢谢! 安德里亚
编辑:我运行一些测试,如果我生成带有以下代码的字符串:
char vel[13];
unsigned int n = 30;
std::sprintf(vel, "%u%f", n, 5.0);
std::stringstream packet;
packet << vel;
std_msgs::String outMsg;
outMsg.data = packet.str();
并且我尝试以这种方式检索信息:
packet = msg->data.c_str();
unsigned int i;
float f;
std::sscanf(packet, "%u%f", &i, &f);
std::cout << "received packet: "<< i << "\tdata: "<< f << std::endl;
生成的打印是
received packet: 305 data: 0
它应该是
received packet: 30 data: 5
不是吗
再次感谢!
如果要使用sprintf
,则必须提供足够大的缓冲区来存储所有字符。 程序中给定的数组很小,因此函数会覆盖以下内存块,在末尾附加NULL
,然后将其正确打印到stdout。 调用sprintf
变量n
可能不等于30。此函数的安全版本是snprintf
。 http://www.cplusplus.com/reference/cstdio/snprintf/ http://www.cplusplus.com/reference/cstdio/sprintf/
您的第一个代码输出的原因是:
packet sending: 30
packet dim: 4
这是因为即使vel
仅是1个字节的char数组, sprintf
成功创建了一个字符串。 您的代码在sprintf
内部的vel
上产生缓冲区溢出。 可能是变量n
被此溢出修改了(您不知道)。 如果您打印n
的值,我想它不再是30
了。
我猜这是您要在第一个代码上完成的工作:
char vel[42]; //42 = 11 + 1 + 14 + 1 + 14 + 1
unsigned int n = 30;
std::sprintf(vel, "%u %.5f %.5f", n, 5.0,6.0);
std::cout<< "packet sending: " << vel << std::endl;
std::cout<< "packet dim: " << strlen(vel)<< std::endl;
//Changes:
// - add spaces in your format string
// change "%u%f%f" to "%u %f %f" so sscanf() will know
// when to stop parsing a specific data.
// - replace sizeof(vel) with strlen(vel) because
// your sending a string that changes size.
// sizeof() is for getting the size of DATA TYPES only.
在您的接收方代码中,尝试更改sscanf()中的格式字符串:
std::sscanf(packet, "%u %f", &i, &f); //add space in the middle.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.