②使用CString对象的"<<"与">>"符读写字符串
CString定义了输入输出符,可以象基本类型的
数据一样使用CArchive 的操作符定义
friend CArchive& AFXAPI operator<<(CArchive& ar, const CString& string);
friend CArchive& AFXAPI operator>>(CArchive& ar, CString& string);
// CString serialization code
// String format:
// UNICODE strings are always prefixed by 0xff, 0xfffe
// if < 0xff chars: len:BYTE, TCHAR chars
// if >= 0xff characters: 0xff, len:WORD, TCHAR chars
// if >= 0xfffe characters: 0xff, 0xffff, len:DWORD, TCHARs
CArchive& AFXAPI operator<<(CArchive& ar, const CString& string)
{
// special signature to recognize unicode strings
#ifdef _UNICODE
ar << (BYTE)0xff;
ar << (WORD)0xfffe;
#endif
if (string.GetData()-> nDataLength < 255)
{
ar << (BYTE)string.GetData()-> nDataLength;
}
else if (string.GetData()-> nDataLength < 0xfffe)
{
ar << (BYTE)0xff;
ar << (WORD)string.GetData()-> nDataLength;
}
else
{
ar << (BYTE)0xff;
ar << (WORD)0xffff;
ar << (DWORD)string.GetData()-> nDataLength;
}
ar.Write(string.m_pchData, string.GetData()-> nDataLength*sizeof(TCHAR));
return ar;
}
// return string length or -1 if UNICODE string is found in the archive
AFX_STATIC UINT AFXAPI _AfxReadStringLength(CArchive& ar)
{
DWORD nNewLen;
// attempt BYTE length first
BYTE bLen;
ar >> bLen;
if (bLen < 0xff)
return bLen;
// attempt WORD length
WORD wLen;
ar >> wLen;
if (wLen == 0xfffe)
{
// UNICODE string prefix (length will follow)
return (UINT)-1;
}
else if (wLen == 0xffff)
{
// read DWORD of length
ar >> nNewLen;
return (UINT)nNewLen;
}
else
return wLen;
}
CArchive& AFXAPI operator>>(CArchive& ar, CString& string)
{
#ifdef _UNICODE
int nConvert = 1; // if we get ANSI, convert
#else
int nConvert = 0; // if we get UNICODE, convert
#endif
UINT nNewLen = _AfxReadStringLength(ar);
if (nNewLen == (UINT)-1)
{
nConvert = 1 - nConvert;
nNewLen = _AfxReadStringLength(ar);
ASSERT(nNewLen != -1);
}
// set length of string to new length
UINT nByteLen = nNewLen;
#ifdef _UNICODE
string.GetBufferSetLength((int)nNewLen);
nByteLen += nByteLen * (1 - nConvert); // bytes to read
#else
nByteLen += nByteLen * nConvert; // bytes to read
if (nNewLen == 0)
string.GetBufferSetLength(0);
else
string.GetBufferSetLength((int)nByteLen+nConvert);
#endif
// read in the characters
if (nNewLen != 0)
{
ASSERT(nByteLen != 0);
// read new data
if (ar.Read(string.m_pchData, nByteLen) != nByteLen)
AfxThrowArchiveException(CArchiveException::endOfFile);
// convert the data if as necessary
if (nConvert != 0)
{
#ifdef _UNICODE
CStringData* pOldData = string.GetData();
LPSTR lpsz = (LPSTR)string.m_pchData;
#else
CStringData* pOldData = string.GetData();
LPWSTR lpsz = (LPWSTR)string.m_pchData;
#endif
lpsz[nNewLen] = ''\0''; // must be NUL terminated
string.Init(); // don''t delete the old data
string = lpsz; // convert with operator=(LPWCSTR)
CString::FreeData(pOldData);
}
}
return ar;
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1658815