使用带有UTF-8编码文件的GetPrivateProfileStringW?

时间:2017-01-26 17:48:13

标签: unicode utf-8 mfc ini

到目前为止,我的INI文本文件已经 Unicode 编码,我一直在做这样的事情来阅读它:

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

首先从互联网上下载该文件,然后进行访问。但我发现,对于阿拉伯语,文本文件已损坏。除非我将编码更改为 UTF-8 。当我这样做时,它下载正确。但是它没有直接从INI读取数据。

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

我认为现在是时候将我的程序的这部分转换为UTF-8编码的XML文件了!要走的路。

但是想先问这个问题。

我应该澄清一下,使用NotePad将文本文件初始保存为UTF-8。

更新

这是我阅读文件时的样子:

Arabic results

这是我下载文件的方式:

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;
}

这是正在下载的文件:

http://publictalksoftware.co.uk/TalkUpdate_Arabic2.ini

更新

似乎该文件在下载时已损坏:

Corrupt

请参阅更新后的观察:

Watch

取得进展,我现在确认数据正常:

Watch results with s8 format specifier

0 个答案:

没有答案