我有一个携带多个不同类型成员的结构。我想将这个结构复制到一个缓冲区,然后连接一个消息供以后使用(将它们分开并读取结构和消息,我在这里没有做过)。这是我的代码。
#define DAT "d"
#define ACK "a"
#define SYN "s"
#define FIN "f"
#define RST "r"
typedef struct Headers { //total 20 bytes
unsigned char _magic_[7];
unsigned char _type_[1];
union {
unsigned int _seq_; //4 bytes
unsigned int _ack_; //4 bytes
} no;
unsigned int _length_; //4 bytes
unsigned short _size_; //2 bytes
} Header;
int main() {
Header receiver_header;
char buffer[1024];
strcpy(receiver_header._magic_, "ABCDEF");
strcpy(receiver_header._type_, DAT);
receiver_header.no._ack_ = 0;
receiver_header._length_ = 900;
receiver_header._size_ = 10240;
char foo[] = "A random message";
memcpy(buffer, &receiver_header, sizeof(Header));
strcat(buffer, foo);
printf("%s\n", buffer);
}
输出
ABCDEFA random message
我的问题是
您是否需要将成员转换为相同类型才能将其复制到缓冲区?
为什么其余的成员在缓冲区中消失了,即使我已经声明了它的来源和长度的正确指针?
答案 0 :(得分:3)
Header
的第一位成员_magic_
拥有7位char
。您复制了6 char
s(" ABCDEF"),后跟空字符。 strcat
将源字符串复制到它遇到的第一个空字符的目标字符串中。因此,它附加了一个随机消息"紧跟在Header
的前六个字节之后。如果要在整个结构之后附加消息,则需要指定要复制到的偏移量,如此。
strcpy(buffer + sizeof(Header), foo);
然而,它不会打印整个结构,因为空字符仍然在" ABCDEF"之后,即使foo
已经附加在正确的偏移处。如果要打印结构中的所有内容,只需明确打印出每个成员,就像这样。
printf("%s %c %u %u %hu %s",
receiver_header._magic_,
receiver_header._type[0],
reveiver_header.no._ack_,
receiver_header._length_,
receiver_header._size_,
foo);
答案 1 :(得分:1)
- 您是否需要将成员转换为相同的类型才能将它们复制到缓冲区中?
醇>
没有。 memcpy()
可以复制任何对象的整个表示。但你确实有其他一些明显的误解和陌生感:
如果Header._magic_
用于保存字符串,则其元素类型应为char
,而不是unsigned char
。另一方面,如果它意味着保存二进制数据,那么您不应该使用strcpy()
将数据复制到其中。
Header._type_
有一个字节的空间,但你strcpy()
一个字符的字符串。计算终结符时,字符串需要两个字节;这些都不适合_type_
。您可能应该执行单个(无符号)char
的普通分配。
如果只有内部空字节,则复制到缓冲区中的结构表示不是C字符串的内容。因此,您无法使用strcat()
安全地附加到它。更一般地说,你不应该用字符串函数来操作一般数据。
尝试将结构表示打印为字符串也是不合理的。即使没有内部空字节,但有一个终止空字节,您的结构也有数字字段。它们的表示是二元的,而不是文本的,并且将它们打印成好像它们是文本的不会产生任何有用的东西。
- 为什么其余的成员在缓冲区中消失了,即使我已经声明了它的来源和长度的正确指针?
醇>
因为当你strcat()
将消息发送到缓冲区时,你覆盖了它们。