CodeGuru
Earthweb Search
Forums Wireless Jars Gamelan Developer.com
CodeGuru Navigation
Member Sign In
User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

Become a Marketplace Partner

jobs.internet.com

internet.commerce
Partners & Affiliates
















RSS Feeds

RSSAll

RSSVC++/C++

RSS.NET/C#

RSSVB

See more EarthWeb Network feeds

Home >> Visual C++ / C++ >> COM-based Technologies >> ATL & WTL Programming >> ATL


CBStr: a BSTR wrapper-class with string manipulation members
Rating: none

Gary Olliffe (view profile)
October 20, 1998

The MFC CString class, has some really nice string manipulation routines. However, if you are trying to avoid the MFC for size/deployment issues, and having to do string manipulation of BSTRs I'm sure that you will be finding the _bstr_t class frustratingly basic.

After doing a great deal of frustrated hair-pulling I finally got around to implementing this class, CBstr. It is a C++ class derived from the MS VC++ _bstr_t COM support class with the added benefit of a barrow-load of string manipulation methods. The original idea came after seeing Alex Stockton's NoMFC::CString class at www.WorldofATL.com. This class was used as the template for the public interface.
(continued)



The class uses the same public "interface" as the NoMFC::CString Class with a couple of minor differences and as a result has all the functionality of the "real" (MFC) CString class with a few extra's. And because it is derived from _bstr_t

Because the class is derived from _bstr_t it is very easy to use instead of that class, especially where string manipulation of any kind is required. If you are not planning on using the string-manipulation functionality I would suggest sticking with the _bstr_t class for reduced class size.

To use the class simply #include the CBstrImpl.h header file supplied in the Zip, and have this and CBStr.h in your include path.

A demo program (and my test rig) follows and is included in the zip file. This exercises all of the functionality of of the class, but for more information I would suggest looking at the documentation of the MFC CString class - it doesn't seem woth copying it out ;-)

This code has been tested with Visual C++ 5.0 Service Pack 3, it has not been tested with Visual C++ 6.0

Example code



// Main.cpp
//
// Test harness to execise the CBstr class
// derived from _bstr_t and based on the 
// NoMFC::CString class from www.worldofatl.com
//
// If anyone can figure out why the ostream::operator<< refuses to
// use the implicit cast to const char* or char* then please email me 
// at gary.olliffe@parallax.co.uk
// 
//
#include "CBstrImpl.h"
#include <iostream>

using std::cout;

const TCHAR* Test(const TCHAR* psz);

// This test only works in ANSI (not UNICODE) builds
// due to lack of _T() and stream insertion operator

