Unicode 将GetPrivateProfileStringW与UTF-8编码文件一起使用?

Unicode 将GetPrivateProfileStringW与UTF-8编码文件一起使用?,unicode,utf-8,mfc,ini,Unicode,Utf 8,Mfc,Ini,到目前为止,我的INI文本文件已经进行了Unicode编码,我一直在这样做来读取它: ::GetPrivateProfileStringW( strUpdateSection, strTalkKey, _T(""), strTalk.GetBuffer( _MAX_PATH ), _MAX_PATH, m_

到目前为止,我的INI文本文件已经进行了Unicode编码,我一直在这样做来读取它:

::GetPrivateProfileStringW(
                strUpdateSection,
                strTalkKey,
                _T(""),
                strTalk.GetBuffer( _MAX_PATH ),
                _MAX_PATH,
                m_strPathINI );
strTalk.ReleaseBuffer();
该文件首先从internet下载,然后访问。但是我发现对于阿拉伯语来说,文本文件已经损坏。除非我将编码更改为UTF-8。当我这么做的时候,它会正确下载。但是它不能正确地从INI读取数据

那个么INI文件必须是Unicode编码的吗?或者在函数调用中使用UTF-8也可以吗

我想是时候把程序的这一部分转换成UTF-8编码的XML文件了!干得好

但我想先问个问题

我应该澄清一下,文本文件最初是使用记事本保存为UTF-8的

更新 这是我读取文件时的样子:

BOOL CUpdatePublicTalksDlg::DownloadINI()
{
    CInternetSession    iSession;
    CHttpFile           *pWebFile = NULL;
    CWaitCursor         wait;
    CFile               fileLocal;
    TCHAR               szError[_MAX_PATH];
    int                 iRead = 0, iBytesRead = 0;
    char                szBuffer[4096];
    BOOL                bOK = FALSE;
    DWORD               dwStatusCode;
    CString             strError;

    // ask user to go online
    if( InternetGoOnline( (LPTSTR)(LPCTSTR)m_strURLPathINI, GetSafeHwnd(), 0 ) )
    {
        TRY
        {
            // our session should already be open
            // try to open up internet session to my URL
            // AJT V10.4.0 Use flag INTERNET_FLAG_RELOAD
            pWebFile = (CHttpFile*)iSession.OpenURL( m_strURLPathINI, 1,
                INTERNET_FLAG_TRANSFER_BINARY |
                INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD);

            if(pWebFile != NULL)
            {
                if( pWebFile->QueryInfoStatusCode( dwStatusCode ) )
                {
                    // 20x codes mean success
                    if( (dwStatusCode / 100) == 2 )
                    {
                        // Our downloaded file is only temporary
                        m_strPathINI = theApp.GetTemporaryFilename();

                        if( fileLocal.Open( m_strPathINI,
                            CFile::modeCreate|CFile::modeWrite|CFile::typeBinary ) )
                        {
                            iRead = pWebFile->Read( szBuffer, 4096 );
                            while( iRead > 0 )
                            {   
                                iBytesRead += iRead;
                                fileLocal.Write( szBuffer, iRead );
                                iRead = pWebFile->Read( szBuffer, 4096 );
                            }
                            fileLocal.Close();

                            bOK = TRUE;
                        }
                    }
                    else
                    {
                        // There was a problem!
                        strError.Format( IDS_TPL_INVALID_URL, dwStatusCode );
                        AfxMessageBox( strError,
                                       MB_OK|MB_ICONERROR );
                    }
                }
            }
            else
            {
                AfxMessageBox( ID_STR_UPDATE_CHECK_ERR, MB_OK|MB_ICONERROR );
            }
        }
        CATCH( CException, e )
        {
            e->GetErrorMessage( szError, _MAX_PATH );
            AfxMessageBox( szError, MB_OK|MB_ICONERROR );
        }
        END_CATCH

        // Tidy up
        if( pWebFile != NULL )
        {
            pWebFile->Close();
            delete pWebFile;
        }

        iSession.Close();
    }

    return bOK;
}
int CUpdatePublicTalksDlg::ReadTalkUpdateINI()
{
    int         iLastUpdate = 0, iUpdate;
    int         iNumTalks, iTalk;
    NEW_TALK_S  sTalk;
    CString     strUpdateSection, strTalkKey, strTalk;

    // How many possible updates are there?
    m_iNumUpdates = ::GetPrivateProfileIntW(
                        _T("TalkUpdates"),
                        _T("NumberUpdates"),
                        0,
                        m_strPathINI );

    // What what the last talk update count?
    iLastUpdate = theApp.GetLastTalkUpdateCount();

    // Loop available updates
    for( iUpdate = iLastUpdate + 1; iUpdate <= m_iNumUpdates; iUpdate++ )
    {
        // Build section key
        strUpdateSection.Format( _T("Update%d"), iUpdate );

        // How many talks are there?
        iNumTalks = ::GetPrivateProfileIntW(
                            strUpdateSection,
                            _T("NumberTalks"),
                            0,
                            m_strPathINI );
        // Loop talks
        for( iTalk = 1; iTalk <= iNumTalks; iTalk++ )
        {
            // Build key
            strTalkKey.Format( _T("Talk%d"), iTalk );

            // Get talk information
            ::GetPrivateProfileStringW(
                            strUpdateSection,
                            strTalkKey,
                            _T(""),
                            strTalk.GetBuffer( _MAX_PATH ),
                            _MAX_PATH,
                            m_strPathINI );
            strTalk.ReleaseBuffer();

            // Decode talk information
            DecodeNewTalk( strTalk, sTalk );

            // Does it already exists in the database?
            // AJT v11.2.0 Bug fix - we want *all* new talks to show
            //if( !IsExistingTalk( sTalk.iTalkNumber ) )
            //{
            //if(!LocateExistingTheme(sTalk, false))
            AddNewTalkToListBox( sTalk );
            //}
        }
    }

    // Return the actual amount of updates possible
    return m_iNumUpdates - iLastUpdate;
}

以下是我下载文件的方式:

BOOL CUpdatePublicTalksDlg::DownloadINI()
{
    CInternetSession    iSession;
    CHttpFile           *pWebFile = NULL;
    CWaitCursor         wait;
    CFile               fileLocal;
    TCHAR               szError[_MAX_PATH];
    int                 iRead = 0, iBytesRead = 0;
    char                szBuffer[4096];
    BOOL                bOK = FALSE;
    DWORD               dwStatusCode;
    CString             strError;

    // ask user to go online
    if( InternetGoOnline( (LPTSTR)(LPCTSTR)m_strURLPathINI, GetSafeHwnd(), 0 ) )
    {
        TRY
        {
            // our session should already be open
            // try to open up internet session to my URL
            // AJT V10.4.0 Use flag INTERNET_FLAG_RELOAD
            pWebFile = (CHttpFile*)iSession.OpenURL( m_strURLPathINI, 1,
                INTERNET_FLAG_TRANSFER_BINARY |
                INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD);

            if(pWebFile != NULL)
            {
                if( pWebFile->QueryInfoStatusCode( dwStatusCode ) )
                {
                    // 20x codes mean success
                    if( (dwStatusCode / 100) == 2 )
                    {
                        // Our downloaded file is only temporary
                        m_strPathINI = theApp.GetTemporaryFilename();

                        if( fileLocal.Open( m_strPathINI,
                            CFile::modeCreate|CFile::modeWrite|CFile::typeBinary ) )
                        {
                            iRead = pWebFile->Read( szBuffer, 4096 );
                            while( iRead > 0 )
                            {   
                                iBytesRead += iRead;
                                fileLocal.Write( szBuffer, iRead );
                                iRead = pWebFile->Read( szBuffer, 4096 );
                            }
                            fileLocal.Close();

                            bOK = TRUE;
                        }
                    }
                    else
                    {
                        // There was a problem!
                        strError.Format( IDS_TPL_INVALID_URL, dwStatusCode );
                        AfxMessageBox( strError,
                                       MB_OK|MB_ICONERROR );
                    }
                }
            }
            else
            {
                AfxMessageBox( ID_STR_UPDATE_CHECK_ERR, MB_OK|MB_ICONERROR );
            }
        }
        CATCH( CException, e )
        {
            e->GetErrorMessage( szError, _MAX_PATH );
            AfxMessageBox( szError, MB_OK|MB_ICONERROR );
        }
        END_CATCH

        // Tidy up
        if( pWebFile != NULL )
        {
            pWebFile->Close();
            delete pWebFile;
        }

        iSession.Close();
    }

    return bOK;
}
int CUpdatePublicTalksDlg::ReadTalkUpdateINI()
{
    int         iLastUpdate = 0, iUpdate;
    int         iNumTalks, iTalk;
    NEW_TALK_S  sTalk;
    CString     strUpdateSection, strTalkKey, strTalk;

    // How many possible updates are there?
    m_iNumUpdates = ::GetPrivateProfileIntW(
                        _T("TalkUpdates"),
                        _T("NumberUpdates"),
                        0,
                        m_strPathINI );

    // What what the last talk update count?
    iLastUpdate = theApp.GetLastTalkUpdateCount();

    // Loop available updates
    for( iUpdate = iLastUpdate + 1; iUpdate <= m_iNumUpdates; iUpdate++ )
    {
        // Build section key
        strUpdateSection.Format( _T("Update%d"), iUpdate );

        // How many talks are there?
        iNumTalks = ::GetPrivateProfileIntW(
                            strUpdateSection,
                            _T("NumberTalks"),
                            0,
                            m_strPathINI );
        // Loop talks
        for( iTalk = 1; iTalk <= iNumTalks; iTalk++ )
        {
            // Build key
            strTalkKey.Format( _T("Talk%d"), iTalk );

            // Get talk information
            ::GetPrivateProfileStringW(
                            strUpdateSection,
                            strTalkKey,
                            _T(""),
                            strTalk.GetBuffer( _MAX_PATH ),
                            _MAX_PATH,
                            m_strPathINI );
            strTalk.ReleaseBuffer();

            // Decode talk information
            DecodeNewTalk( strTalk, sTalk );

            // Does it already exists in the database?
            // AJT v11.2.0 Bug fix - we want *all* new talks to show
            //if( !IsExistingTalk( sTalk.iTalkNumber ) )
            //{
            //if(!LocateExistingTheme(sTalk, false))
            AddNewTalkToListBox( sTalk );
            //}
        }
    }

    // Return the actual amount of updates possible
    return m_iNumUpdates - iLastUpdate;
}
以下是我读取文件的方式:

BOOL CUpdatePublicTalksDlg::DownloadINI()
{
    CInternetSession    iSession;
    CHttpFile           *pWebFile = NULL;
    CWaitCursor         wait;
    CFile               fileLocal;
    TCHAR               szError[_MAX_PATH];
    int                 iRead = 0, iBytesRead = 0;
    char                szBuffer[4096];
    BOOL                bOK = FALSE;
    DWORD               dwStatusCode;
    CString             strError;

    // ask user to go online
    if( InternetGoOnline( (LPTSTR)(LPCTSTR)m_strURLPathINI, GetSafeHwnd(), 0 ) )
    {
        TRY
        {
            // our session should already be open
            // try to open up internet session to my URL
            // AJT V10.4.0 Use flag INTERNET_FLAG_RELOAD
            pWebFile = (CHttpFile*)iSession.OpenURL( m_strURLPathINI, 1,
                INTERNET_FLAG_TRANSFER_BINARY |
                INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD);

            if(pWebFile != NULL)
            {
                if( pWebFile->QueryInfoStatusCode( dwStatusCode ) )
                {
                    // 20x codes mean success
                    if( (dwStatusCode / 100) == 2 )
                    {
                        // Our downloaded file is only temporary
                        m_strPathINI = theApp.GetTemporaryFilename();

                        if( fileLocal.Open( m_strPathINI,
                            CFile::modeCreate|CFile::modeWrite|CFile::typeBinary ) )
                        {
                            iRead = pWebFile->Read( szBuffer, 4096 );
                            while( iRead > 0 )
                            {   
                                iBytesRead += iRead;
                                fileLocal.Write( szBuffer, iRead );
                                iRead = pWebFile->Read( szBuffer, 4096 );
                            }
                            fileLocal.Close();

                            bOK = TRUE;
                        }
                    }
                    else
                    {
                        // There was a problem!
                        strError.Format( IDS_TPL_INVALID_URL, dwStatusCode );
                        AfxMessageBox( strError,
                                       MB_OK|MB_ICONERROR );
                    }
                }
            }
            else
            {
                AfxMessageBox( ID_STR_UPDATE_CHECK_ERR, MB_OK|MB_ICONERROR );
            }
        }
        CATCH( CException, e )
        {
            e->GetErrorMessage( szError, _MAX_PATH );
            AfxMessageBox( szError, MB_OK|MB_ICONERROR );
        }
        END_CATCH

        // Tidy up
        if( pWebFile != NULL )
        {
            pWebFile->Close();
            delete pWebFile;
        }

        iSession.Close();
    }

    return bOK;
}
int CUpdatePublicTalksDlg::ReadTalkUpdateINI()
{
    int         iLastUpdate = 0, iUpdate;
    int         iNumTalks, iTalk;
    NEW_TALK_S  sTalk;
    CString     strUpdateSection, strTalkKey, strTalk;

    // How many possible updates are there?
    m_iNumUpdates = ::GetPrivateProfileIntW(
                        _T("TalkUpdates"),
                        _T("NumberUpdates"),
                        0,
                        m_strPathINI );

    // What what the last talk update count?
    iLastUpdate = theApp.GetLastTalkUpdateCount();

    // Loop available updates
    for( iUpdate = iLastUpdate + 1; iUpdate <= m_iNumUpdates; iUpdate++ )
    {
        // Build section key
        strUpdateSection.Format( _T("Update%d"), iUpdate );

        // How many talks are there?
        iNumTalks = ::GetPrivateProfileIntW(
                            strUpdateSection,
                            _T("NumberTalks"),
                            0,
                            m_strPathINI );
        // Loop talks
        for( iTalk = 1; iTalk <= iNumTalks; iTalk++ )
        {
            // Build key
            strTalkKey.Format( _T("Talk%d"), iTalk );

            // Get talk information
            ::GetPrivateProfileStringW(
                            strUpdateSection,
                            strTalkKey,
                            _T(""),
                            strTalk.GetBuffer( _MAX_PATH ),
                            _MAX_PATH,
                            m_strPathINI );
            strTalk.ReleaseBuffer();

            // Decode talk information
            DecodeNewTalk( strTalk, sTalk );

            // Does it already exists in the database?
            // AJT v11.2.0 Bug fix - we want *all* new talks to show
            //if( !IsExistingTalk( sTalk.iTalkNumber ) )
            //{
            //if(!LocateExistingTheme(sTalk, false))
            AddNewTalkToListBox( sTalk );
            //}
        }
    }

    // Return the actual amount of updates possible
    return m_iNumUpdates - iLastUpdate;
}
int-CUpdatePublicTalksDlg::ReadTalkUpdateINI()
{
int=0,i更新;
int iNumTalks,iTalk;
新话题;
CString strUpdateSection,strTalkKey,strTalk;
//有多少可能的更新?
m_iNumUpdates=::GetPrivateProfileIntW(
_T(“谈话更新”),
_T(“数字更新”),
0,
m_strPathINI);
//上次的谈话更新计数是多少?
iLastUpdate=theApp.GetLastTalkUpdateCount();
//循环可用更新

对于(iUpdate=iLastUpdate+1;iUpdate@MarkRansom):
W
函数将处理UTF-8编码的INI文件,但仅当该文件上有UTF-8 BOM时,否则该函数要求该文件编码为UTF-16。
a
函数将读取没有BOM的UTF-8编码文件(但不会处理不使用操作系统当前Ansi字符集的Unicode文件名),但它不知道该文件正在使用UTF-8,因此它只会按原样返回UTF-8数据,您必须手动将其转换为UTF-16。“该文件为Unicode。”-Unicode是一个标准。这不有趣。有趣的是使用的编码。我不知道Unicode字符编码,它不能表示阿拉伯文本。您是否单步通过代码找到字符串不显示预期内容的最早点?确保正确解释字符串内容ts在调试器中,在“监视”窗口中使用适当的。没有任何迹象表明文件下载点已损坏。您正在将其加载到类型为
char[4096]
szBuffer
中。调试器的文本可视化工具将假定这是ANSI编码(不是UTF-8或UTF-16)。我建议使用带有适当格式说明符的“监视”窗口。这是确保数据按您希望的方式解释的唯一方法。您的屏幕截图显示了将解释留给调试器可视化工具的结果(调试器可视化工具出错).输入
szBuffer,s8
作为监视表达式应将内容解释为UTF-8编码字符串。