如何处理插入 '\0' 的字符数组?
Posted
技术标签:
【中文标题】如何处理插入 \'\\0\' 的字符数组?【英文标题】:How to deal with char array which '\0' is inserted into?如何处理插入 '\0' 的字符数组? 【发布时间】:2021-04-08 01:56:28 【问题描述】:当我尝试使用 memcpy 函数将结构复制到 char 数组缓冲区中时,'\0' 被插入到 char 数组中。我将缓冲区指针传递给一个函数。第一个 '\0' 之前的内容已经过去,但其余的都丢失了。我怎么解决这个问题?如果您能帮助我,我将不胜感激。
这里是代码,虽然结构体Mystruct和函数display()设计不合理。
#include <QCoreApplication>
#include <stdio.h>
struct MyStruct
char c;
int order;
char ch;
MyStruct(char c = 'b', int order = 0, char ch = 'a'):order(order), ch(ch), c(c)
;
;
void display(char* str)
printf("%s", str);
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
MyStruct *mystruct = new MyStruct;
// char* test = new char[50];
char test[50];
memset(test, 0, 50);
memcpy(test, mystruct, sizeof(MyStruct));
display(test);
return a.exec();
我想通过套接字发送像“Mystruct”这样的结构,而函数 send(char*) 需要一个指向缓冲区的 char* 指针。将 int 顺序复制到 test[50] 时,会将 '\0' 插入到 char 数组中。
我们使用 QT 的 QTcpSocket::write(char* ) 代替 Linux 或 Windows 提供的 API。我的队友给我提供了一个接口函数send(char )。我需要传递char指针指向的缓冲区。
我用显示的代码简化了我的问题,并为我令人困惑的表达道歉。还有任何通过套接字发送结构的好方法?
【问题讨论】:
如果您要复制的数据可能包含空字节并且您不希望这样,则必须清理数据。你如何做到这一点取决于你想要什么。搜索空值并将其更改为空格?复制时跳过空值?遇到空字节时插入“(null)”?如果数据包含空字节,则抛出错误?你需要决定应该发生什么。 您希望通过以下方式完成struct
的具体操作:1) 单个char
,2) 单个int
,和3) 第二个char
值,然后将整个结构解释为单个字符搅拌?您对这一系列事件的预期结果是什么?为什么要将 struct
复制到单个 char
缓冲区中,并尝试将其打印为普通的以空字符结尾的字符串?
字符串函数依赖'\0'
来标记字符串的结尾。您需要避免所有做出这种假设的函数。
有什么好的方法可以通过socket发送结构体吗?
您使用什么网络库,不会将数据的大小与指向数据的指针一起计算?如果例如您在谈论this send
,请注意它如何将长度与指针一起使用,并且不依赖于 nul 终止。
【参考方案1】:
C-string 函数适用于 nul 终止字符串。
如果你想用 nul 非终端字符串处理char*
,你需要大小(或其他标记)。
MyStruct mystruct;
std::string buffer (char*) &mystruct, sizeof (MyStruct);
Demo
请注意,这种序列化方式有很多陷阱:
填充(您可能会在c
和order
之间以及ch
之后看到随机值(那些0
是随机的)。
字节序问题。
...
【讨论】:
感谢您的回答。顺便说一句,我发现 Qbytearray 和 std::string 一样是一个很好的工具。以上是关于如何处理插入 '\0' 的字符数组?的主要内容,如果未能解决你的问题,请参考以下文章
我如何处理有关输入的字符串大小超过字符数组的设定大小的错误?
从PHP版本7.2.0开始,“数组解除引用”如何处理类型为boolean / integer / float / string的标量值?