Several string operation functions are useful in MFC, but some cannot be found in MSDN, because MSDN has not published them. Let's take a look at their usage, declarations, and definitions.
// Function: format a string
// Parameter: rString-output parameter. The formatted string is saved in this string.
// NIDS-resource ID of the string that will be replaced
// Lpsz1-point to the string that will replace the "% 1" character in the Format String
// Lpsz2-point to the string that will replace the "% 2" character in the Format String
Void AFXAPI AfxFormatString1 (CString & rString, UINT nIDS, LPCTSTR lpsz1 );
Void AFXAPI AfxFormatString2 (CString & rString, UINT nIDS, LPCTSTR lpsz1, LPCTSTR lpsz2 );
// Implementation string helpers
Void AFXAPI AfxFormatStrings (CString & rString, UINT nIDS, LPCTSTR const * rglpsz, int nString );
Void AFXAPI AfxFormatStrings (CString & rString, LPCTSTR lpszFormat, LPCTSTR const * rglpsz, int nString );
// Function: Obtain the sub-string
// Parameter: rString-output parameter. Save the sub-string.
// LpszFullString-source string
// ISubString-Sub-string index, counted from 0
// ChSep-delimiter between substrings. The default value is
Bool afxapi AfxExtractSubString (CString & rString, LPCTSTR lpszFullString, int iSubString, TCHAR chSep = );
//////////////////////////////////////// /////////
//////////////////////////////////////// ////////
///
// Strings in format "... % 1... % 1... % 2..." etc. void AFXAPI AfxFormatStrings (CString & rString, UINT nIDS,
LPCTSTR const * rglpsz, int nString)
{
TCHAR szFormat [256];
If (! AfxLoadString (nIDS, szFormat )! = 0)
{
TRACE1 ("Error: failed to load AfxFormatString 0x % 04x.", nIDS );
ASSERT (FALSE );
Return;
}
AfxFormatStrings (rString, szFormat, rglpsz, nString );
}
Void AFXAPI AfxFormatStrings (CString & rString, LPCTSTR lpszFormat,
LPCTSTR const * rglpsz, int nString)
{
// Length of the calculated string
Int nTotalLen = 0;
LPCTSTR pchSrc = lpszFormat;
While (* pchSrc! =)
{
If (pchSrc [0] ==% &&
(PchSrc [1]> = 0 & pchSrc [1] <= 9) |
(PchSrc [1]> = A & pchSrc [1] <= Z )))
{
// % A comes after % 9 -- well need it someday
Int I;
If (pchSrc [1]> 9)
I = 9 + (pchSrc [1]-);
Else
I = pchSrc [1]-1;
PchSrc + = 2;
If (I> = nString)
++ NTotalLen;
Else if (rglpsz [I]! = NULL)
NTotalLen + = lstrlen (rglpsz [I]);
}
Else
{
If (_ istlead (* pchSrc ))
++ NTotalLen, ++ pchSrc;
++ PchSrc;
++ NTotalLen;
}
}
PchSrc = lpszFormat;
LPTSTR pchDest = rString. GetBuffer (nTotalLen );
While (* pchSrc! =)
{
If (pchSrc [0] ==% &&
(PchSrc [1]> = 0 & pchSrc [1] <= 9) |
(PchSrc [1]> = A & pchSrc [1] <= Z )))
{
// % A comes after % 9 -- well need it someday
Int I;
If (pchSrc [1]> 9)
I = 9 + (pchSrc [1]-);
Else
I = pchSrc [1]-1;
PchSrc + = 2;
If (I> = nString)
{
TRACE1 ("Error: illegal string index requested % d.", I );
* PchDest ++ = ?;
}
Else if (rglpsz [I]! = NULL)
{
Lstrcpy (pchDest, rglpsz [I]);
PchDest + = lstrlen (pchDest );
}
}
Else
{
If (_ istlead (* pchSr
C) // * Whether pchSrc is the first byte of Multi-byte characters
* PchDest ++ = * pchSrc ++; // copy the first byte
* PchDest ++ = * pchSrc ++;
}
}
RString. ReleaseBuffer (int) (LPCTSTR) pchDest-(LPCTSTR) rString ));
// ReleaseBuffer will assert if we went too far
}
Void AFXAPI AfxFormatString1 (CString & rString, UINT nIDS, LPCTSTR lpsz1)
{
AfxFormatStrings (rString, nIDS, & lpsz1, 1 );
}
Void AFXAPI AfxFormatString2 (CString & rString, UINT nIDS, LPCTSTR lpsz1,
LPCTSTR lpsz2)
{
LPCTSTR rglpsz [2];
Rglpsz [0] = lpsz1;
Rglpsz [1] = lpsz2;
AfxFormatStrings (rString, nIDS, rglpsz, 2 );
}
Bool afxapi AfxExtractSubString (CString & rString, LPCTSTR lpszFullString,
Int iSubString, TCHAR chSep)
{
If (lpszFullString = NULL)
Return FALSE;
While (iSubString --)
{
LpszFullString = _ tcschr (lpszFullString, chSep );
If (lpszFullString = NULL)
{
RString. Empty (); // return empty string as well
Return FALSE;
}
LpszFullString ++; // point past the separator
}
LPCTSTR lpchEnd = _ tcschr (lpszFullString, chSep );
Int nLen = (lpchEnd = NULL )? Lstrlen (lpszFullString): (int) (lpchEnd-lpszFullString );
ASSERT (nLen> = 0 );
Memcpy (rString. GetBufferSetLength (nLen), lpszFullString, nLen * sizeof (TCHAR ));
Return TRUE;
}
//////////////////////////////////////// /////////
//////////////////////////////////////// ////////
///