Почему memcpy не работает при копировании массива char в структуру? - PullRequest
0 голосов
/ 11 марта 2012
#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 ++?

Ответы [ 3 ]

3 голосов
/ 11 марта 2012

Как отмечено во всех комментариях (вам не хватает символа '\ 0', или при печати C-строк оператор << ожидает завершения последовательности символов '\ 0'). </p>

Попытка:

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

Это напечатает три символа в поле заголовка.

0 голосов
/ 11 марта 2012

другие проблемы, с которыми вы можете столкнуться при использовании memcpy:

  • ваши элементы структуры могут быть выровнены компилятором по границам слова.большинство компиляторов имеют некоторые прагмы или переключатель командной строки для указания используемого выравнивания.
  • некоторые процессоры требуют, чтобы шорты или длинные строки были сохранены на границах слов, в этом случае изменение выравнивания вам не поможет, так как вы не будетевозможность чтения с невыровненных адресов.
  • если вы копируете целые числа, большие чем char (например, short или long), вы должны обязательно исправить порядок байтов в зависимости от архитектуры вашего процессора.
0 голосов
/ 11 марта 2012

Скорее всего, проблема в том, что memcpy делает то, что делает.

Копирует 128 байтов в вашу структуру.

Затем вы пытаетесь распечатать заголовок. Он печатает 1-й символ, 2-й, 3-й .. и продолжает печатать, пока не найдет '\0' (символ завершения строки).

Обычно, при распечатке, копируйте заголовок в другой массив символов и добавляйте символ завершения (или копируйте в строку c ++).

...