繁体   English   中英

编码字符串中的浮点数和整数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM