⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lantranform.cpp

📁 一本书里的代码
💻 CPP
字号:
/////////////////////////////////////////////////////////////////
// BIG5与GB2312编码转换程序
// 作者: Janhail Luo
// 最后整理: 2003-03-03
/////////////////////////////////////////////////////////////////
#include    <stdio.h>
#include    "LanTranform.h"

// 构造函数
CLanTransform::CLanTransform()
{
    pBIG5 = 0;
    pGB2312 = 0;
}

// 析构函数
CLanTransform::~CLanTransform()
{
    // 释放码表
    FreeTableBuf(true);
    FreeTableBuf(false);
}

// 初始化转换程序,读入转换码表文件
bool CLanTransform::Init(const char* lpszBig2GBFile, const char* lpszGB2BigFile)
{
    // 读入BIG5转换GB2312的码表文件
    if (lpszBig2GBFile)
    {
        if (false==this->LoadTable(lpszBig2GBFile, true))
        {
            return false;   // 读入失败
        }
    }

    // 读入GB2312转换BIG5的码表文件
    if (lpszGB2BigFile)
    {
        if (false==this->LoadTable(lpszGB2BigFile, false))
        {
            return false;   // 读入失败
        }
    }

    // 读入成功
    return true;
}


// 转换一个指定的BIG5编码的字符串到GB2312编码的字符串
//   lpBuf 是指定字符串的指针
//   如果不能转换就返回0, 否则返回lpBuf指向的地址
char* CLanTransform::BIG2GB(char* lpBuf)
{
    unsigned char *pCur, *pDest, bFirst, bSecond, bIndex ;

    // 如果没有初始化数据或者没有需要转换的数据,就直接返回
    if (pBIG5==0 || lpBuf==0)
    {
        return 0;
    }

    pCur = (unsigned char*)lpBuf;
    while(*pCur)   // 处理到字符串结束
    {
        bFirst = *pCur;         // 取得第一个字节的值
        bSecond = *(pCur+1);    // 取得第二个字节的值
        if (bFirst<0xA1 || bFirst>0xFE)   // 如果是英文字符
        {
            // 不转换,直接跳到下一个字符
            pCur++;
        }else if (bSecond<0x40 // 如果是非BIG5的其他字符
            || bSecond>0xFE || (bSecond>0X7E&&bSecond<0XA1))
        {
            // 不转换,直接跳到下一个字符
            pCur++;
        }else   // 是BIG5字符,需要转换
        {
            bIndex = bFirst-0xA1;

            // 由
            // if (bSecond<0x7F)
            // {
            //     d = pBIG5 + ((temp*0xA0 + (bSecond-0x40))<<1);
            // }else
            // {
            //     d = pBIG5 + ((temp*0xA0 +
            //                (bSecond+(0x7F-0x40)-0xA1))<<1);
            // }
            // 可以优化成为下面语句
            //pDest = pBIG5 + ((bIndex<<7)+(bIndex<<5))<<1;
            pDest = pBIG5 + (((bIndex<<7)+(bIndex<<5))<<1);
            if (bSecond<0x7F)
            {
                pDest += (bSecond-0x40)<<1;
            }else
            {
                pDest += (bSecond+0x3F-0xA1)<<1;
            }

            *pCur++ = *pDest++;    // 第一个字节
            *pCur++ = *pDest;      // 第二个字节
        }
    }
    return lpBuf;
}

// 转换一个指定的GB2312编码的字符串到BIG5编码的字符串
//   lpBuf 是指定字符串的指针
//   如果不能转换就返回0, 否则返回lpBuf指向的地址
char* CLanTransform::GB2BIG(char* lpBuf)
{
    unsigned char *pCur, *pDest, bFirst, bSecond, bIndex ;
 
    // 如果没有初始化数据或者没有需要转换的数据,就直接返回
    if (pGB2312==0 || lpBuf==0)
    {
        return 0;
    }

    pCur = (unsigned char*)lpBuf;
    while(*pCur)   // 如果字符串结束
    {
        bFirst = *pCur;         // 取得第一个字节的值
        bSecond = *(pCur+1);    // 取得第二个字节的值
        if (bFirst<0xA1 || bFirst>0xF7)   // 如果是英文字符
        {
            pCur++;    // 不转换,直接跳到下一个字符
        }else if (bSecond<0xA1 || bSecond>0xFE) // 如果是非GB2312的其他字符
        {
            pCur++;    // 不转换,直接跳到下一个字符
        }else   // 是GB2312字符,需要转换
        {
            bIndex = bFirst-0xA1;

            // 由 d = pGB2312 + ((temp*0x5E + (bSecond-0xA1))<<1);
            // 可以优化成为下面语句
            pDest = pGB2312 + (((bIndex<<6)+(bIndex<<5)
                + (bSecond-0xA1))<<1);

            *pCur++ = *pDest++;    // 第一个字节
            *pCur++ = *pDest;      // 第二个字节
        }
    }
    return lpBuf;
}

// 从指定文件中读入字符转换表。
//   lpFileName 字符转换表的文件名
//   bIsBIG5 是否是BIG5的转换表
//   返回true读入成功,否则失败
bool CLanTransform::LoadTable(const char* lpFileName, const bool bIsBIG5)
{
    FILE*           fp;
    fpos_t          pos;
    unsigned long   fileSize;
    unsigned char*  pData;

    if (bIsBIG5)
    {
        // 如果数据已经有读入
        if (pBIG5)
        {
            // 释放原来读入的数据准备重新读入
            this->FreeTableBuf(bIsBIG5);
            pBIG5 = 0;
        }
    }else
    {
        // 如果数据已经有读入
        if (pGB2312)
        {
            // 释放原来读入的数据准备重新读入
            this->FreeTableBuf(bIsBIG5);
            pGB2312 = 0;
        }
    }

    // 打开文件
    if ((fp=fopen(lpFileName, "rb"))==NULL)
    {
        return false;   // 文件打开失败
    }

    // 取得文件大小
    fseek(fp, 0, SEEK_END);
    fgetpos( fp, &pos );
    fileSize = (unsigned long)(pos&0x00000000FFFFFFFF);

    // 跳回到文件头部
    fseek(fp, 0, SEEK_SET);

    // 在这里跳过文件头部信息
    // ...

    // 分配內存
    pData = new unsigned char[fileSize];
    if (pData==NULL)    // 如果內存分配失败
    {
        fclose(fp);     // 关闭文件
        return false;   // 内存分配失败
    }

    // 读取文件数据到内存中
    fread(pData, fileSize, 1, fp);

    // 关闭文件
    fclose(fp);

    if (bIsBIG5)
    {
        pBIG5 = pData;
    }else
    {
        pGB2312 = pData;
    }
    return true;    // 完成
}

// 释放字符表
//   bIsBIG5 是否是BIG5的字符表
bool CLanTransform::FreeTableBuf(const bool bIsBIG5)
{
    if (bIsBIG5)
    {
        if (pBIG5)      // 如果有数据
        {
            delete[] pBIG5; // 刪除数据
            pBIG5 = 0 ;     // 清空指针
        }
    }else
    {
        if (pGB2312)        // 如果有数据
        {
            delete[] pGB2312;   // 刪除数据
            pGB2312 = 0 ;       // 清空指针
        }
    }
    return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -