Simple CString Extension






3.55/5 (7 votes)
Jun 6, 2002
2 min read

121184

858
Simple extension for better substring functionality and numeric formatting
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:
// everything to the left of the nth occurance of <c> CStringEx LeftEx(char c, int n=1) const; // everything to the right of the nth occurance of <c> CStringEx RightEx(char c, int n=1) const; // everything to the right of the last occurance of <c> CStringEx Rightmost(char c) const; // everything to the left of the last occurance of <c> 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();} // trims both left and right sides
Comma Delimiting Numbers
This implementation probably doesn't handle everything, but here it is.
CStringEx CStringEx::CommaDelimitNumber(const char* s) { CStringEx s2=s;// convert to CStringEx // get everything to the left of the first decimal point CStringEx q=s2.Left('.'); // get the first char char posNegChar=q[0]; // if not digit, then assume + or - bool posNeg=!isdigit(posNegChar); // if so, strip off if (posNeg) { q=q.SubStr(1, strlen(q)-1); } // remember everything to the right of the decimal point CStringEx dp=s2.Right('.'); // working string CStringEx q2; // if more than three digits... while (strlen(q) > 3) { // insert a comma before the last three digits (100's) CStringEx s3=CStringEx(",") +q.SubStr(strlen(q)-3, 3); // append this to our working string q2=s3+q2; // get everything except the last three digits q=q.SubStr(0, strlen(q)-3); } // prepend remainder to the working string q2=q+q2; // if we have decimal point... if (dp != "") { // append it and the digits q2=q2+"."+dp; } // if we stripped off a +/- ... if (posNeg) { // add it back in q2=CStringEx(posNegChar)+q2; } // this is our final comma delimited string return q2; }
Some Test
// A CStringEx a('A'); // ABC CStringEx abc("ABC"); // 1 CStringEx one(1); // 1.50000 CStringEx onePointFive(1.5); // 1,234.50 CStringEx commaDelimited1(1234.5, "%.02lf", CStringEx::COMMA_DELIMIT); // -987,654,321.1234 CStringEx commaDelimited2(-987654321.1234, "%+.04lf", CStringEx::COMMA_DELIMIT); CStringEx test=" \t ABCDEFG 1234567890 ABCDEFG \t "; // ABCDEFG 1234567890 ABCDEFG test.Trim(); // CDEFG 1234567890 ABCDEFG CStringEx r1=test.RightEx('B'); // CDEFG CStringEx r2=test.RightEx('B', 2); // empty string CStringEx r3=test.RightEx('Z'); // DEFG CStringEx r4=test.Rightmost('C'); // A CStringEx l1=test.LeftEx('B'); // ABCDEFG 1234567890 A CStringEx l2=test.LeftEx('B', 2); // ABCDEFG 1234567890 ABCDEFG CStringEx l3=test.LeftEx('Z'); // ABCDEFG 1234567890 A 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