高度自定义的简繁转换 VS2022 C++ 工程

2023-05-16

首先秀一下简繁转换结果图,如下:


 


#include <iostream>
#include"../KOpenCC/KOpenCCExport.h"
#include<string>
#ifdef  _WIN64
#pragma comment(lib,"../x64//Release/KOpenCC.lib")
#else
#pragma comment(lib,"../Release/KOpenCC.lib")
#endif //  _WIN64


int main()
{
    std::wcout.imbue(std::locale("chs"));
    KWString s(L"KOpenCC.txt");
    CKOpenCCExport  m;
    m.CKOpenCC_InitCCMap(s);

    KWString pStrIn(L"我们一起去怼牛太公"), pStrOut;
    std::wstring ws;
    pStrOut = ws.c_str();
     m.CKOpenCC_Switch(s,pStrIn, pStrOut,1);//简到繁
    std::wcout << pStrIn.c_str() << " -> " << pStrOut.c_str() << L"\n";
    pStrIn = ws.c_str();
    m.CKOpenCC_Switch(s,pStrOut,pStrIn,2);//繁到简
    std::wcout << pStrOut.c_str() << " -> " << pStrIn.c_str() << L"\n";
    std::cin.get();
}
 

具体实现如下:

生成一个c++ dll工程,定义如下导出简繁转换类.

1.自定义接口字符串类 与 接口导出转换类

#ifndef  H_88748467_32FF_4954_AF6C_B6C6DED7885F
#define  H_88748467_32FF_4954_AF6C_B6C6DED7885F

#ifdef   H_BCD969BF_81FD_4C53_B792_C128FB4C2F8E
#define  COPENCCEXPORTDLLPORT  __declspec(dllexport)
#else
#define  COPENCCEXPORTDLLPORT  __declspec(dllimport)
#endif

//定义接口宽字符串类  以统一内外字符数据类型
class KWString
{
public:
    KWString& operator=(const wchar_t* pwstr)
    {
        if (NULL == pwstr)
        {
            m_pwsr = new wchar_t[1];
            *m_pwsr = L'\0';
            m_size = 0;
        }
        else
        {
            m_size = wcslen(pwstr);
            m_pwsr = new wchar_t[m_size + 1];
            memcpy(m_pwsr,pwstr, m_size*2);
            m_pwsr[m_size] = L'\0';
        }
        return *this;
    }
    KWString& operator=(KWString& ws)
    {
        if (m_pwsr)
        {
            delete[] m_pwsr;
            m_pwsr = nullptr;
        }
        m_size = ws.length();
        m_pwsr = new wchar_t[ws.length() + 1];
        memcpy(m_pwsr,  ws.c_str(), ws.length()*2);
        m_pwsr[m_size] = L'\0';
        return *this;
    }
    size_t length()const
    {
        return m_size;
    }
    const wchar_t* c_str()const
    {
        return m_pwsr;
    }
    KWString()
    {
        m_pwsr = new wchar_t[1];
        *m_pwsr = L'\0';
        m_size = 0;
    }
    KWString(const wchar_t* pwstr)
    {
        if (NULL == pwstr)
        {
            m_pwsr = new wchar_t[1];
            *m_pwsr = L'\0';
            m_size = 0;
        }
        else
        {
            m_size = wcslen(pwstr);
            m_pwsr = new wchar_t[m_size + 1];
            memcpy(m_pwsr, pwstr, m_size*2);
            m_pwsr[m_size] = L'\0';
        }
    }
    ~KWString()
    {
        if (m_pwsr)
        {
            delete[] m_pwsr;
            m_pwsr = nullptr;
        }
    }
private:
    wchar_t*  m_pwsr;
    size_t    m_size;
};

//检索词库的词的最大长度为4

class COPENCCEXPORTDLLPORT CKOpenCCExport
{
public:
    CKOpenCCExport(void);
    ~CKOpenCCExport(void);

public:
    void CKOpenCC_InitCCMap(KWString& sName,int nFlag=3);//初始化KOpenCC夹下的txt文件,如sName=L"KOpenCC.txt",nFlag=初始化正映射 =2初始化反映射 =3正反映射皆初始化
    void CKOpenCC_ClearCCMap();//清理

    void CKOpenCC_Switch(KWString& sName, KWString& QWSIn, KWString& QSWOut, int nFlag=1);//nFlag=1简体到繁体 nFlag=2繁体到简体 
};
#endif

2.定义转换类的实现

//C++ cpp文件

#include "pch.h"
#include "KOpenCCExport.h"
#include "TextFileIO.h"
#include <map>
using namespace std;

map<wstring,wstring>g_1And2Map,g_2And1Map;
map<wstring, map<wstring, wstring>> g_maps;

void GetPath(wstring& FolderPath, UINT pos = 0)
{
    TCHAR path[MAX_PATH] = { 0 };
    TCHAR* p = nullptr;

    if (GetModuleFileName(NULL, path, _countof(path)))
    {
        for (UINT i = 0; i <= pos; i++)
        {
            p = _tcsrchr(path, _T('\\'));
            if (p != nullptr)
                p[0] = 0;
            else
                path[2] = 0;
        }
    }
    FolderPath = wstring(path) + L"\\";
}


