VC++lrc歌词解析类

来源:互联网 发布:软件项目经理简历 编辑:程序博客网 时间:2024/05/01 07:02

        由于时间仓促,所以没有加过多的错误处理或检查,另外结构体、变量和字符串等没有动态定义,可能会导致严重的缓冲区错误,所以如果要当做一个项目来做的话,建议加上这些处理、检查,并动态分配内存。

        虽然说这是写成了一个C++类,但是文件读写以及许多函数都是C中的。见代码吧!代码看起来比较简单,老规矩,下载地址在后面。

        差点忘记说明了,这种实现比较不好暂停,若有好点子,欢迎回复。谢谢!

#include <stdio.h>#include <windows.h>typedef struct{    unsigned  int  time;    char           data[40];}LineData;class CLrc{    public:        BOOL  Open( LPTSTR  FileName );        void  Close();        BOOL  GetTitle( LPTSTR  Title ); // 未实现        BOOL  GetAlbum( LPTSTR  Album ); // 未实现        BOOL  GetArtist( LPTSTR  Artist ); // 未实现        BOOL  GetEditor( LPTSTR  Editor ); // 未实现        BOOL  ReadLine( LPTSTR  Data );        CLrc()        {            memset( LrcFile, 0, 128 );            ldpoint = 0;        }        ~CLrc()        {            if( hLrcFile != NULL )            {                fclose( hLrcFile );            }        }   // private:        FILE *hLrcFile;        char  LrcFile[128];        LineData  ld[100];        int   ldpoint;        void  DelCRLF( char *Data );        void  Sort();        int   Findch( const char *str, unsigned char ch );        int   GetTime( const char *line );        void  ResolveLine( const char *line );        void  GetLineData( const char *line, char *data );};// 打开文件BOOL CLrc::Open( LPTSTR  FileName ){    FILE  *fp;    fp = fopen(FileName, "r");    if( fp == NULL )    {        return FALSE;    }    hLrcFile = fp;    return  TRUE;}// 关闭文件void  CLrc::Close(){    if( hLrcFile != NULL )    {        fclose( hLrcFile );    }}// 获得行的歌词// 例如,[00:00.01]abc,该函数将获取到的"abc"保存到data中void CLrc::GetLineData( const char *line, char *data ){    int  i = 0,         j = 0,         len;    if( strcmp( line, "" ) )    {        len = strlen( line );        i = len;        while( line[i] != ']' && i > 0 )        {            i--;        }        for( j = i + 1, i += 1; j <= len; j++ )        {            data[j - i] = line[j];        }    }}// 读取下一行数据BOOL CLrc::ReadLine( char *line ){    char  Line[100];    memset( Line, 0, 100 );    if( feof( hLrcFile ) || fgets( Line, 100, hLrcFile) == NULL )    {        return FALSE;  // 表示文件结束    }    DelCRLF( Line );    strcpy( line, Line );    return TRUE;  // 正常}// 删除Data中的空格void CLrc::DelCRLF( char *Data ){    int  i = 0;    int  len = strlen( Data );    for( ; i < len; i++ )    {        if( Data[i] == 0x0D || Data[i] == 0x0A )        {            int  j = i;            for( ; j < len ; j++ )            {                Data[j] = Data[j + 1];            }        }    }}// Findch用于检测ch在str中出现的次数int CLrc::Findch( const char *str, unsigned char ch ){    int  i = strlen( str );    int  quan = 0;    while( i-- )    {        if( str[i] == ch )        {            quan++;        }    }    return  quan;}// 获得歌词时间int CLrc::GetTime( const char *line ){    int  min = 0,         sec = 0,         ms  = 0;    if(Findch(line, '.') == 0)    {        sscanf( line, "[%d:%d]", &min, &sec );    }    else    {        sscanf( line, "[%d:%d.%d]", &min, &sec, &ms );    }    return  (min * 6000 + sec * 100 + ms );}// 解析每一行的数据,存入结构void CLrc::ResolveLine( const char *line ){    char  str[100];    int   i = 0,          j = 0,          last = 0;    strcpy( str, line );    if (Findch(str, '[') != Findch(str, ']') )  // 检测正确性    {        return;    }    for (i = 0; i <= strlen(str); i++ )    {        if (str[i] == ']')        {            char  buf[50] = "";            int   t = 0;                        for (j = last; j <= i; j++ )            {                buf[t++] = str[j];            }ld[ ldpoint ].time = GetTime( buf ) * 10;            GetLineData( line, ld[ldpoint].data);            ldpoint++;             i++;            last = i;                   }    }}// 将结构中所有歌词排序,冒泡排序void  CLrc::Sort(){    int  i = 0, j;    for( ; i < ldpoint - 1; i++ )    {        for( j = i; j < ldpoint - i; j++ )        {            if( ld[j].time > ld[j + 1].time )            {                LineData  t;                t = ld[j];                ld[j] = ld[j + 1];                ld[j + 1] = t;            }        }    }}


调用方式:

int main(){    CLrc  lrc;    if( lrc.Open("J:\\lrc2.lrc") == FALSE )    {        printf( "无法打开歌词文件!\n" );        return 0;    }    while( true )    {        char  line[100] = "";        if( !lrc.ReadLine( line ) ) // 读完了        {            break;        }        if( strcmp( line, "" ) )        {            lrc.ResolveLine( line ); // 解析数据        }    }    lrc.Close(); // 关闭文件句柄    lrc.Sort(); // 排序    if( lrc.ldpoint )    {        Sleep( lrc.ld[0].time );        printf( "%s\n", lrc.ld[0].data ); // 输出第一行        for( int i = 1; i < lrc.ldpoint; i++ )        {            Sleep( lrc.ld[i].time - lrc.ld[i - 1].time );            printf( "%s\n", lrc.ld[i].data );        }    }    return 0;}


 

原创粉丝点击