Click here to Skip to main content
15,867,704 members
Articles / Desktop Programming / MFC
Article

Simple CString Extension

Rate me:
Please Sign up or sign in to vote.
3.55/5 (7 votes)
12 Jun 20022 min read 119.9K   856   22   15
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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect Interacx
United States United States
Blog: https://marcclifton.wordpress.com/
Home Page: http://www.marcclifton.com
Research: http://www.higherorderprogramming.com/
GitHub: https://github.com/cliftonm

All my life I have been passionate about architecture / software design, as this is the cornerstone to a maintainable and extensible application. As such, I have enjoyed exploring some crazy ideas and discovering that they are not so crazy after all. I also love writing about my ideas and seeing the community response. As a consultant, I've enjoyed working in a wide range of industries such as aerospace, boatyard management, remote sensing, emergency services / data management, and casino operations. I've done a variety of pro-bono work non-profit organizations related to nature conservancy, drug recovery and women's health.

Comments and Discussions

 
GeneralTrim Pin
Max Santos26-Mar-06 5:48
Max Santos26-Mar-06 5:48 
GeneralInserting commas Pin
David Crow11-Nov-05 9:16
David Crow11-Nov-05 9:16 
GeneralNumeric conversion - variants Pin
Rome Singh6-Oct-03 23:11
Rome Singh6-Oct-03 23:11 
General'char conversion' doesn't work Pin
WREY18-Jun-02 3:04
WREY18-Jun-02 3:04 
GeneralRe: 'char conversion' doesn't work Pin
jhwurmbach19-Jul-02 4:28
jhwurmbach19-Jul-02 4:28 
GeneralRe: 'char conversion' doesn't work Pin
WREY19-Jul-02 8:28
WREY19-Jul-02 8:28 
GeneralRe: 'char conversion' doesn't work Pin
Colin Leitner29-Jul-02 7:08
Colin Leitner29-Jul-02 7:08 
GeneralRe: 'char conversion' doesn't work Pin
peterchen2-Dec-06 21:15
peterchen2-Dec-06 21:15 
GeneralMinor quibbles Pin
Gary Wheeler6-Jun-02 10:40
Gary Wheeler6-Jun-02 10:40 
GeneralRe: Minor quibbles Pin
Michael Dunn14-Jun-02 14:50
sitebuilderMichael Dunn14-Jun-02 14:50 
GeneralRe: Minor quibbles Pin
Colin Leitner29-Jul-02 7:15
Colin Leitner29-Jul-02 7:15 
GeneralRe: Minor quibbles Pin
Michael Dunn29-Jul-02 18:26
sitebuilderMichael Dunn29-Jul-02 18:26 
GeneralRe: Minor quibbles Pin
Colin Leitner30-Jul-02 1:22
Colin Leitner30-Jul-02 1:22 
GeneralRe: Minor quibbles Pin
Michael Dunn30-Jul-02 15:51
sitebuilderMichael Dunn30-Jul-02 15:51 
GeneralRe: Minor quibbles Pin
David Crow11-Nov-05 9:11
David Crow11-Nov-05 9:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.