CKOpenCCExport::CKOpenCCExport(void)
{
    wstring path;
    GetPath(path);
    path=path+_T("KOpenCC");
    CreateDirectory(path.c_str(), NULL);
}


CKOpenCCExport::~CKOpenCCExport(void)
{
    CKOpenCC_ClearCCMap();
}
void CKOpenCCExport::CKOpenCC_ClearCCMap()
{
    map<wstring,map<wstring,wstring>>().swap(g_maps);
}
void CKOpenCCExport::CKOpenCC_InitCCMap(KWString& sName,int nFlag)
{
    wstring path;
    GetPath(path);
    path=path+_T("KOpenCC\\");
    wstring wsName = sName.c_str();
    path = path + wsName;
    CTextFileIO m;
    m.ReadWholeTextFileToDQ(path.c_str());
    
    deque<wstring>::iterator    it=m._LineWStrDQ.begin();
    UINT                        nLine=1;
    bool                        Flag=false;//给定初始值
    size_t                        Len=m._LineWStrDQ.size();
    char                        separator ='\t'; 
    wstring                        str,strLeft,strRight;
    deque<wstring>                WStrDQ;
    size_t                        pos=-1;
    wstring                        s0;

    g_2And1Map.clear();
    g_1And2Map.clear();
    
    for(int j=0;it!=m._LineWStrDQ.end();it++,nLine++,j++)
    {
        if(j<2)continue;
        
        WStrDQ.clear();
        str=*it;
        
        //处理结果压入
        wstring  s0, s1;
        //分隔符处理
        pos=str.find(separator);
        if (pos == string::npos)
            continue;

        s0 = str.substr(0, pos);
        s1 = str.substr(pos + 1);
        
        size_t pos = s0.find(_T("\r\n"));
        if (pos != string::npos)s0=s0.substr(0,s0.length()-2);
        pos = s1.find(_T("\r\n"));
        if (pos != string::npos)s1 = s1.substr(0, s1.length() - 2);

        if(s0==s1)continue;
            
        g_1And2Map.insert(pair<wstring,wstring>(s0,s1));
        g_2And1Map.insert(pair<wstring,wstring>(s1,s0));
        
    }

    wstring  wsName1 = wsName + L"1";
    wstring  wsName2 = wsName + L"2";
    if (nFlag == 3)
    {
        g_maps.insert(pair<wstring, map<wstring, wstring>>(wsName1, g_1And2Map));
        g_maps.insert(pair<wstring, map<wstring, wstring>>(wsName2, g_2And1Map));
    }
    else if (nFlag == 2)
    {
        g_maps.insert(pair<wstring, map<wstring, wstring>>(wsName2, g_2And1Map));
    }
    else if (nFlag == 1)
    {
        g_maps.insert(pair<wstring, map<wstring, wstring>>(wsName1, g_1And2Map));
    }
    else
        ;

    map<wstring, wstring>().swap(g_1And2Map);
    map<wstring, wstring>().swap(g_2And1Map);
}

void CKOpenCCExport::CKOpenCC_Switch(KWString& sName,KWString& QWSIn,KWString& QSWOut,int nFlag)
{
    wstring wsName = sName.c_str();

    if(nFlag==1)
        wsName = wsName + L"1";
    else if (nFlag == 2)
        wsName = wsName + L"2";
    else
        return;

    auto it0 = g_maps.find(wsName);
    if (it0 == g_maps.end())return;
    
    
    wstring str(QWSIn.c_str());
    wstring s,sOut;
    map<wstring,wstring>::iterator it=it0->second.end();
    size_t Len=str.length();
    for(size_t i=0;i<Len;i++)
    {
        s=str[i];
        
        //4字词
        if(i<=Len-4)
        {
            wstring s0=s+str[i+1]+str[i+2]+str[i+3];
            it=it0->second.find(s0);
            if(it!=it0->second.end())
            {
                sOut+=it->second;
                i++;i++;i++;
                continue;
            }
        }
        //3字词
        if(i<=Len-3)
        {
            wstring s0=s+str[i+1]+str[i+2];
            it = it0->second.find(s0);
            if (it != it0->second.end())
            {
                sOut+=it->second;
                i++;i++;
                continue;
            }
        }
        //2字词
        if(i<=Len-2)
        {            
            wstring s0=s+str[i+1];
            it = it0->second.find(s0);
            if (it != it0->second.end())
            {                    
                sOut+=it->second;
    
                i++;
                continue;
            }
        }
        //单字
        it= it0->second.find(s);
        if(it!= it0->second.end())
            sOut+=it->second;
        else
            sOut+=s;
    }

    QSWOut = sOut.c_str();
}


3.定义加载文本映射文件类的头文件和实现代码

