使用std :: copy将char数组中的两个字节复制到unsigned short中

时间:2011-10-31 17:36:17

标签: c++

我有一个二进制数组char buffer[N];,它包含两个字节,在其开头被解释为unsigned short,并且当前正在通过

提取它们
unsigned short size= 0;
memcpy((char *) &size, buffer, sizeof(unsigned short));

但是我想为此使用std :: copy。这可能吗?

尝试

std::copy(buffer, buffer+sizeof(unsigned short), (char *) &size);
编译时

导致各种错误。

编辑抱歉,我匆忙忘了: 这是在具有gcc 4.4.3的Ubuntu GNU / Linux系统上。错误消息为Error: Invalid conversion from ‘char*’ to ‘char’

4 个答案:

答案 0 :(得分:6)

您不应该为此使用任何类型的批量复制例程,也不应该使用类型转换来获取指向unsigned short的指针,因为这些选项都不会考虑字节顺序。从char[]缓冲区中提取双字节无符号整数的正确方法是使用以下函数之一:

unsigned short extract_littleend16(const unsigned char *buf)
{
    return (((unsigned short)buf[0]) << 0) |
           (((unsigned short)buf[1]) << 8);
}

unsigned short extract_bigend16(const unsigned char *buf)
{
    return (((unsigned short)buf[0]) << 8) |
           (((unsigned short)buf[1]) << 0);
}

std::copymemcpy和直接指针抨击都会与一个这些函数做同样的事情,但你不知道它是哪一个将会,并且每当你完成这项任务时,其中一个功能是正确的而另一个是错误的。此外,如果你不知道从上下文中需要哪一个,那就去几个设计级别并找出它。

答案 1 :(得分:4)

你实际上根本不需要使用任何副本,这就是真正指针的美妙之处。 例如,在基于Windows的系统上,您可以只使用这行代码。 尝试

size = *((unsigned short *)buffer);

std :: copy需要迭代器,为此,我会坚持使用memcpy afterall

答案 2 :(得分:2)

size = *(unsigned short*)buffer;

应该做; - )

答案 3 :(得分:2)

好的,我的回答有点澄清:

你可以这样做,应该* 编译 * 没有问题,请参阅下面的代码。但是,你真的不想这样做,因为它有一些警告。

1:如果本地字节顺序与char缓冲区中的字节顺序不同,它将会很糟糕(参见4,由于Zack而导致的学分 - 我自己错过了这一点)。

2:如果你搞砸了演员阵容,你将最终处于未定义的行为中(请参阅帖子上的评论,我首先错过了指定演员)

3。:STL的调试实现可能会发出警告,或者完全阻止您编译这样的代码(并且出于某种原因这样做)。

4:它可能会编译并且似乎运行良好,但它不一定按照您的意图执行(参见2.)

5:我确信还有更多:)

这是编译示例(i686-apple-darwin11-llvm-gcc-4.2)。使用风险自负。

#include <algorithm>
#include <iostream>

int main()
{
  unsigned short foo = 0;
  char byte[2] = { 0x10, 0xFF };

  // WARNING: This will screw up if the native byte order is different 
  // from the byte order in the buffer!!! (Credits: Zack)**
  std::copy(byte, byte + sizeof(unsigned short), (char*)&foo);

  std::cerr << foo << std::endl;

  return 0;
}