0

我正在尝试使用“BASS.dll”(通过 bass.lib 和 bass.h)从 mp3 文件中读取 ID3v1 标签。
它工作正常,直到 .mp3 文件的标题(或艺术家)有 30 个字符。
相反 Happy Times (Feat. Margaux Bos ,我得到Happy Times (Feat. Margaux BosEmigrate
Emigrate添加(那是艺术家标签)。

如何在不添加艺术家标签的情况下使其正常工作?
这是我的源代码:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "bass.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;

//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
    BASS_Init(-1, 44000, 0, 0, 0);

    if(OpenDialog1->Execute())
    {
       HSTREAM stream = BASS_StreamCreateFile(false, OpenDialog1->FileName.c_str(), 0, 0, 0);
       TAG_ID3 *tags = (TAG_ID3*)BASS_ChannelGetTags(stream, BASS_TAG_ID3);
       Edit1->Text = tags->title;
    }
}
4

1 回答 1

0

结构的文本字段TAG_ID3不能保证为空终止,但您的代码将它们视为它们,因此当空终止符不存在时,它最终会读入下一个字段。要解决这个问题,您必须考虑它们的最大长度,例如:

Edit1->Text = AnsiString().sprintf("%.*s", sizeof(tags->title), tags->title);

或者:

Edit1->Text = AnsiString(tags->title, sizeof(tags->title)).TrimRight();

与所有其他文本字段相同:

  • id: 3 个字符
  • title: 30 个字符
  • artist: 30 个字符
  • album: 30 个字符
  • year: 4 个字符
  • comment: 30 个字符

您可以使用简单的模板包装器来帮助您:

template<size_t N>
String toString(char (&arr)[N])
{
    return AnsiString().sprintf("%.*s", N, arr); 
    /* or:
    return AnsiString(arr, N).TrimRight();
    */
}

Edit1->Text = toString(tags->title);

请注意,该comment字段还有一个需要注意的额外警告:

如果第 30 个字符为非空,而第 29 个字符为空,则第 30 个字符为曲目编号,注释仅限于前 28 个字符。

于 2018-06-18T19:02:25.927 回答