#include "pch.h"
#include "TextFileIO.h"
#include "io.h"
#include <iostream>  
#include <fstream> 
// Define tstring
#ifdef UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

// define Open
#if ((defined UNICODE)|| (defined _UNICODE))
#define Open OpenW
#else
#define Open OpenA
#endif

// define ReadLine
#if ((defined UNICODE)|| (defined _UNICODE))
#define ReadLine ReadLineW
#else
#define ReadLine ReadLineA
#endif

// Define WriteLine
#if ((defined UNICODE)|| (defined _UNICODE))
#define WriteLine WriteLineW
#else
#define WriteLine WriteLineA
#endif

// Define check file encoding type
#if ((defined UNICODE)|| (defined _UNICODE))
#define CheckFileEncodingType CheckFileEncodingTypeW
#else
#define CheckFileEncodingType CheckFileEncodingTypeA
#endif

CTextFileIO::CTextFileIO(void)
:_encodingType(ANSI)
, _IsValidate(false)
{
    _file=0;
}

CTextFileIO::~CTextFileIO(void)
{
    if(_file)
        fclose(_file);

    deque<wstring>().swap(_LineWStrDQ);
}
BOOL CTextFileIO::WriteWStringToUnicodeTxtFile(LPCTSTR lpPath,wstring& WStr)
{
    ofstream    out;//流对象
    
    out.open(lpPath,ios::binary|ios::ate|ios::out);
    char const* pos=(char const*)WStr.c_str();
    //写入Unicode文件头
    char const* const UnicodeHead="\xFF\xFE";
    out.write(UnicodeHead,2);
    out.write(pos,WStr.length()*2);
    
    out.close();
    return _IsValidate;
}
UINT g_nLine=0;
BOOL CTextFileIO::ReadWholeTextFileToDQ(LPCTSTR lpPath)
{
    if(!(_IsValidate=Open(lpPath,READ)))     return _IsValidate;
    _encodingType=CheckFileEncodingType(lpPath);

    tstring str;

    int i=0;
    bool bFlag=false;
    g_nLine=0;
    do
    {
        bFlag=ReadLine(str);
        
        wstring WStr(str.c_str());
        if(i==0&&_encodingType!=ANSI)
            WStr=WStr.substr(1);

        size_t  pos = WStr.find(TEXT("\r\n"));
        if(pos!= string::npos)WStr.replace(pos,2,TEXT(""));
        
        _LineWStrDQ.push_back(WStr);
        i++;
    }while(bFlag);
    

    if(_file)
        fclose(_file);

    return _IsValidate;
}
BOOL CTextFileIO::WStringFromTxtFile(LPCTSTR lpPath,wstring& WStr)
{
    BOOL flag=ReadWholeTextFileToDQ(lpPath);

    if(flag)
    {
        WStr=wstring();
        deque<wstring>::iterator it=_LineWStrDQ.begin();
        for(;it!=_LineWStrDQ.end();it++)
            WStr+=*it+TEXT("\r\n");

        deque<wstring>().swap(_LineWStrDQ);
    }
    
    return flag;
}
CTextFileIO::CTextFileIO(const WCHAR* filename,  EDealMode mode)
{
    // Testing for file type
    _encodingType=CTextFileIO::CheckFileEncodingTypeW(filename);

    _IsValidate=OpenW(filename,mode);


}

CTextFileIO::CTextFileIO(const char* filename,  EDealMode mode)
{
    // Testing for file type
    _encodingType=CTextFileIO::CheckFileEncodingTypeA(filename);

    _IsValidate=OpenA(filename,mode);


}

// Open file,UNICODE version
BOOL CTextFileIO::OpenW(const WCHAR* const filename, EDealMode mode)
{
    _wfopen_s(&_file,filename,mode==READ?L"rb":L"wb");
    if(_file==NULL)
        return FALSE;
    
    // Write Encoding tag
    if(mode==WRITE)
        WriteEncodingTag(_encodingType);
    
    // Seek  file pos
    if(mode==READ)
        OmitEncodingTag(_encodingType);
    
    return TRUE;
}

// Open file,ANSI Version
BOOL CTextFileIO::OpenA(const char* const filename, EDealMode mode)
{
    fopen_s(&_file,filename,mode==READ?"rb":"wb");
    if(_file==NULL)
        return FALSE;
    // Write Encoding tag
    if(mode==WRITE)
        WriteEncodingTag(_encodingType);
    
    // Seek  file pos
    if(mode==READ)
        OmitEncodingTag(_encodingType);
    
    return TRUE;
}

bool CTextFileIO::_ReadLine(string& s, int eol, int eof)
{

    // reset string
    s.clear();
    
    // read one char at a time
    while (true)
    {
        // read char
        int c = fgetc(_file);        
        
        // check for EOF
        if (c == eof || c == EOF) return false;
        
        // append this character to the string
        s += c;

        // check for EOL
        if (c == eol) return true;
    };
}

