2012-03-10 13 views
0
#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配列を構造体にコピーするときにmemcpyが機能しないのはなぜですか?

+2

char [3]に「より多くのデータをプッシュする」ことはできません。ゼロ終了していないため、あまりにも多くのデータを読み取ることはできません。 –

+1

あなたの 'ID3v1.header'は、おそらくヌルで終了しないでしょう。 '\ 0'まですべてを印刷しています。 – lapk

+2

バッファとバッファサイズに 'buf'と' buffer'という名前を付けないことを強くお勧めします。 'buf'と' bufSize'という名前を付けてみませんか?あるいは 'buffer'と' bufferSize'ですか?これは混乱しています!さらに、コピーしたいものがすべてID3タグで、そのサイズが '128'の場合は、' ID3TAG_SIZE'などの意味のある名前ですべての '128'を定数で置き換えます。 – hochl

答えて

0

問題は、memcpyが行うことを最もよく捉えている可能性があります。

あなたの構造に128バイトをコピーします。

次に、ヘッダーを印刷しようとします。第1文字、第2、第3 ..を印刷し、'\0'(文字列終了文字)が見つかるまで印刷し続けます。

基本的に、印刷するときは、ヘッダを別のchar配列にコピーし、終了文字を追加します(またはC++文字列にコピーします)。

3

すべてのコメント(「\ 0」文字が欠落しているか、またはC文字列を印刷するときに、オペレータ< <は「\ 0」の文字列が終了すると予想しています)。

試してみてください。

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

これは、ヘッダフィールドの3つの文字を印刷します。 memcpyを使用するときに発生する可能性がある

0

その他の問題:

  • あなたの構造体要素は、コンパイラによってワード境界に揃えることができます。 ほとんどのコンパイラには、使用するアラインメントを指定するプラグマまたはコマンドラインスイッチがあります。
  • いくつかのCPUはワード境界にショートまたはロングを格納する必要があります。その場合、アラインメントを変更しても、アライメントされていないアドレスから読み取ることはできません。
  • charより大きい整数(shortまたはlongなど)をコピーする場合は、CPUのアーキテクチャに応じてバイト順を修正する必要があります。
関連する問題