将具有不同类型成员的struct复制到缓冲区

时间:2017-03-10 22:55:17

标签: c struct buffer memcpy

我有一个携带多个不同类型成员的结构。我想将这个结构复制到一个缓冲区,然后连接一个消息供以后使用(将它们分开并读取结构和消息,我在这里没有做过)。这是我的代码。

#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

我的问题是

  1. 您是否需要将成员转换为相同类型才能将其复制到缓冲区?

  2. 为什么其余的成员在缓冲区中消失了,即使我已经声明了它的来源和长度的正确指针?

2 个答案:

答案 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)

  
      
  1. 您是否需要将成员转换为相同的类型才能将它们复制到缓冲区中?
  2.   

没有。 memcpy()可以复制任何对象的整个表示。但你确实有其他一些明显的误解和陌生感:

  • 如果Header._magic_用于保存字符串,则其元素类型应为char,而不是unsigned char。另一方面,如果它意味着保存二进制数据,那么您不应该使用strcpy()将数据复制到其中。

  • Header._type_有一个字节的空间,但你strcpy()一个字符的字符串。计算终结符时,字符串需要两个字节;这些都不适合_type_。您可能应该执行单个(无符号)char的普通分配。

  • 如果只有内部空字节,则复制到缓冲区中的结构表示不是C字符串的内容。因此,您无法使用strcat()安全地附加到它。更一般地说,你不应该用字符串函数来操作一般数据。

  • 尝试将结构表示打印为字符串也是不合理的。即使没有内部空字节,但有一个终止空字节,您的结构也有数字字段。它们的表示是二元的,而不是文本的,并且将它们打印成好像它们是文本的不会产生任何有用的东西。

  
      
  1. 为什么其余的成员在缓冲区中消失了,即使我已经声明了它的来源和长度的正确指针?
  2.   

因为当你strcat()将消息发送到缓冲区时,你覆盖了它们。

相关问题