// Read a line from file,return value is UNICODE string
bool CTextFileIO::_ReadLine(wstring& s, wint_t eol, wint_t eof)
{
    // reset string
    s.clear();

    
    // read one wide char at a time
    while (true)
    {
        // read wide char
        wint_t c = fgetwc(_file);
        
        // check for EOF
        if (c == eof || c == WEOF) return false;

        // append the wide character to the string        
        s += c;

        // check for EOL
        if (c == eol) return true;
    };
    return 0;
}

bool CTextFileIO::_WriteLine(const char *const s, int ret,int newline, size_t length)
{
    // check if the pointer is valid
    if (!s)
    {
        return false;
    };
    
    // calculate the string's length
    if (length==-1)
    {
        length = strlen(s);
    };
    
    // write the string to the file
    size_t n = fwrite(s, sizeof(char), length, _file);
            
    // write line break to the file
    fputc(ret, _file);
    fputc(newline, _file);
            
    // return whether the write operation was successful
    return (n == length);
}

bool CTextFileIO::_WriteLine(const wchar_t *const s, wint_t ret,wint_t newline, size_t length)
{
        // check if the pointer is valid
    if (!s)
    {
        return false;
    };
        
    // calculate the string's length
    if (length==-1)
    {
        length = wcslen(s);
    };    
    
    // write the string to the file
    size_t n = fwrite(s, sizeof(wchar_t), length, _file);
            
    // write line break to the file
    fputwc(ret, _file);
    fputwc(newline,_file);
            
    // return whether the write operation was successful
    return (n == length);
}

// Unicode version of read line

bool CTextFileIO::ReadLineW(std::wstring &ws)
{
    bool bResult=false;
    switch(_encodingType)
    {
    case ANSI:
        {
            std::string s;
            bResult=_ReadLine(s);
            s+='\0';
            int nLength=MultiByteToWideChar(CP_OEMCP,MB_PRECOMPOSED,s.c_str(),-1,NULL,0);
            LPWSTR lpwStr=new WCHAR[nLength];
            MultiByteToWideChar(CP_OEMCP,MB_PRECOMPOSED,s.c_str(), nLength,lpwStr,nLength);
            ws=lpwStr;
            
            //5行内出现utf-8 则认为是不加BOM的 UTF-8文件
            g_nLine++;
            if(g_nLine<5)
                if(s.find("utf-8")!=-1||s.find("UTF-8")!=-1||
                    s.find("UTF_8")!=-1||    s.find("utf_8")!=-1)
                    _encodingType=UTF_8;
        }
        break;
    case UTF_8:
        {
            std::string s;
            bResult=_ReadLine(s);
            s+='\0';
            int nLength=MultiByteToWideChar(CP_UTF8,0,s.c_str(),-1,NULL,0);
            LPWSTR lpwStr=new WCHAR[nLength];
            MultiByteToWideChar(CP_UTF8,0,s.c_str(),-1,lpwStr,nLength);
            ws=lpwStr;
        }
        break;
    case UTF16_BE:
        {
            std::wstring s;
            bResult=_ReadLine(s,0x0A00);
            // Convert UTF16 big endian to UTF little endian
            
            size_t nLength=s.length()*2+1;
            BYTE *src=(BYTE*)s.c_str();
            BYTE *dst=new BYTE[nLength];
            
            memset(dst,0,nLength);
            
            for(size_t i=0;i<nLength;)
            {
                dst[i]=src[i+1];
                dst[i+1]=src[i];
                i+=2;
            }

            ws=(WCHAR*)dst;
            
            delete dst;
        }
        break;
    case UTF16_LE:
        {
            std::wstring s;
            bResult=_ReadLine(s);
            ws=s;
        }
        break;
    case UTF32_BE:
        {
            // TODO:will be implement later
        }
        break;
    case UTF32_LE:
        {
            // TODO:will be implement later
        }
        break;
    default:
        {
        }
    }
    return bResult;
}