int main()
{
	// Create a proper BSTR 
	BSTR bstr = ::SysAllocString(L"Hello World");

	// Create two objects of out new class
	CBstr newstr(bstr, true);    //Take a copy of bstr
	CBstr newstr2(bstr, false);  //attach to bstr

	// test the MakeUpper method
	newstr2.MakeUpper();

	// Extract the BSTR (this gives a reference 
	// to the encapulated BSTR, not a copy)
	BSTR ptrcopy = newstr2;

	// Take a copy of the encapsulated BSTR 
	BSTR deepcopy = newstr2.copy();

	// Test cast to char *
	char * ansistr = newstr2;

	// Test cast to const char *
	const char* ansicstr = newstr2;

	// output results 	
	cout << ansistr << "\n" << ansicstr;
	cout << newstr2;

	// Create another string for testing
	CBstr str("twenty");

	// Call a method that takes a const char* parameter
	Test(str);

	// create another CBstr from the first
	CBstr str2(str);

	// output results
	cout << (const char*)str << "\n";
	cout << (const char*)str2 << "\n";

	// test the format method  
	str.Format("sder %d %s", 1, "ss");
	cout << (const char*)str << "\n";

	// test the length() method
	CBstr s("abcdef");
	cout << s.length() << "\n"; // == 6 

	// test the isempty() method
	CBstr s2;
	cout << s2.IsEmpty() << "\n"; // == true

	// test the Empty method
	CBstr s3("abc");
	s3.Empty();
	cout << s3.length() << "\n"; // == 0

	// Test GetAt() method
	CBstr s4("abcdef");
	cout << s4.GetAt(2) << "\n"; //  == 'c'

	// Test the operator[]
	CBstr s5("abc");
	cout << s5[1] << "\n"; // == 'b'
	s5.SetAt(1, 'X');
	cout << s5[1] << "\n"; // == 'X'


	// test assignment operators
	CBstr s6, s7;        // Empty CBstr objects
	s6 = "cat";            // s6 == "cat"
	cout << (const char*)s6 << "\n";
	s7 = s6;               // s6 and s7 each == "cat"
	cout << (const char*)s7 << "\n";

	// test operator+()
	s6 = "the " + s6;      // Or expressions
	cout << (const char*)s6 << "\n";

	// example for CBstr::operator +
	CBstr s8("abc");
	CBstr s9("def");
	cout << (const char*)(s8 + s9 ) << "\n"; // == "abcdef"
	CBstr s10;
	s10 = CBstr("abc") + "def" ; // == "abcdef"
	cout << (const char*)s10 << "\n";

	// example for CBstr::operator +=
	CBstr s11("abc");
	cout << (const char*)( s11 += "def") << "\n"; // == "abcdef"

	// example for CBstr Comparison Operators
	CBstr s12("abc");
	CBstr s13("abd");
	if (s12 < s13)
		cout << "s12 < 13" << "\n"; // == true Operator is overloaded for both.
	if ("ABC" < s12)
		cout << "ABC < s12" << "\n"; // == true CBstr and char*
	if (s13 > "abe")
		cout << "s13 > abe" << "\n"; // == false 
	if (s13 == "abd")
		cout << "s13 == abd" << "\n"; // == true

	// example for CBstr::Compare
	CBstr s14( "abc" );
	CBstr s15( "abd" );
	cout << s14.Compare(s15) << "\n"; // == -1 // Compare with another CBstr.
	cout << s14.Compare("abe") << "\n"; // == -1 // Compare with LPTSTR string.

	// example for CBstr::CompareNoCase
	CBstr s16( "abc" );
	CBstr s17( "ABD" );
	cout << s16.CompareNoCase( s17 ) << "\n"; // == -1 // Compare with a CBstr.
	cout << s16.Compare( "ABE" )  << "\n"; // == 1 // Compare with LPTSTR string.

	// example for CBstr::Mid
	CBstr s18("abcdef");
	cout << (const char*)s18.Mid(2, 3) << "\n"; //  == _T("cde")

	// example for CBstr::Left
	CBstr s19( _T("abcdef") );
	cout << (const char*)s19.Left(2) << "\n"; //  == _T("ab")

	// example for CBstr::Right
	CBstr s20( _T("abcdef") );
	cout << (const char*)s20.Right(2) << "\n"; //  == _T("ef")

	// example for CBstr::SpanIncluding
	CBstr s21( "cabbage" );
	CBstr s22 = s21.SpanIncluding( "abc" );
	cout << (const char*)s22 << "\n"; //  == "cabba"
	s22 = s21.SpanIncluding( "xyz" );
	cout << s22.IsEmpty( ) << "\n"; // == true

	// example for CBstr::MakeUpper
	CBstr s23( "abc" );
	s23.MakeUpper();
	cout << (const char*)s23 << "\n"; //  == "ABC"

	// example for CBstr::MakeLower
	CBstr s24( "ABC" );
	s24.MakeLower();
	cout << (const char*)s24 << "\n"; //  == "abc"

	// example for CBstr::MakeReverse
	CBstr s25( "abc" );
	s25.MakeReverse();
	cout << (const char*)s25 << "\n"; //  == "cba"

	// example for CBstr::Find
	CBstr s26( "abcdef" );
	cout << s26.Find( 'c' ) << "\n"; //  == 2
	cout << s26.Find( "de" ) << "\n"; //  == 3

	// example for CBstr::ReverseFind
	CBstr s27( "abcabc" );
	cout << s27.ReverseFind( 'b' ) << "\n"; //  == 4

	// example for CBstr::FindOneOf
	CBstr s28( "abcdef" );
	cout << s28.FindOneOf( "xd" ) << "\n"; //  == 3 // 'd' is first match

	return 0;
}


Download demo project - 7 KB

Tools:
Add www.codeguru.com to your favorites
Add www.codeguru.com to your browser search box
IE 7 | Firefox 2.0 | Firefox 1.5.x
Receive news via our XML/RSS feed







RATE THIS ARTICLE:   Excellent  Very Good  Average  Below Average  Poor  

(You must be signed in to rank an article. Not a member? Click here to register)

Latest Comments:
Amendment to the Format() method - Ben Staveley-Taylor (03/05/2004)
memory leak in replace - Legacy CodeGuru (04/09/2002)
There are std::wstrings! - Legacy CodeGuru (02/21/2002)
A better way - Legacy CodeGuru (12/06/2001)
Can't compile it with eMbedded Visual C++ - Legacy CodeGuru (04/25/2001)

View All Comments
Add a Comment:
Title:
Comment:
Pre-Formatted: Check this if you want the text to display with the formatting as typed (good for source code)



(You must be signed in to comment on an article. Not a member? Click here to register)


JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
Intel PDF: Virtualization Delivers Data Center Efficiency
Intel eBook: Managing the Evolving Data Center
Microsoft Article: BitLocker Brings Encryption to Windows Server 2008
Symantec eBook: The Guide to E-Mail Archiving and Management
Microsoft Article: RODCs Transform Branch Office Security
Go Parallel Article: James Reinders on the Intel Parallel Studio Beta Program
Avaya Article: Advancing the State of the Art in Customer Service
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Avaya Article: Avaya AE Services Provide Rapid Telephony Integration with Facebook
Go Parallel Article: Getting Started with TBB on Windows
HP eBook: Storage Networking , Part 1
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
Intel Seminar: Efficiencies in Hardware/Software Virtualization
HP Webcast: Disaster Recovery Planning
Go Parallel Video: Performance and Threading Tools for Game Developers
HP Video: StorageWorks EVA4400 and Oracle
HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
IBM TCO eKIT: Your IT Budget is Under Attack, Get in Control
IBM Energy Efficiency eKIT: Learn How to Reduce Costs
30-Day Trial: SPAMfighter Exchange Module
Red Gate Download: SQL Toolbelt and free High-Performance SQL Code eBook
Iron Speed Designer Application Generator
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
Microsoft Article: Silverlight Streaming--Free Video Hosting for All
Featured Algorithm: Intel Threading Building Blocks - parallel_reduce
HP Demo: StorageWorks EVA4400
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES