头文件声明(CStdioFileEx.h):

// StdioFileEx.h: interface for the CStdioFileEx class.
//
// Version 1.1 23 August 2003.  Incorporated fixes from Dennis Jeryd.
// Version 1.3 19 February 2005. Incorporated fixes from Howard J Oh and some of my own.
// Version 1.4 26 February 2005. Fixed stupid screw-up in code from 1.3.
// Version 1.5 18 November 2005. - Incorporated fixes from Andy Goodwin.
//                                          - Allows code page to be specified for reading/writing
//                                          - Properly calculates multibyte buffer size instead of
//                                              assuming lstrlen(s).
//                                          - Should handle UTF8 properly.
//
// Copyright David Pritchard 2003-2005. davidpritchard@ctv.es
//
// You can use this class freely, but please keep my ego happy
// by leaving this comment in place.
//
//#if !defined(AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_)
#define AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#define nUNICODE_BOM                    0xFEFF      // Unicode "byte order mark" which goes at start of file
#define nUTF8_BOM                       0xEFBBBF    // utf-8
#define sNEWLINE                        _T("\r\n")    // New line characters
#define sDEFAULT_UNICODE_FILLER_CHAR    "#"           // Filler char used when no conversion from Unicode to local code page is possibleclass CStdioFileEx : public CStdioFile
{
public:CStdioFileEx();CStdioFileEx(LPCTSTR lpszFileName, UINT nOpenFlags);virtual BOOL  Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL);virtual BOOL    ReadString(CString& rString);virtual void   WriteString(LPCTSTR lpsz);bool          IsFileUnicodeText() { return m_bIsUnicodeText; }bool            IsFileUtf8Text() { return m_bIsUtf8Text; }unsigned long GetCharCount();// Additional flag to allow Unicode text writingstatic const UINT modeWriteUnicode;void          SetCodePage(IN const UINT nCodePage);// static utility functions// --------------------------------------------------------------------------------------------//// CStdioFileEx::GetUnicodeStringFromMultiByteString()//// --------------------------------------------------------------------------------------------// Returns:    int - num. of chars written (0 means error)// Parameters:    char *      szMultiByteString   (IN)        Multi-byte input string//               wchar_t*    szUnicodeString     (OUT)       Unicode outputstring//              int         nUnicodeBufferSize  (IN)        Size of Unicode output buffer (chars) (IN)//                int         nCodePage           (IN)        Code page used to perform conversion//                                                              Default = -1 (Get local code page).//// Purpose:       Gets a Unicode string from a MultiByte string.// Notes:     None.// Exceptions: None.//static int       GetUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, OUT wchar_t* szUnicodeString, IN int nUnicodeBufferSize, IN int nCodePage = -1);// --------------------------------------------------------------------------------------------////   CStdioFileEx::GetMultiByteStringFromUnicodeString()//// --------------------------------------------------------------------------------------------// Returns:    int - number of characters written. 0 means error// Parameters:  wchar_t *   szUnicodeString         (IN)    Unicode input string//              char*       szMultiByteString       (OUT)   Multibyte output string//               int         nMultiByteBufferSize    (IN)    Multibyte buffer size//             int         nCodePage               (IN)    Code page used to perform conversion//                                                              Default = -1 (Get local code page).//// Purpose:       Gets a MultiByte string from a Unicode string.// Notes:     .// Exceptions: None.//static int       GetMultiByteStringFromUnicodeString(wchar_t* szUnicodeString, char* szMultiByteString,int nMultiByteBufferSize, int nCodePage = -1);//---------------------------------------------------------------------------------------------------////  CStdioFileEx::GetRequiredMultiByteLengthForUnicodeString()////---------------------------------------------------------------------------------------------------// Returns:    int// Parameters: wchar_t * szUnicodeString,int nCodePage=-1//// Purpose:      Obtains the multi-byte buffer size needed to accommodate a converted Unicode string.//  Notes:      We can't assume that the buffer length is simply equal to the number of characters//                   because that wouldn't accommodate multibyte characters!//static int        GetRequiredMultiByteLengthForUnicodeString(wchar_t* szUnicodeString, int nCodePage = -1);// --------------------------------------------------------------------------------------------////   CStdioFileEx::IsFileUnicode()//// --------------------------------------------------------------------------------------------// Returns:    bool// Parameters: const CString& sFilePath//// Purpose:       Determines whether a file is Unicode by reading the first character and detecting//                 whether it's the Unicode byte marker.// Notes:     None.// Exceptions: None.//static bool IsFileUnicode(const CString& sFilePath);static bool IsFileUtf8(const CString& sFilePath);static UINT GetCurrentLocaleCodePage();protected:UINT   ProcessFlags(const CString& sFilePath, UINT& nOpenFlags);bool   m_bIsUnicodeText;bool   m_bIsUtf8Text;UINT  m_nFlags;int        m_nFileCodePage;
};#endif // !defined(AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_)

源码定义(CStdioFileEx.cpp):

// StdioFileEx.cpp: implementation of the CStdioFileEx class.
//
// Version 1.1 23 August 2003.  Incorporated fixes from Dennis Jeryd.
// Version 1.3 19 February 2005. Incorporated fixes from Howard J Oh and some of my own.
// Version 1.4 26 February 2005. Fixed stupid screw-up in code from 1.3.
// Version 1.5 18 November 2005. - Incorporated fixes from Andy Goodwin.
//                                          - Allows code page to be specified for reading/writing
//                                          - Properly calculates multibyte buffer size instead of
//                                              assuming lstrlen(s).
//                                          - Should handle UTF8 properly.
//
// Copyright David Pritchard 2003-2005. davidpritchard@ctv.es
//
// You can use this class freely, but please keep my ego happy
// by leaving this comment in place.
//
//#include "stdafx.h"
#include "CStdioFileEx.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif//
// Construction/Destruction
///*static*/ const UINT CStdioFileEx::modeWriteUnicode = 0x20000; // Add this flag to write in UnicodeCStdioFileEx::CStdioFileEx() : CStdioFile()
{m_bIsUnicodeText = false;m_nFileCodePage = -1;m_bIsUtf8Text = false;m_nFlags = CFile::typeText | CFile::modeReadWrite;
}CStdioFileEx::CStdioFileEx(LPCTSTR lpszFileName, UINT nOpenFlags):CStdioFile(lpszFileName, ProcessFlags(lpszFileName, nOpenFlags))
{m_nFileCodePage = -1;
}void CStdioFileEx::SetCodePage(IN const UINT nCodePage)
{m_nFileCodePage = (int)nCodePage;
}BOOL CStdioFileEx::Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError /*=NULL*/)
{// Process any Unicode stuffProcessFlags(lpszFileName, nOpenFlags);if (m_bIsUtf8Text)SetCodePage(CP_UTF8);return CStdioFile::Open(lpszFileName, nOpenFlags, pError);
}BOOL CStdioFileEx::ReadString(CString& rString)
{const int  nMAX_LINE_CHARS = 4096;BOOL        bReadData = FALSE;LPTSTR       lpsz;int            nLen = 0;wchar_t* pszUnicodeString = NULL;char* pszMultiByteString = NULL;int            nChars = 0;try{// If at position 0, discard byte-order mark before readingif (!m_pStream || (GetPosition() == 0 && m_bIsUnicodeText)){wchar_t    cDummy;//       Read(&cDummy, sizeof(_TCHAR));Read(&cDummy, sizeof(wchar_t));}// If compiled for Unicode
#ifdef _UNICODEif (m_bIsUnicodeText){// Do standard stuff - Unicode to Unicode. Seems to work OK.bReadData = CStdioFile::ReadString(rString);}else{pszUnicodeString = new wchar_t[nMAX_LINE_CHARS];pszMultiByteString = new char[nMAX_LINE_CHARS];// Initialise to something safememset(pszUnicodeString, 0, sizeof(wchar_t) * nMAX_LINE_CHARS);memset(pszMultiByteString, 0, sizeof(char) * nMAX_LINE_CHARS);// Read the stringbReadData = (NULL != fgets(pszMultiByteString, nMAX_LINE_CHARS, m_pStream));if (bReadData){// Convert multibyte to Unicode, using the specified code pagenChars = GetUnicodeStringFromMultiByteString(pszMultiByteString, pszUnicodeString, nMAX_LINE_CHARS, m_nFileCodePage);if (nChars > 0){rString = (CString)pszUnicodeString;}}}
#elseif (!m_bIsUnicodeText){// Do standard stuff -- read ANSI in ANSIbReadData = CStdioFile::ReadString(rString);// Get the current code pageUINT nLocaleCodePage = GetCurrentLocaleCodePage();// If we got it OK...if (nLocaleCodePage > 0){// if file code page does not match the system code page, we need to do a double conversion!if (nLocaleCodePage != (UINT)m_nFileCodePage){int nStringBufferChars = rString.GetLength() + 1;pszUnicodeString = new wchar_t[nStringBufferChars];// Initialise to something safememset(pszUnicodeString, 0, sizeof(wchar_t) * nStringBufferChars);// Convert to Unicode using the file code pagenChars = GetUnicodeStringFromMultiByteString(rString, pszUnicodeString, nStringBufferChars, m_nFileCodePage);// Convert back to multibyte using the system code page// (This doesn't really confer huge advantages except to avoid "mangling" of non-convertible special// characters. So, if a file in the E.European code page is displayed on a system using the // western European code page, special accented characters which the system cannot display will be// replaced by the default character (a hash or something), rather than being incorrectly mapped to// other, western European accented characters).if (nChars > 0){// Calculate how much we need for the MB buffer (it might be larger)nStringBufferChars = GetRequiredMultiByteLengthForUnicodeString(pszUnicodeString, nLocaleCodePage);pszMultiByteString = new char[nStringBufferChars];nChars = GetMultiByteStringFromUnicodeString(pszUnicodeString, pszMultiByteString, nStringBufferChars, nLocaleCodePage);rString = (CString)pszMultiByteString;}}}}else{pszUnicodeString = new wchar_t[nMAX_LINE_CHARS];// Initialise to something safememset(pszUnicodeString, 0, sizeof(wchar_t) * nMAX_LINE_CHARS);// Read as Unicode, convert to ANSI// Bug fix by Dennis Jeryd 06/07/2003: initialise bReadDatabReadData = (NULL != fgetws(pszUnicodeString, nMAX_LINE_CHARS, m_pStream));if (bReadData){// Calculate how much we need for the multibyte stringint nRequiredMBBuffer = GetRequiredMultiByteLengthForUnicodeString(pszUnicodeString, m_nFileCodePage);pszMultiByteString = new char[nRequiredMBBuffer];nChars = GetMultiByteStringFromUnicodeString(pszUnicodeString, pszMultiByteString, nRequiredMBBuffer, m_nFileCodePage);if (nChars > 0){rString = (CString)pszMultiByteString;}}}
#endif// Then remove end-of-line character if in Unicode text modeif (bReadData){// Copied from FileTxt.cpp but adapted to Unicode and then adapted for end-of-line being just '\r'. nLen = rString.GetLength();if (nLen > 1 && rString.Mid(nLen - 2) == sNEWLINE){rString.GetBufferSetLength(nLen - 2);}else{lpsz = rString.GetBuffer(0);if (nLen != 0 && (lpsz[nLen - 1] == _T('\r') || lpsz[nLen - 1] == _T('\n'))){rString.GetBufferSetLength(nLen - 1);}}}}// Ensure we always delete in case of exceptioncatch (...){if (pszUnicodeString)  delete[] pszUnicodeString;if (pszMultiByteString) delete[] pszMultiByteString;throw;}if (pszUnicodeString)      delete[] pszUnicodeString;if (pszMultiByteString)       delete[] pszMultiByteString;return bReadData;
}// --------------------------------------------------------------------------------------------
//
//  CStdioFileEx::WriteString()
//
// --------------------------------------------------------------------------------------------
// Returns:    void
// Parameters: LPCTSTR lpsz
//
// Purpose:     Writes string to file either in Unicode or multibyte, depending on whether the caller specified the
//                  CStdioFileEx::modeWriteUnicode flag. Override of base class function.
// Notes:       If writing in Unicode we need to:
//                      a) Write the Byte-order-mark at the beginning of the file
//                      b) Write all strings in byte-mode
//                  -   If we were compiled in Unicode, we need to convert Unicode to multibyte if
//                      we want to write in multibyte
//                  -   If we were compiled in multi-byte, we need to convert multibyte to Unicode if
//                      we want to write in Unicode.
// Exceptions:  None.
//
void CStdioFileEx::WriteString(LPCTSTR lpsz)
{wchar_t* pszUnicodeString = NULL;char* pszMultiByteString = NULL;try{// If writing Unicode and at the start of the file, need to write byte markif (m_nFlags & CStdioFileEx::modeWriteUnicode){// If at position 0, write byte-order mark before writing anything elseif (!m_pStream || GetPosition() == 0){wchar_t cBOM = (wchar_t)nUNICODE_BOM;CFile::Write(&cBOM, sizeof(wchar_t));}}// If compiled in Unicode...
#ifdef _UNICODE// If writing Unicode, no conversion neededif (m_nFlags & CStdioFileEx::modeWriteUnicode){// Write in byte modeCFile::Write(lpsz, lstrlen(lpsz) * sizeof(wchar_t));}// Else if we don't want to write Unicode, need to convertelse{int      nChars = lstrlen(lpsz) + 1;               // Why plus 1? Because yes
//          int     nBufferSize = nChars * sizeof(char);   // leave space for multi-byte charsint      nCharsWritten = 0;int      nBufferSize = 0;pszUnicodeString = new wchar_t[nChars];// Copy string to Unicode bufferlstrcpy(pszUnicodeString, lpsz);// Work out how much space we need for the multibyte conversionnBufferSize = GetRequiredMultiByteLengthForUnicodeString(pszUnicodeString, m_nFileCodePage);pszMultiByteString = new char[nBufferSize];// Get multibyte stringnCharsWritten = GetMultiByteStringFromUnicodeString(pszUnicodeString, pszMultiByteString, nBufferSize, m_nFileCodePage);if (nCharsWritten > 0){// Do byte-mode write using actual chars written (fix by Howard J Oh)//          CFile::Write((const void*)pszMultiByteString, lstrlen(lpsz));CFile::Write((const void*)pszMultiByteString,nCharsWritten * sizeof(char));}}// Else if *not* compiled in Unicode
#else// If writing Unicode, need to convertif (m_nFlags & CStdioFileEx::modeWriteUnicode){int       nChars = lstrlen(lpsz) + 1;    // Why plus 1? Because yesint      nBufferSize = nChars * sizeof(wchar_t);int     nCharsWritten = 0;pszUnicodeString = new wchar_t[nChars];pszMultiByteString = new char[nChars];// Copy string to multibyte bufferlstrcpy(pszMultiByteString, lpsz);nCharsWritten = GetUnicodeStringFromMultiByteString(pszMultiByteString, pszUnicodeString, nChars, m_nFileCodePage);if (nCharsWritten > 0){// Do byte-mode write using actual chars written (fix by Howard J Oh)//         CFile::Write(pszUnicodeString, lstrlen(lpsz) * sizeof(wchar_t));CFile::Write(pszUnicodeString, nCharsWritten * sizeof(wchar_t));}else{ASSERT(false);}}// Else if we don't want to write Unicode, no conversion needed, unless the code page differselse{//     // Do standard stuff//      CStdioFile::WriteString(lpsz);// Get the current code pageUINT nLocaleCodePage = GetCurrentLocaleCodePage();// If we got it OK, and if file code page does not match the system code page, we need to do a double conversion!if (nLocaleCodePage > 0 && nLocaleCodePage != (UINT)m_nFileCodePage){int  nChars = lstrlen(lpsz) + 1;    // Why plus 1? Because yespszUnicodeString = new wchar_t[nChars];// Initialise to something safememset(pszUnicodeString, 0, sizeof(wchar_t) * nChars);// Convert to Unicode using the locale code page (the code page we are using in memory)nChars = GetUnicodeStringFromMultiByteString((LPCSTR)(const char*)lpsz, pszUnicodeString, nChars, nLocaleCodePage);// Convert back to multibyte using the file code page// (Note that you can't reliably read a non-Unicode file written in code page A on a system using a code page B,// modify the file and write it back using code page A, unless you disable all this double-conversion code.// In effect, you have to choose between a mangled character display and mangled file writing).if (nChars > 0){// Calculate how much we need for the MB buffer (it might be larger)nChars = GetRequiredMultiByteLengthForUnicodeString(pszUnicodeString, m_nFileCodePage);pszMultiByteString = new char[nChars];memset(pszMultiByteString, 0, sizeof(char) * nChars);nChars = GetMultiByteStringFromUnicodeString(pszUnicodeString, pszMultiByteString, nChars, m_nFileCodePage);// Do byte-mode write. This avoids annoying "interpretation" of \n's as \r\nCFile::Write((const void*)pszMultiByteString, nChars * sizeof(char));}}else{// Do byte-mode write. This avoids annoying "interpretation" of \n's as \r\nCFile::Write((const void*)lpsz, lstrlen(lpsz) * sizeof(char));}}#endif}// Ensure we always clean upcatch (...){if (pszUnicodeString)   delete[] pszUnicodeString;if (pszMultiByteString)   delete[] pszMultiByteString;throw;}if (pszUnicodeString)    delete[] pszUnicodeString;if (pszMultiByteString)   delete[] pszMultiByteString;
}UINT CStdioFileEx::ProcessFlags(const CString& sFilePath, UINT& nOpenFlags)
{m_bIsUnicodeText = false;m_bIsUtf8Text = false;// If we have writeUnicode we must have write or writeRead as well
#ifdef _DEBUGif (nOpenFlags & CStdioFileEx::modeWriteUnicode){ASSERT(nOpenFlags & CFile::modeWrite || nOpenFlags & CFile::modeReadWrite);}
#endif// If reading in text mode and not creating... ; fixed by Dennis Jeryd 6/8/03if (nOpenFlags & CFile::typeText && !(nOpenFlags & CFile::modeCreate) && !(nOpenFlags & CFile::modeWrite)){m_bIsUnicodeText = IsFileUnicode(sFilePath);m_bIsUtf8Text = IsFileUtf8(sFilePath);// If it's Unicode, switch to binary modeif (m_bIsUnicodeText){nOpenFlags ^= CFile::typeText;nOpenFlags |= CFile::typeBinary;}}m_nFlags = nOpenFlags;return nOpenFlags;
}// --------------------------------------------------------------------------------------------
//
//  CStdioFileEx::IsFileUnicode()
//
// --------------------------------------------------------------------------------------------
// Returns:    bool
// Parameters: const CString& sFilePath
//
// Purpose:     Determines whether a file is Unicode by reading the first character and detecting
//                  whether it's the Unicode byte marker.
// Notes:       None.
// Exceptions:  None.
//
/*static*/ bool CStdioFileEx::IsFileUnicode(const CString& sFilePath)
{CFile          file;bool           bIsUnicode = false;wchar_t         cFirstChar;CFileException   exFile;// Open file in binary mode and read first characterif (file.Open(sFilePath, CFile::typeBinary | CFile::modeRead, &exFile)){// If byte is Unicode byte-order marker, let's say it's Unicodeif (file.Read(&cFirstChar, sizeof(wchar_t)) > 0 && cFirstChar == (wchar_t)nUNICODE_BOM){bIsUnicode = true;}file.Close();}else{// Handle error here if you like}return bIsUnicode;
}/*static*/ bool CStdioFileEx::IsFileUtf8(const CString& sFilePath)
{CFile          file;bool           bIsUtf8 = false;unsigned char  cFirstChar[3];CFileException    exFile;// Open file in binary mode and read first characterif (file.Open(sFilePath, CFile::typeBinary | CFile::modeRead, &exFile)){// If byte is Unicode byte-order marker, let's say it's Unicodeif (file.Read(&cFirstChar, sizeof(cFirstChar)) > 0 && cFirstChar[0] == 0xEF && cFirstChar[1] == 0xBB && cFirstChar[2]==0xBF){bIsUtf8 = true;}file.Close();}else{// Handle error here if you like}return bIsUtf8;
}unsigned long CStdioFileEx::GetCharCount()
{int                nCharSize;unsigned long nByteCount, nCharCount = 0;if (m_pStream){// Get size of chars in filenCharSize = m_bIsUnicodeText ? sizeof(wchar_t) : sizeof(char);// If Unicode, remove byte order mark from countnByteCount = GetLength();if (m_bIsUnicodeText){nByteCount = nByteCount - sizeof(wchar_t);}else if (m_bIsUtf8Text){nByteCount = nByteCount - 3;}// Calc charsnCharCount = (nByteCount / nCharSize);}return nCharCount;
}// Get the current user磗 code page
UINT CStdioFileEx::GetCurrentLocaleCodePage()
{_TCHAR szLocalCodePage[10];UINT    nLocaleCodePage = 0;int        nLocaleChars = ::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE, szLocalCodePage, 10);// If OKif (nLocaleChars > 0){nLocaleCodePage = (UINT)_ttoi(szLocalCodePage);ASSERT(nLocaleCodePage > 0);}else{ASSERT(false);}// O means either: no ANSI code page (Unicode-only locale?) or failed to get locale// In the case of Unicode-only locales, what do multibyte apps do? Answers on a postcard.return nLocaleCodePage;
}// --------------------------------------------------------------------------------------------
//
//  CStdioFileEx::GetUnicodeStringFromMultiByteString()
//
// --------------------------------------------------------------------------------------------
// Returns:    int - num. of chars written (0 means error)
// Parameters:  char *      szMultiByteString   (IN)        Multi-byte input string
//              wchar_t*    szUnicodeString     (OUT)       Unicode outputstring
//              int         nUnicodeBufferSize  (IN)        Size of Unicode output buffer in chars(IN)
//              UINT        nCodePage           (IN)        Code page used to perform conversion
//                                                              Default = -1 (Get local code page).
//
// Purpose:     Gets a Unicode string from a MultiByte string.
// Notes:       None.
// Exceptions:  None.
//
int CStdioFileEx::GetUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, OUT wchar_t* szUnicodeString, IN int nUnicodeBufferSize, IN int nCodePage)
{bool   bOK = true;int     nCharsWritten = 0;if (szUnicodeString && szMultiByteString){// If no code page specified, take default for systemif (nCodePage == -1){nCodePage = GetACP();}try{// Zero out buffer first. NB: nUnicodeBufferSize is NUMBER OF CHARS, NOT BYTES!memset((void*)szUnicodeString, '\0', sizeof(wchar_t) *nUnicodeBufferSize);// When converting to UTF8, don't set any flags (see Q175392).nCharsWritten = MultiByteToWideChar((UINT)nCodePage,(nCodePage == CP_UTF8 ? 0 : MB_PRECOMPOSED), // FlagsszMultiByteString, -1, szUnicodeString, nUnicodeBufferSize);}catch (...){TRACE(_T("Controlled exception in MultiByteToWideChar!\n"));}}// Now fix nCharsWrittenif (nCharsWritten > 0){nCharsWritten--;}//    ASSERT(nCharsWritten > 0);return nCharsWritten;
}// --------------------------------------------------------------------------------------------
//
//  CStdioFileEx::GetMultiByteStringFromUnicodeString()
//
// --------------------------------------------------------------------------------------------
// Returns:    int - number of characters written. 0 means error
// Parameters:  wchar_t *   szUnicodeString         (IN)    Unicode input string
//              char*       szMultiByteString       (OUT)   Multibyte output string
//              int         nMultiByteBufferSize    (IN)    Multibyte buffer size (chars)
//              UINT        nCodePage               (IN)    Code page used to perform conversion
//                                                              Default = -1 (Get local code page).
//
// Purpose:     Gets a MultiByte string from a Unicode string
// Notes:       Added fix by Andy Goodwin: make buffer into int.
// Exceptions:  None.
//
int CStdioFileEx::GetMultiByteStringFromUnicodeString(wchar_t* szUnicodeString, char* szMultiByteString,int nMultiByteBufferSize, int nCodePage)
{BOOL   bUsedDefChar = FALSE;int       nCharsWritten = 0;// Fix by Andy Goodwin: don't do anything if buffer is 0if (nMultiByteBufferSize > 0){if (szUnicodeString && szMultiByteString){// Zero out buffer firstmemset((void*)szMultiByteString, '\0', nMultiByteBufferSize);// If no code page specified, take default for systemif (nCodePage == -1){nCodePage = GetACP();}try{// If writing to UTF8, flags, default char and boolean flag must be NULLnCharsWritten = WideCharToMultiByte((UINT)nCodePage,(nCodePage == CP_UTF8 ? 0 : WC_COMPOSITECHECK | WC_SEPCHARS), // FlagsszUnicodeString, -1,szMultiByteString,nMultiByteBufferSize,(nCodePage == CP_UTF8 ? NULL : sDEFAULT_UNICODE_FILLER_CHAR),    // Filler char(nCodePage == CP_UTF8 ? NULL : &bUsedDefChar));                     // Did we use filler char?// If no chars were written and the buffer is not 0, error!if (nCharsWritten == 0 && nMultiByteBufferSize > 0){TRACE1("Error in WideCharToMultiByte: %d\n", ::GetLastError());}}catch (...){TRACE(_T("Controlled exception in WideCharToMultiByte!\n"));}}}// Now fix nCharsWritten if (nCharsWritten > 0){nCharsWritten--;}return nCharsWritten;
}//---------------------------------------------------------------------------------------------------
//
//  CStdioFileEx::GetRequiredMultiByteLengthForUnicodeString()
//
//---------------------------------------------------------------------------------------------------
// Returns:    int
// Parameters: wchar_t * szUnicodeString,int nCodePage=-1
//
// Purpose:     Obtains the multi-byte buffer size needed to accommodate a converted Unicode string.
//  Notes:      We can't assume that the buffer length is simply equal to the number of characters
//                  because that wouldn't accommodate multibyte characters!
//
/*static*/ int CStdioFileEx::GetRequiredMultiByteLengthForUnicodeString(wchar_t* szUnicodeString, int nCodePage /*=-1*/)
{int nCharsNeeded = 0;try{// If no code page specified, take default for systemif (nCodePage == -1){nCodePage = GetACP();}// If writing to UTF8, flags, default char and boolean flag must be NULLnCharsNeeded = WideCharToMultiByte((UINT)nCodePage,(nCodePage == CP_UTF8 ? 0 : WC_COMPOSITECHECK | WC_SEPCHARS), // FlagsszUnicodeString, -1,NULL,0,   // Calculate required buffer, please! (nCodePage == CP_UTF8 ? NULL : sDEFAULT_UNICODE_FILLER_CHAR),   // Filler charNULL);}catch (...){TRACE(_T("Controlled exception in WideCharToMultiByte!\n"));}return nCharsNeeded;
}

[*注]:

1、源码摘自互联网,由于具体出处未知,所以未引用源链接地址,如若侵犯版权,请联系博主!

2、源码在原文基础上,添加了对UTF-8 BOM文件类型的支持。

CStdioFile扩展(支持Ansi、Unicode、Utf-8等文本格式)相关推荐

  1. 字符编码简介 ANSI Unicode Unicode big endian UTF-8

    1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和 1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte) ...

  2. ANSI环境下支持多语言输入的单行文本编辑器 V0.01

    File:      SMLInput Name:      ANSI环境下支持多语言输入的单行文本编辑器 Author:    zyl910 Blog:      http://blog.csdn. ...

  3. EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案

    众所周知,RTMP标准协议实际是不支持HEVC(H.265)编码格式的,同样,现行的H5标准里面,也没有对H.265的描述,所以,在很大程度上,H5网页浏览器是无法接入HEVC(H.265)的,但是, ...

  4. php7 memcached sasl,Mac安装memcached扩展支持sasl

    Mac安装memcached扩展支持sasl Memcached在服务以及扩展中,默认都是不支持用户名和密码,但是如果需要可以通过打开sasl来提供用户名和密码服务.所以在memcached的扩展与服 ...

  5. 微软将结束对Windows Vista系统的扩展支持

    (原标题:微软将结束对Windows Vista系统的扩展支持) 4月11日,微软将结束对于Windows Vista系统的扩展支持,彻底停止发放安全更新和修复.这款备受争议.被很多人视为微软最失败的 ...

  6. MFC - CStdioFile 读取txt文件UNICODE 中文异常

    MFC - CStdioFile 读取txt文件UNICODE 中文异常 参考文章: (1)MFC - CStdioFile 读取txt文件UNICODE 中文异常 (2)https://www.cn ...

  7. 字符串处理 - ANSI - Unicode - UTF8 转换

    字符串处理 - ANSI - Unicode - UTF8 转换 [C语言]字符串处理 - ANSI - Unicode - UTF8 转换 2008-11-4: 使用MultiByteToWideC ...

  8. php开启sockets模块,linux下开启php的sockets扩展支持实例

    下个相同版本的php源码,进行编译安装,再按照上面步骤搞,生成的so.copy到rpm装的那个,修改php.ini进行扩展就行了, 或者到网上找相同版本,相同系统 的编译好的so文件. 在linux下 ...

  9. [转载]ExtJs4 笔记(2) ExtJs对js基本语法扩展支持

    作者:李盼(Lipan) 出处:[Lipan] (http://www.cnblogs.com/lipan/) 本篇主要介绍一下ExtJs对JS基本语法的扩展支持,包括动态加载.类的封装等. 一.动态 ...

最新文章

  1. Linux下快速分区格式化大于2T大容量存储
  2. MongoDB数据库索引基础知识与实战技巧
  3. MySQL高级-索引是什么
  4. MariaDB的简单使用
  5. html 文本横向,纯css 如何实现文本超出部分横向滚动
  6. JavaWeb:Ajax和JSON
  7. Android Studio Gradle下载慢解决方法
  8. 动态炫酷的404页面源码
  9. iis7 运行多个https,433端口监听多个htps 站点
  10. 站群服务器找11火星软件
  11. java 发 腾讯企业邮_JAVA使用腾讯企业邮箱发送邮件时报错Could not connect to SMTP host...
  12. 软件测试中冒烟测试范例,浅谈冒烟测试及用例
  13. 谷歌google bard vs chatgpt给我的最大感受,速度真快,注册简单,多种答案提供。。。
  14. 跨专业考清华大学的计算机,18级学长跨考清华大学计算机考研经验分享
  15. Springboot学生选课系统的设计与实现毕业设计源码
  16. Python+Flask
  17. 计算机中sqrt函数是什么意思,(excle sqrt)excel中的SQRT是什么意思?
  18. 中国互联网量级分化严重:小米将360踢出第二阵营
  19. 软件测试课设总结报告,软件测试课设感言
  20. 号称硬核厨师的美食作家,让千万Z世代爱上了做菜!

热门文章

  1. 【ReactJS】一、手把手搭建ReactJS开发环境(Sublime)
  2. 前端开发中IE6的问题的汇总
  3. CNVD-2021-49104——泛微E-Office文件上传漏洞
  4. 新闻网站模板html4,织梦新闻文章门户网站模板,Html5响应式高权重网站织梦模板...
  5. S32K144 bootloader 方案设计
  6. 充电口 米兔积木机器人_米兔积木 篇三:我与小米积木有个约会之米兔机器人平衡车版...
  7. Excel多人同时编辑的几种方案与比较
  8. 世界上五十大开心事(点评)
  9. python读取txt文件特定内容,并绘制折线图
  10. MBA联考-20101130