Click here to Skip to main content
Licence 
First Posted 5 Jun 2002
Views 85,829
Bookmarked 21 times

Simple CString Extension

By | 12 Jun 2002 | Article
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

About the Author

Marc Clifton



United States United States

Member

Marc is the creator of two open source projets, MyXaml, a declarative (XML) instantiation engine and the Advanced Unit Testing framework, and Interacx, a commercial n-tier RAD application suite.  Visit his website, www.marcclifton.com, where you will find many of his articles and his blog.
 
Marc lives in Philmont, NY with his son Ian.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralTrim PinmemberMax Santos5:48 26 Mar '06  
GeneralInserting commas PinmemberDavidCrow9:16 11 Nov '05  
GeneralNumeric conversion - variants PinmemberRome Singh23:11 6 Oct '03  
General'char conversion' doesn't work PinmemberWREY3:04 18 Jun '02  
GeneralRe: 'char conversion' doesn't work Pinsussjhwurmbach4:28 19 Jul '02  
GeneralRe: 'char conversion' doesn't work PinmemberWREY8:28 19 Jul '02  
GeneralRe: 'char conversion' doesn't work PinmemberColin Leitner7:08 29 Jul '02  
GeneralRe: 'char conversion' doesn't work Pinmemberpeterchen21:15 2 Dec '06  
GeneralMinor quibbles PinmemberGary Wheeler10:40 6 Jun '02  
GeneralRe: Minor quibbles PinsitebuilderMichael Dunn14:50 14 Jun '02  
GeneralRe: Minor quibbles PinmemberColin Leitner7:15 29 Jul '02  
GeneralRe: Minor quibbles PinsitebuilderMichael Dunn18:26 29 Jul '02  
GeneralRe: Minor quibbles PinmemberColin Leitner1:22 30 Jul '02  
GeneralRe: Minor quibbles PinsitebuilderMichael Dunn15:51 30 Jul '02  
GeneralRe: Minor quibbles PinmemberDavidCrow9:11 11 Nov '05  

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

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 13 Jun 2002
Article Copyright 2002 by Marc Clifton
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid