How to Go Backward in a DBCS String

The usual method for retrieving the previous character in a DBCS string is to go back to the beginning of the string and progress through it until the previous character is found. An alternative method that is more efficient in the average case is to go backward, testing each byte until a "true non–lead-byte" character is found, and then calculate the previous character from that point. In the worst-case scenario (stepping all the way back to the beginning of your buffer), this method is comparable to the traditional one.

char* MyCharPrev (char *psz, char *pch)
{
// pch must point either to a single-byte character
// or to the beginning of a double-byte character.
// It cannot point to the middle of a double-byte character.
char *pchTemp;

// If we are at the beginning, or the previous byte
// is at the beginning, simply return psz.
if (psz <= pch - 1)
return psz;

pchTemp = pch - 1; // point to previous byte

// If *(pch-1) is a Lead Byte-, it must actually
// be functioning as a trail byte so return pch-2.
if (IsDBCSLeadByte(*pchTemp))
return (pch - 2);
// Otherwise, step back until a non-lead-byte is found.
while (psz <= --pchTemp && IsDBCSLeadByte(*pchTemp))
;
// Now pchTemp+1 must point to the beginning of a character,
// so figure out whether we went back an even or an odd
// number of bytes and go back 1 or 2 bytes, respectively.
return (pch - 1 - ((pch - pchTemp) & 1));
{