Advertisement

I need to get a CString to a Char

Started by October 11, 2000 07:59 PM
5 comments, last by DisKordCoder 24 years, 2 months ago
Just like the Title, i need to convert a CString to a basic Char Array. Does anyone know how? Thanks.

    	CString str;	const char* s;	s = (LPCTSTR)str;    


if you need to modify it, you need to copy it... there''s probably a better way to do that than to use a char*.

Are you serializing it or something?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Advertisement
I think a cast there is a bit dangerous, because CString is a dynamic string class (as the string changes size dynamically the address changes, which can lead to interesting results if you''re pointing at the memory when that happens). The safest way to do it is use GetBuffer, being sure to use ReleaseBuffer when you''re done.
~ The opinions stated by this individual are the opinions of this individual and not the opinions of her company, any organization she might be part of, her parrot, or anyone else. ~
CString::GetBuffer is something you should use as a last resort, not the other way around. The const char* operator is very safe to use. The only thing you have to assure is that the CString being used is not changed while you use the pointer.

It''ll be easier if I show some examples.
CString str ("1000 is the number I want");
int num = atoi (str); // works fine, num = 1000;
unsigned long num2 = strtoul (str, NULL, 10); // num2 = 1000
const char buf[256];
strcpy (buf, str); // also works fine

As you can see, all these functions that take an argument of const char* work fine with CString. You don''t even have to explicitly cast it. In fact, the operation of converting a CString to a const char* is extremely fast--it just returns a pointer to its internal buffer. CString always keeps its string null-terminated in memory, even though the length it reports does not include the null character.

It''s important to note that you shouldn''t SAVE the pointer returned by CString:
CString str = "Hello";
const char* p = str;
cout << p; // prints "Hello"
str += " World, how ya doing?";
cout << p; // undefined!!

The reason the last call is undefined is because when you do any kind of an operation on a CString, the CString might reallocate its internal buffer and put it somewhere else. If you save the const char*, you''re still looking at the old buffer. You might get garbage.

One thing you can''t do is pass a CString to a function that takes a (non-const) char*; you can''t use it with strtok, the target of a sprintf or the target of a strcpy for instance. CString tries to make is so you don''t have to by providing a lot of functionality with the class: CString::Format does everything sprintf would do, and CString::operator += is the same as a strcat, etc. However, if you absolutely MUST pass it to a function that requires a char*, you have to use GetBuffer.

I have a philosophical problem with GetBuffer. GetBuffer returns a pointer to a char*, and allocates the amount of memory to the char array. Now you''re free to use it completely like a char*, including overrunning the memory, accidentally deleting it, etc. In addition, you can''t use ANY of CString''s functions until you ReleaseBuffer. And if you don''t keep track of how much of the allocated memory you''ve used, and just do a ReleaseBuffer (-1), CString has to do a strlen on the string, which can be costly.

The only time I use GetBuffer and ReleaseBuffer is when I need to modify a CString in a tight loop. Even then, I find myself screwing up the calculations and overrunning the bounds that I requested--I always have to carefully step through the code and look at the memory, making sure I did everything correctly.

CString is supposed to encapsulate the above kind of operations so that you can''t screw up allocation. I''d suggest using GetBuffer only as a last resort. If you''re using GetBuffer with CString as your exclusive operation, you might as well be using vector< char >--it''s the exact same thing.
Actually Stoffel my comment on GetBuffer was in response to Magmai''s comment about modifying it... and the char array being talked about wasn''t specified as const. If it''s a const char *, then I agree that using the internal conversion is definately the way to go.

Personally I think the STL basic_string class is a little bit more robust, having used both, if you want a dynamic string class.
~ The opinions stated by this individual are the opinions of this individual and not the opinions of her company, any organization she might be part of, her parrot, or anyone else. ~
fel: wow, good thing I took out all the flaming language, then. =)

I don''t like basic_string because it doesn''t have a natural cast to const char*; I hate peppering my code with ".c_str ()" everywhere. I suppose I could write a global operator to do it, but, well, you know. That would be work.

And I LOVE Left, Right and Mid on CString. Just call me a BASIC fool. =)
Advertisement
Heehee... yeah, true... I cheat tho. If I need left right mid I just throw it into a CString temporarily...

Then again the stuff I''m doing makes full use of the STL container classes, so I''m biased.
~ The opinions stated by this individual are the opinions of this individual and not the opinions of her company, any organization she might be part of, her parrot, or anyone else. ~

This topic is closed to new replies.

Advertisement