I would like to shuffle the characters present in CString varible. How do i do it? Std provide a finction called random_shuffle() which can be used to shuffle std::string in the following way std::string s("ThisIsSample"); random_shuffle(s.first(),s.last()); But since CString doesnt have a function to access the fisrt and last character to iterate. How do i use random_shuffle with CString?
2 Answers
Use GetBuffer
to obtain the character buffer, and pass its boundaries to std::random_shuffle
:
void shuffle_cstring(CString& c)
{
size_t len = c.GetLength();
LPTSTR buf = c.GetBuffer(1);
std::random_shuffle(buf, buf + len);
c.ReleaseBuffer();
}
-
You need to call
ReleaseBuffer
when you're done with your manipulations. Commented Nov 29, 2014 at 8:21 -
Oh, and you should also call
GetLength
first, and store the result in a separate variable. Because you're not supposed to call any other member functions on theCString
between the time you callGetBuffer
and the time you callReleaseBuffer
. Commented Nov 29, 2014 at 8:26 -
@BenjaminLindley I wonder if that's really necessary in this case. MSDN says, If you use the pointer returned by
GetBuffer
to change the string contents, you must callReleaseBuffer
before using any other CString member functions. The code does change the contents, but only by rearranging characters, so it affects neither the length of the string nor the characters present. Commented Nov 29, 2014 at 8:32 -
A shuffle is a series of swaps. A swap is 3 assignments (1 to an external character, and 2 to elements in the array). And an assignment is changing a character. Ergo, shuffling is changing the contents. You might be able to get away with it, but I don't see why you would unnecessarily break the contract of the API, knowing the implementation could change later on, possibly breaking your code. Commented Nov 29, 2014 at 8:37
-
@BenjaminLindley I agree that
std::random_shuffle
is changing the buffer contents. It is very questionable, however, that a character shuffle would affectGetLength
in any way, especially asGetLength
is required to work when the buffer remains unmodified. Commented Nov 29, 2014 at 8:55
Convert CString to std::string:-
CString cs("Hello");
std::string s((LPCTSTR)cs);
NOTE:- BUT: std::string cannot always construct from a LPCTSTR. i.e. the code
will fail for UNICODE builds.
EDIT IN RESPONSE TO COMMENT
As std::string can construct only from LPSTR / LPCSTR, a programmer who uses VC++ 7.x or better can utilize conversion classes such as CT2CA as an intermediary.
CString cs ("Hello");
// Convert a TCHAR string to a LPCSTR
CT2CA pszConvertedAnsiString (cs);
// construct a std::string using the LPCSTR input
std::string strStd (pszConvertedAnsiString);
Use random_shuffle on s and then:-
CString cs1(s.c_str());
-
Note that you can use
std::basic_string<TCHAR>
to effectively get astd::string
in narrow build andstd::wstring
in Unicode builds. Commented Nov 29, 2014 at 9:06