【问题标题】:Why doesn't memcpy work when copying a char array into a struct?为什么将 char 数组复制到结构时 memcpy 不起作用?
【发布时间】:2012-03-27 20:09:55
【问题描述】:
#define buffer 128    

int main(){
  char buf[buffer]="";

  ifstream infile("/home/kevin/Music/test.mp3",ios::binary);
  infile.seekg(-buffer,ios::end);
  if(!infile || !infile.read(buf,buffer)){
      cout<<"fail!"<<endl;
  }
  ID3v1 id3;
  cout<<sizeof(id3)<<endl;
  memcpy(&id3,buf,128);
  cout<<id3.header<<endl;
}


struct ID3v1{
  char header[3];
  char title[30];
  char artist[30];
  char album[30];
  char year[4];
  char comment[28];
  bool zerobyte;
  bool track;
  bool genre;

};

当我执行 memcpy 时,似乎将太多数据推送到标题字段中。我需要遍历每个结构成员并复制数据吗?我也在使用 c++,但这似乎更像是一种“C”策略。 c++有没有更好的方法?

【问题讨论】:

  • 您不能将更多数据“推送”到 char[3] 中,您只能读取太多,因为它不是以零结尾的。
  • 您的 ID3v1.header 很可能不是以空值结尾的。在\0 之前,您正在打印所有内容。
  • 我强烈建议您不要将缓冲区和缓冲区大小命名为bufbuffer。为什么不命名一个buf 和另一个bufSize?还是bufferbufferSize?这令人困惑!此外,如果您要复制的只是 ID3 标记且其大小为 128,则将所有 128 替换为具有有意义名称的常量,例如 ID3TAG_SIZE 或其他。
  • 要添加到 111111,您确定您在该 c 字符串中获得的数据是您想要的吗?
  • 是的,我想就是这样,因为其余输入的数据是正确的。我确保我正确使用了 memcpy,我以前从未使用过它,但标签数据不是以零结尾的。

标签: c++ file-io struct memcpy id3


【解决方案1】:

正如所有 cmets 中所指出的(您缺少 '\0' 字符,或者在打印 C 字符串时,运算符

试试:

std::cout << std::string(id3.header, id3.header+3) << std::endl;

这将打印标题字段中的三个字符。

【讨论】:

    【解决方案2】:

    问题很可能在于memcpy 做了它该做的事情。

    它将 128 字节复制到您的结构中。

    然后你尝试打印出标题。它打印第一个字符,第二个,第三个......并继续打印,直到找到'\0'(字符串终止字符)。

    基本上,当打印出来时,将标题复制到另一个 char 数组并附加终止字符(或复制到 c++ 字符串)。

    【讨论】:

      【解决方案3】:

      您在使用 memcpy 时可能遇到的其他问题:

      • 您的结构元素可能会被编译器对齐到字边界。 大多数编译器都有一些编译指示或命令行开关来指定要使用的对齐方式。
      • 某些 cpu 要求将 short 或 long 存储在字边界上,在这种情况下,修改对齐对您没有帮助,因为您将无法从未对齐的地址中读取。
      • 如果您复制大于 char 的整数(例如 short 或 long ),您必须确保根据您的 cpu 架构更正字节顺序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-12
        • 2014-12-13
        • 1970-01-01
        • 2021-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多