// ANSI version of read line
bool CTextFileIO::ReadLineA(std::string &s)
{
    bool bResult=false;
    switch(_encodingType)
    {
    case ANSI:
        {
            bResult=_ReadLine(s);
        }
        break;
    case UTF_8:
        {
            std::string s;
            bResult=_ReadLine(s);
            s+='\0';

            // Convert utf-8 to ANSI,must first convert to UTF16-LE,then to ANSI
            int nLength=MultiByteToWideChar(CP_UTF8,0,s.c_str(),-1,NULL,0);
            LPWSTR lpwStr=new WCHAR[nLength];
            MultiByteToWideChar(CP_UTF8,0,s.c_str(),-1,lpwStr,nLength);
            
            int Length=WideCharToMultiByte(CP_ACP,0,lpwStr,nLength,NULL,0,NULL,NULL);
            LPSTR lpStr=new CHAR[nLength];
            WideCharToMultiByte(CP_UTF8,0,lpwStr,nLength,lpStr,Length,NULL,NULL);
            s=lpStr;
        }
        break;
    case UTF16_BE:
        {
            // Convert UTF16 big endian to UTF little endian
            std::wstring ws;
            bResult=_ReadLine(ws,0x0A00);
            size_t nLength=ws.length()*2+1;
            BYTE *src=(BYTE*)ws.c_str();
            BYTE *dst=new BYTE[nLength];
            memset(dst,0,nLength);
            for(size_t i=0;i<nLength;)
            {
                dst[i]=src[i+1];
                dst[i+1]=src[i];
                i+=2;
            }
            ws.clear();
            ws=(WCHAR*)dst;
            delete dst;

            // Convert UTF16 little endian to ANSI
            int Length=WideCharToMultiByte(CP_ACP,0,ws.c_str(),-1,NULL,0,NULL,NULL);
            LPSTR lpStr=new CHAR[Length];
            WideCharToMultiByte(CP_ACP,0,ws.c_str(),-1,lpStr,Length,NULL,NULL);
            s=lpStr;
        }
        break;
    case UTF16_LE:
        {
            std::wstring ws;
            bResult=_ReadLine(ws);
            int nLength=WideCharToMultiByte(CP_ACP,0,ws.c_str(),-1,NULL,0,NULL,NULL);
            LPSTR lpStr=new CHAR[nLength];
            WideCharToMultiByte(CP_ACP,0,ws.c_str(),-1,lpStr,nLength,NULL,NULL);
            s=lpStr;
        }
        break;
    case UTF32_BE:
        {
            // TODO:will be implement later            
        }
        break;
    case UTF32_LE:
        {
            // TODO:will be implement later
        }
        break;
    default:
        {
        }
    }
    return bResult;
}

// UNICODE version of write line
bool CTextFileIO::WriteLineW(const wchar_t *const wc)
{
    bool bResult=false;
    switch(_encodingType)
    {
    case ANSI:
        {
            int nLength=WideCharToMultiByte(CP_ACP,0,wc,-1,NULL,0,NULL,NULL);
            LPSTR lpStr=new char[nLength];
            WideCharToMultiByte(CP_ACP,0,wc,-1,lpStr,nLength,NULL,NULL);
            
            bResult=_WriteLine(lpStr);
        }
        break;
    case UTF_8:
        {
            // Convert utf-16 to UTF8
            int nLength=WideCharToMultiByte(CP_UTF8,0,wc,-1,NULL,0,NULL,NULL);
            LPSTR lpStr=new CHAR[nLength];
            WideCharToMultiByte(CP_UTF8,0,wc,-1,lpStr,nLength,NULL,NULL);
            // Write to file

            bResult=_WriteLine(lpStr);
        }
        break;
    case UTF16_BE:
        {
            BYTE *src=(BYTE*)wc;
            size_t nLength=wcslen(wc)*2;
            BYTE *dst=new BYTE[nLength]+2;
            memset(dst,0,nLength+2);
            for(size_t i=0;i<nLength;)
            {
                dst[i]=src[i+1];
                dst[i+1]=src[i];
                i+=2;
            }

            bResult=_WriteLine((wchar_t*)dst,0x0D00,0x0A00);
        }
        break;
    case UTF16_LE:
        {
            bResult=_WriteLine(wc);
        }
        break;
    case UTF32_BE:
        {
            // TODO:will be implement later
        }
        break;
    case UTF32_LE:
        {
            // TODO:will be implement later
        }
        break;
    default:
        {
        }
    }
    return bResult;
}

