Archive

Posts Tagged ‘CString’

Converting CString to LPCTSTR or LPTSTR

September 5, 2008 2 comments

Converting from CString to char* is conditional, becuase CString is a TCHAR based implementation. TCHAR is defined as a char if _UNICODE is not defined, so if this is the case we can convert to char*, since TCHAR* and char*  are equal, else we’ve got to use function like MultiByteToWideChar/W2A/W2AEX etc.

So from now on for this post I will be using TCHAR version of char. Above explanation would have helped you in understanding what exactly is a TCHAR.

Converting CString to LPCTSTR –

CString has an inbuilt operator which returns a constant pointer to it’s internal data member. It’s called operator LPCTSTR().

So if you write code like this…

CString Str;
LPCTSTR lpctszStr = Str;

The compiler replaces above line with a call to operator LPCTSTR(). So will look somewhat like this…

LPCTSTR lpctszStr = Str.operator LPCTSTR();

This is the reason why we can directly pass CString objects to SDK functions which takes LPCTSTR arguments, for e.g. ::SetWindowText.

Converting CString to LPTSTR –

Converting from CString to LPTSTR is slightly bit more work. We’ve got to call function GetBuffer to get internal data pointer. Don’t forget to call ReleaseBuffer once you are done with the buffer.

LPTSTR lptszStr = Str.GetBuffer(0);
Str.ReleaseBuffer();

A different flavor of this function exists called GetBufferSetLength. Well what’s the use of this function, you can explicitly as CString to give you a larger buffer that the current one. For eg. if you wanna call the SDK version of GetWindowText using a CString object without using a temporary raw TCHAR buffer, you can use GetBufferSetLength function passing the required buffer length as the argument and of course the ReleaseBuffer call should be made too!

Here is a classic example from CWnd::GetWindowText on how to use GetBufferSetLength.

CString rString;
int nLen = ::GetWindowTextLength(m_hWnd);
::GetWindowText(m_hWnd, rString.GetBufferSetLength(nLen),  nLen+1);
rString.ReleaseBuffer();

Converting to and from a unicode string –

https://nibuthomas.wordpress.com/2008/07/02/how-to-convert-a-ansi-string-to-unicode-string-and-vice-versa/

Advertisements

How to trim white space before and after a string?

September 5, 2008 4 comments

I will describe in this post three ways to trim a string of given characters…

  1. Using custom function for std::string
  2. Using CString
  3. Using StrTrim shell API function.

Using custom function for std::string

Its bit strange that std::string doesn’t provide a Trim function 😕 , but hey since we’ve got head upon our shoulders we’re gonna write one. :P. Here is a simple function which removes white space before and after a string. We’ll call it Trim! 😛

void Trim( const std::string& StrToTrim, std::string& TrimmedString )
{
  // Find first non whitespace char in StrToTrim
  std::string::size_type First = StrToTrim.find_first_not_of( ' ' );
  // Check whether something went wrong?
  if( First == std::string::npos )
  {
    First = 0;
  }

  // Find last non whitespace char from StrToTrim
  std::string::size_type Last = StrToTrim.find_last_not_of( ' ' );
  // If something didn't go wrong, Last will be recomputed to get real length of substring
  if( Last != std::string::npos )
  {
    Last = ( Last + 1 ) - First;
  }

  // Copy such a string to TrimmedString
  TrimmedString = StrToTrim.substr( First, Last );
}

int main()
{
  std::string StrToTrim = " 32 Nibu babu thomas 2342 2 23 3 ";
  std::string TrimmedString = "On return will hold trimmed string";
  Trim( StrToTrim, TrimmedString );

  return 0;
}
//Output is: 32 Nibu babu thomas 2342 2 23 3

Using CString

Also CString has a Trim function, if you have the liberty to use CString then that’s another option.

Using StrTrim shell API function

Another option is to use StrTrim shell API function. Here is a demo from MSDN.

#include
#include
#include “Shlwapi.h”

void main(void)
{
//String one
TCHAR buffer[ ] = TEXT(“_!ABCDEFG#”);
TCHAR trim[ ] = TEXT(“#A!_”);

cout << "The string before calling StrTrim: "; cout << buffer; cout << "\n"; StrTrim(buffer, trim); cout << "The string after calling StrTrim: "; cout << buffer; cout << "\n"; } OUTPUT: - - - - - - The string before calling StrTrim: _!ABCDEFG# The string after calling StrTrim: BCDEFG[/sourcecode]

Replacement for CString::Format in standard C++

std::stringstream can be used as a replacement for CString::Format, if you are using CString just for the sake of Format, caveat being that it could be slow, I’ve heard a user mentioning this but not sure, I haven’t tested it out, but should be definitely better that using CString::Format and then assigning to std::string.

std::stringstream strm;
strm << "Age: " << nAge << ", DOB: " << szDate << ", Salary: " << nSalary; std::cout << strm.str();[/sourcecode]

A TCHAR version of std stream and string classes

Quite simple…

// A TCHAR based std::string
typedef std::basic_string<tchar> tstring;
// A TCHAR based std::ifstream;
typedef std::basic_ifstream</tchar><tchar , std::char_traits<TCHAR> > tstream;
// A TCHAR based std::stringstream
typedef std::basic_stringstream</tchar><tchar , std::char_traits<TCHAR>, std::allocator</tchar><tchar> > tstringstream;

So now no need to worry about UNICODE and ANSI, should work as CString, since TCHAR becomes char/wchar_t based on _UNICODE macro definition.

Also note that stl has provided UNICODE versions of these classes for e.g. wstring, wstringstream, wifstream, but since windows has a type that switches automagically between char/wchar_t, we are making use of it.

So the idea behind this is that stl classes are mostly template based, so this means you can add your own version of an stl class for a custom type just like I’ve done. As a conclusion we can say that std::string can be called a vector<char> but with dedicated string operations.

%d bloggers like this: