Introduction
Here's a pretty brainless extension to MFC's CString
. The only reason I'm posting this is that I looked at the String archives on CP and didn't find anything that does:
1. Automatic conversion to string format of integers and doubles
2. Improves MFC's Left and Right substring functions
3. Can automatically comma delimit a number for me
This may be a simple class, but it is a real workhorse for me--I use it in almost every project! That said, it really is tailored to the kind of work that I do--a lot of database interfacing and number formatting. I hope that it spurs your imagination though. If you add any other cool features, just let me know.
Numeric Conversion
OK, there's sprintf, there's I/O streams, there's itoa and ltoa, and there's probably other things too. Unfortunately, CString
doesn't provide the ability to automatically convert from a number into a string. For floats/doubles, I can sort of understand--it would be hard to make assumptions about how to represent the number. But that's easily addressed:
CStringEx(int i, const char* format="%d", DWORD options=NO_OPTIONS);
CStringEx(double d, const char* format="%02lf", DWORD options=NO_OPTIONS);
by providing a default format which can be overridden.
Char Conversion
Ever need to convert a char to a string? Another feature that CString
is missing.
CStringEx(const char c) {char s[2]={'\0', '\0'}; s[0]=c; CString::operator=(s);}
Substring Functions
I end up writing a lot of functions like:
CString foo=bar.Left(bar.Find('Q'));
because I am parsing strings, looking for token characters. CString
is based on Basic concepts of Mid$, Left$, Right$, etc.
How about these instead:
CStringEx LeftEx(char c, int n=1) const;
CStringEx RightEx(char c, int n=1) const;
CStringEx Rightmost(char c) const;
CStringEx LeftOfRightmost(char c) const;
I didn't like the functionality of the CString::Left()
function--if the character isn't found, it returns an empty string. I prefer to think of these functions as scanning functions. Therefore, Left() should return everything that the scanner encountered exclusive of the search character. If no character is encountered, the entire string is returned.
Lastly, CString
provides TrimLeft()
and TrimRight()
functions, but no function that does both. Therefore:
void Trim(void) {TrimLeft(); TrimRight();}
Comma Delimiting Numbers
This implementation probably doesn't handle everything, but here it is.
CStringEx CStringEx::CommaDelimitNumber(const char* s)
{
CStringEx s2=s;
CStringEx q=s2.Left('.');
char posNegChar=q[0];
bool posNeg=!isdigit(posNegChar);
if (posNeg)
{
q=q.SubStr(1, strlen(q)-1);
}
CStringEx dp=s2.Right('.');
CStringEx q2;
while (strlen(q) > 3)
{
CStringEx s3=CStringEx(",")
+q.SubStr(strlen(q)-3, 3);
q2=s3+q2;
q=q.SubStr(0, strlen(q)-3);
}
q2=q+q2;
if (dp != "")
{
q2=q2+"."+dp;
}
if (posNeg)
{
q2=CStringEx(posNegChar)+q2;
}
return q2;
}
Some Test
CStringEx a('A');
CStringEx abc("ABC");
CStringEx one(1);
CStringEx onePointFive(1.5);
CStringEx commaDelimited1(1234.5,
"%.02lf", CStringEx::COMMA_DELIMIT);
CStringEx commaDelimited2(-987654321.1234,
"%+.04lf", CStringEx::COMMA_DELIMIT);
CStringEx test=" \t ABCDEFG
1234567890 ABCDEFG \t ";
test.Trim();
CStringEx r1=test.RightEx('B');
CStringEx r2=test.RightEx('B', 2);
CStringEx r3=test.RightEx('Z');
CStringEx r4=test.Rightmost('C');
CStringEx l1=test.LeftEx('B');
CStringEx l2=test.LeftEx('B', 2);
CStringEx l3=test.LeftEx('Z');
CStringEx l4=test.LeftOfRightmost('B');
Conclusion
Pretty simple, huh? But sometimes the simplest things in life are the best. And besides, MFC has done all the hard work with the CString
class!
Revision History
13 Jun 2002 - Initial Revision
13 Jun 2002 - Fixed Formatting and Code Snippets