// ANSI Version of writeline
bool CTextFileIO::WriteLineA(const char *const c)
{
    bool bResult=false;
    switch(_encodingType)
    {
    case ANSI:
        {
            bResult=_WriteLine(c);
        }
        break;
    case UTF_8:
        {
            // First convert to UTF16 litter endier
            int nLength=MultiByteToWideChar(CP_ACP,0,c,-1,NULL,0);
            LPWSTR lpWStr=new WCHAR[nLength];
            MultiByteToWideChar(CP_ACP,0,c,-1,lpWStr,nLength);

            // Convert utf-16 to UTF8
            int Length=WideCharToMultiByte(CP_UTF8,0,lpWStr,nLength,NULL,0,NULL,NULL);
            LPSTR lpStr=new CHAR[Length];
            WideCharToMultiByte(CP_UTF8,0,lpWStr,nLength,lpStr,Length,NULL,NULL);
            
            // Write to file
            bResult=_WriteLine(lpStr);
        }
        break;
    case UTF16_BE:
        {
            // First convert to UTF16 litter endian
            int nLength=MultiByteToWideChar(CP_ACP,0,c,-1,NULL,0);
            LPWSTR lpWStr=new WCHAR[nLength];
            MultiByteToWideChar(CP_ACP,0,c,-1,lpWStr,nLength);
            
            // Then convert to UTF16 big endian
            BYTE *src=(BYTE*)lpWStr;
            size_t Length=wcslen(lpWStr)*2;
            BYTE *dst=new BYTE[Length+2];
            memset(dst,0,Length+2);
            for(size_t i=0;i<Length;)
            {
                dst[i]=src[i+1];
                dst[i+1]=src[i];
                i+=2;
            }
            
            // Write to file
            bResult=_WriteLine((wchar_t*)dst,0x0D00,0x0A00);
        }
        break;
    case UTF16_LE:
        {
            // First convert to UTF16 litter endian
            int nLength=MultiByteToWideChar(CP_ACP,0,c,-1,NULL,0);
            LPWSTR lpWStr=new WCHAR[nLength];
            MultiByteToWideChar(CP_ACP,0,c,-1,lpWStr,nLength);
            bResult=_WriteLine(lpWStr);
        }
        break;
    case UTF32_BE:
        {
            // TODO:will be implement later
        }
        break;
    case UTF32_LE:
        {
            // TODO:will be implement later
        }
        break;
    default:
        {
        }
    }
    return bResult;
}
// Check file encoding type
CTextFileIO::EncodingType CTextFileIO::CheckFileEncodingTypeW(const WCHAR* const filename)
{
    FILE* _file=0;
    _wfopen_s(&_file,filename,L"rb");
    // Read first 4 byte for testing
    BYTE* buf=new BYTE[4];
    size_t nRead=fread((void*)buf,sizeof(BYTE),4,_file);
    // Close file
    fclose(_file);

    // Testing
    if(nRead<2)
        return ANSI;
    // Testting tocken
    BYTE utf32_le[]={0xFF,0xFE,0x00,0x00};
    if(memcmp(buf,&utf32_le,4)==0)
        return UTF32_LE;

    BYTE utf32_be[]={0x00,0x00,0xFE,0xFF};
    if(memcmp(buf,&utf32_be,4)==0)
        return UTF32_BE;

    BYTE utf_8[]={0xEF,0xBB,0xBF};
    if(memcmp(buf,&utf_8,3)==0)
        return UTF_8;

    BYTE utf16_le[]={0xFF,0xFE};
    if(memcmp(buf,&utf16_le,2)==0)
        return UTF16_LE;

    BYTE utf16_be[]={0xFE,0xFF};
    if(memcmp(buf,&utf16_be,2)==0)
        return UTF16_BE;
    
    // Else
    return ANSI;
}

CTextFileIO::EncodingType CTextFileIO::CheckFileEncodingTypeA(const CHAR* const filename)
{
    FILE* _file=0;
    fopen_s(&_file,filename,"rb");
    // Read first 4 byte for testing
    BYTE* buf=new BYTE[4];
    size_t nRead=fread((void*)buf,sizeof(BYTE),4,_file);
    // Close file
    fclose(_file);

    // Testing
    if(nRead<2)
        return ANSI;

    //UTF32_LE 编码:
    BYTE utf32_le[]={0xFF,0xFE,0x00,0x00};
    if(memcmp(buf,&utf32_le,4)==0)
        return UTF32_LE;
    
    //UTF32_BE 编码:
    BYTE utf32_be[]={0x00,0x00,0xFE,0xFF};
    if(memcmp(buf,&utf32_be,4)==0)
        return UTF32_BE;
    
    //UTF-8 编码:
    BYTE utf_8[]={0xEF,0xBB,0xBF};
    if(memcmp(buf,&utf_8,3)==0)
        return UTF_8;

    //UNICODE编码 UTF16_LE:
    BYTE utf16_le[]={0xFF,0xFE};
    if(memcmp(buf,&utf16_le,2)==0)
        return UTF16_LE;
    
    //Unicode big endian编码 UTF16_BE :
    BYTE utf16_be[]={0xFE,0xFF};
    if(memcmp(buf,&utf16_be,2)==0)
        return UTF16_BE;
    
    // ANSI编码:无文件头(文件编码开头标志性字节)
    return ANSI;
}
// Omit file encoding tag
int CTextFileIO::OmitEncodingTag(EncodingType type)
{
    int nResult=0;
    switch(_encodingType)
    {
    case UTF_8:
            nResult=fseek(_file,3,SEEK_SET);
        break;
    case UTF16_BE:
    case UTF16_LE:
            nResult=fseek(_file,2,SEEK_SET);
        break;
    case UTF32_BE:
    case UTF32_LE:
        nResult=fseek(_file,4,SEEK_SET);
        break;
    }
    return nResult;
}

// Write the encoding type tag an beginner of file
void CTextFileIO::WriteEncodingTag(EncodingType type)
{
    switch(type)
    {
    case UTF_8:
        {
            BYTE utf_8[]={0xEF,0xBB,0xBF};
            fwrite(utf_8,sizeof(BYTE),3,_file);
        }            
        break;
    case UTF16_BE:
        {
            BYTE utf16_be[]={0xFE,0xFF};
            fwrite(utf16_be,sizeof(BYTE),2,_file);
        }
        break;
    case UTF16_LE:
        {
            BYTE utf16_le[]={0xFF,0xFE};
            fwrite(utf16_le,sizeof(BYTE),2,_file);
        }            
        break;
    case UTF32_BE:
        {
            BYTE utf32_be[]={0x00,0x00,0xFE,0xFF};
            fwrite(utf32_be,sizeof(BYTE),4,_file);
        }
    case UTF32_LE:
        {
            BYTE utf32_le[]={0xFF,0xFE,0x00,0x00};
            fwrite(utf32_le,sizeof(BYTE),4,_file);
        }        
        break;
    default:; // ANSI, do nothing
    }

}

// 头文件

#ifndef H_89412764_0AAE_4D28_8500_75B6D40CEAE4
#define H_89412764_0AAE_4D28_8500_75B6D40CEAE4

#pragma once

#include <stdio.h>
#include <string>
#include <windows.h>
#include <tchar.h>
#include <deque>

using namespace std;

// CTextFileIO class declaration
class CTextFileIO
{
public:
    CTextFileIO(void);
public:
    ~CTextFileIO(void);
public:
    enum EDealMode {READ,WRITE};
    // Text file encoding type enum
    enum EncodingType {ANSI,UTF16_LE,UTF16_BE,UTF32_LE,UTF32_BE,UTF_8};
    deque<wstring>   _LineWStrDQ;
public:
    CTextFileIO(const WCHAR* filename,  EDealMode mode);
    CTextFileIO(const char *filename,EDealMode mode);

public:
    // Open the file
    BOOL OpenW(const WCHAR* const filename,  EDealMode mode);
    BOOL OpenA(const char* const filename, EDealMode mode);

    BOOL ReadWholeTextFileToDQ(LPCTSTR lpPath);
    BOOL WStringFromTxtFile(LPCTSTR lpPath, wstring& WStr);
    BOOL WriteWStringToUnicodeTxtFile(LPCTSTR lpPath, wstring& WStr);
private:
    
    // Internale FILE object 
    FILE* _file;

private:
    // Read a line from a MBCS file 
    // Return value:if end of file,return value is false,else is true
    bool _ReadLine(string& s, int eol='\n', int eof=EOF);
    
    // Read aline from a UNICODE file
    // Return value:if end of file,return value is false,else is true
    bool _ReadLine(wstring& s, wint_t eol=L'\n', wint_t eof=WEOF);

    // ANSI version of read line
    bool ReadLineA(std::string &s);
    
    // Unicode version of read line
    bool ReadLineW(std::wstring &ws);
private:
    // To write an ANSI zero-terminated string (please consider using STL instead)
    bool _WriteLine(const char* const s, int ret = '\r',int newline='\n', size_t length = -1);

    // To write a Unicode zero-terminated string (please consider using STL instead)
    bool _WriteLine(const wchar_t* const s, wint_t =L'\r', wint_t newline = L'\n', size_t length = -1);

    // To write an ANSI STL string
    bool _WriteLine(const std::string& s, int ret = '\r',int newline='\n')
    {
        return _WriteLine(s.c_str(), ret,newline, s.size());
    };

    // To write a Unicode STL string
    bool _WriteLine(const std::wstring& s, wint_t ret=L'\r', wint_t newline = L'\n')
    {
        return _WriteLine(s.c_str(), ret, newline, s.size());
    };
    // ANSI version of write line
    bool WriteLineA(const char* const s);
    bool WriteLineA(const std::string &s)
    {
        return WriteLineA(s.c_str());
    }
    // Unicode version of write line
    bool WriteLineW(const wchar_t* const ws);
    bool WriteLineW(const std::wstring &ws)
    {
        return WriteLineW(ws.c_str());
    };


private:
    // File encoding type
    EncodingType _encodingType;
public:
    // Check file encoding type
    static EncodingType CheckFileEncodingTypeW(const WCHAR* const filename);
    static EncodingType CheckFileEncodingTypeA(const char* const filename);
public:
    // Get current open file's encoding type
    CTextFileIO::EncodingType GetEncodingType(void)
    {
        return _encodingType;
    }
    // Omit file encoding tag
    int OmitEncodingTag(EncodingType type);
    // Indicate file can be read or not
    BOOL _IsValidate;
public:

    // Check file is validate to read
    BOOL IsValidate(void)
    {
        return _IsValidate;
    }

    // Write the encoding type tag an beginner of file
    void WriteEncodingTag(EncodingType type);
};

#endif
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

高度自定义的简繁转换 VS2022 C++ 工程 的相关文章

随机推荐

  • 解决rosbag时间戳未对齐的解决方法

    解决rosbag时间戳未对齐的解决方法 Reference ROS org rosbag Cookbook http wiki ros org rosbag Cookbook rosbag在存储时间时 xff0c 接收消息的时间和生成消息的
  • ROS+python控制小乌龟走方形的实现rospy

    常见的简陋的控制乌龟行走方形的方式很简单 xff0c 例如 xff1a 代码有些地方是测试用的 xff0c 可以不要 usr bin env python from pickle import TRUE import rospy from
  • C++ STL算法

    C 43 43 STL算法 1 非修正序列算法1 1 adjacent find first last 1 2 count first last val 2 修正序列算法2 1 random shuffle first last 2 2 p
  • git子模块的修改和更新操作

    Reference git子模块的修改和更新操作 1 子库与父库 git关于子模块的官方文档链接 xff1a https git scm com book zh v2 Git E5 B7 A5 E5 85 B7 E5 AD 90 E6 A8
  • CMakeLists Option使用简介

    CMakeLists Option使用简介 1 基本格式2 示例3 基本用法4 C程序条件编译5 次项目之间选项的关系 Reference xff1a CMake之Option使用简介 CMake中的option用于控制编译流程 xff0c
  • 四轴一键起飞定高定点悬停伪代码

    四轴飞行器一键起飞定高 xff0c 降落 xff0c 光流定点悬停控制算法伪代码 基于飞控系统的二次开发
  • 开源飞控地面站 Openpilot GCS (现在的Librepilot GCS)源码分析  (2)地图插件

    xff08 xff11 xff09 OpenPilot项目中有地图显示模块 xff08 xff12 xff09 地图显示模块的插件是 xff1a opmap插件 xff0c 位置是src gt plugins gt opmap xff08
  • ubuntu 下运行程序报错 对‘std::cout’未定义的引用:gcc与g++的区别

    目录 1 问题提出 2 gcc与g 43 43 的区别 2 1 预处理 2 2 编译 2 3 汇编 2 4 链接运行 3 总结 1 问题提出 linux初学 xff0c 写了个例程 xff0c 用gcc o编译时出现以下问题 xff1a 后
  • 2.2 开启调度器

    开启调度器 void vTaskStartScheduler void BaseType t xReturn if configSUPPORT STATIC ALLOCATION 61 61 1 静态创建空闲任务 StaticTask t
  • 4. 消息队列

    消息队列 队列又称消息队列 xff0c 常用于任务间通信的数据结构 xff0c 可以在任务与任务之间 xff0c 中断与任务之间传递消息 xff0c 实现任务接收来自其他任务或中断的不固定长度的消息 任务可从消息队列中读取消消息 xff0c
  • 网卡接口

    网络接口 网络接口 xff08 以太网 xff09 是硬件接口 xff0c LwIP是软件 xff0c 并且网卡也是由很多种的 LwIP使用一个数据结构 xff0c nitif来描述网卡 用户提供最底层的接口函数 xff0c LwIP则提供
  • 系统扇区

    系统结构 DBR xff0c 主引导记录 xff1b DPT xff0c 分区表 xff1b DBR xff0c 分区引导扇区 引导扇区 MBR Main Boot Record xff0c 主引导扇区 xff0c 硬盘主引导记录区 xff
  • 华为3COM交换机配置命令详解

    1 配置文件相关命令 Quidway display current configuration 显示当前生效的配置 Quidway display saved configuration xff1b 显示flash中配置文件 xff0c
  • 分区结构

    分区结构 DBR xff0c 引导记录区 xff0c 包括一个引导程序和一个BPB xff0c 即本分区参数记录表 系统可直接访问的第一个扇区 xff0c 大小为512个字节 xff08 特殊情况占用其他保留扇区 xff09 512字节中
  • 1. 列表和列表项

    列表和列表项 列表 列表是一个数据结构 xff0c 用来追踪任务 xff0c 列表中有一个指针指向列表项 列表是一个结构体 xff0c 内部携带一个指针 xff0c 指针指向列表项 xff0c 列表项形成双向链式结构挂载在列表下 一个列表下
  • C#简单串口调试助手【傻瓜教程】chanson_chapter01

    简易串口调试助手制作教程 C Winform chanson chapter01 说明 xff1a 本教程基于win10 x64 位操作系统 xff0c 软件环境为Microsoft Visual Studio Community 2015
  • 快速上手Ubuntu之安装篇——安装win7,Ubuntu16.04双系统

    Linux可以说是开发者的系统 xff0c 对于开发者来说 xff0c Linux发行版不仅为我们提供了无数强大的开发工具 xff0c 还能帮助我们从源码上学习操作系统是工作的 而且经常在命令行上工作的我们还能在别人面前耍下酷 Ubuntu
  • SpringBoot中事件的使用

    项目中很多场景可以使用事件来对系统进行解耦 xff0c 让系统更便于维护和扩展 SpringBoot项目默认是支持事件的 xff0c 我们只需要自定义事件 xff0c 然后发布事件 xff0c 之后监听事件处理业务逻辑即可 SpringBo
  • STM32F4串口通信(UART)详解

    UART串口通信 我们在生活中处处都会接触到或者是用到通信 QQ 微信 电话 这些都是最常见的人与人之间远程无线通信的方式 那么也有像红外遥控 蓝牙数据传输等器件或硬件之间的通信 这些通信方式都有一些共同点 无线 易受干扰 信号变差 等 而
  • 高度自定义的简繁转换 VS2022 C++ 工程

    首先秀一下简繁转换结果图 如下 include lt iostream gt include 34 KOpenCC KOpenCCExport h 34 include lt string gt ifdef WIN64 pragma com