Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

convert wstring to wchar*

4,821 views
Skip to first unread message

Ashish

unread,
Oct 14, 2008, 10:37:47 AM10/14/08
to
To convert std::wstring to wchar* or LPWSTR the function is
wstring.c-str() which returns wchar*
This works fine in VC6
But in visual studio 2008(vc9) it returns garbage value.
is there some other function to convert std::wstring to wchar*/LPWSTR


Eberhard Schefold

unread,
Oct 14, 2008, 11:32:02 AM10/14/08
to
Ashish wrote:

> To convert std::wstring to wchar* or LPWSTR the function is
> wstring.c-str() which returns wchar*

Actually, wstring::c_str() returns a "const wchar_t *". You can use it
as a LPCWSTR, but not as a LPWSTR.

> This works fine in VC6
> But in visual studio 2008(vc9) it returns garbage value.

You should post a compilable example where you think that happens.

Mark Salsbery [MVP]

unread,
Oct 14, 2008, 11:38:21 AM10/14/08
to
"Ashish" <akohl...@hotmail.com> wrote in message
news:epghoqg...@TK2MSFTNGP06.phx.gbl...

> To convert std::wstring to wchar* or LPWSTR the function is
> wstring.c-str() which returns wchar*

It returns a const wchar_t *


> This works fine in VC6
> But in visual studio 2008(vc9) it returns garbage value.


What does your code look like?

This works for me:

wstring wstr = L"Test wstring";
const wchar_t *pwstr = wstr.c_str();


Mark

--
Mark Salsbery
Microsoft MVP - Visual C++

Giovanni Dicanio

unread,
Oct 14, 2008, 11:44:56 AM10/14/08
to

"Ashish" <akohl...@hotmail.com> ha scritto nel messaggio
news:epghoqg...@TK2MSFTNGP06.phx.gbl...

As others already wrote, std::wstring::c_str() returns a '*const* wchar_t
*'.

If you want to modify the buffer (i.e. if you want a non-const wchar_t *),
you may try CStringW::GetBuffer().

Giovanni


Ashish

unread,
Oct 15, 2008, 4:41:18 AM10/15/08
to
Please try following code

std::wstring wst;
void Fillwst(std::wstring st) {wst = st;}
std::wstring Getwst(){return wst;}

Fillwst(L"WideString");
WCHAR* outstr= (WCHAR*) Getwst().c_str();

Please check what's in outstr.
It contains garbage value.

If we define Fillwst like
void Fillwst(const std::wstring& st) {wst = st;}
Then no impact means above code will return garbage value


Eberhard Schefold

unread,
Oct 15, 2008, 5:57:24 AM10/15/08
to
Ashish wrote:

> Please try following code
>
> std::wstring wst;
> void Fillwst(std::wstring st) {wst = st;}
> std::wstring Getwst(){return wst;}
>
> Fillwst(L"WideString");
> WCHAR* outstr= (WCHAR*) Getwst().c_str();

This example doesn't compile by any stretch of the imagination. I beg
you, please post compilable code. Don't let us guess over the actual
problems you're having.

In any event, two problems are obvious:

- You're brutally casting a const pointer into a non-const pointer.
Any use of the resulting pointer has undefined behaviour.

- You're storing a pointer that is only valid as long as the
underlying wstring object is not modified (in particular: not
destroyed). Since Getwst returns just a temporary wstring object, the
pointer becomes invalid after the line is finished.

Ashish

unread,
Oct 15, 2008, 8:17:34 AM10/15/08
to
Ok. Please try the following code in VC6 and VC9(visual studio 2008).
Make a console application in VC6/VC9, create a new file and paste following
code. When run in VC6 you'll see "WideString" will be printed on console
window. While in VC9 console window is empty.

#include<stdio.h>
#include <iostream>
#include <sstream>
#include <ComDef.h>
using std::wstring;
using std::cout;
class usewstring
{
public:
std::wstring wst;
void Fillwst(const std::wstring& st) {wst = st;}
std::wstring Getwst() const throw(){return wst;}

};


void main()
{
usewstring Obj;
Obj.Fillwst(L"WideString");
WCHAR* outstr= (WCHAR*) Obj.Getwst().c_str();
_putws(outstr);
}


Igor Tandetnik

unread,
Oct 15, 2008, 8:31:19 AM10/15/08
to
"Ashish" <akohl...@hotmail.com> wrote in message
news:%23JWh%23AsLJ...@TK2MSFTNGP05.phx.gbl

> Ok. Please try the following code in VC6 and VC9(visual studio 2008).
> Make a console application in VC6/VC9, create a new file and paste
> following code. When run in VC6 you'll see "WideString" will be
> printed on console window. While in VC9 console window is empty.

The code exhibits undefined behavior (in other words, it's buggy). The
bug just happens to manifest differently under different
implementations. "Appears to work" is just one possible manifestation of
undefined behavior.

> WCHAR* outstr= (WCHAR*) Obj.Getwst().c_str();

Again, Getwst returns a temporary wstring object. This object goes out
of scope and is destroyed at the end of the statement above. When it's
destroyed, it deallocates the memory it has allocated for the string
data - precisely the memory that c_str() returns a pointer to. So outstr
becomes invalid - it ends up pointing to a block of deallocated memory
(also known as a "dangling pointer").
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Giovanni Dicanio

unread,
Oct 15, 2008, 9:08:42 AM10/15/08
to

"Ashish" <akohl...@hotmail.com> ha scritto nel messaggio
news:%23JWh%23AsLJ...@TK2MSFTNGP05.phx.gbl...

> class usewstring
> {
> public:
> std::wstring wst;
> void Fillwst(const std::wstring& st) {wst = st;}
> std::wstring Getwst() const throw(){return wst;}

I don't understand why you give 'wst' data member public visibility and you
offer also a getter (Getwst()).

I would just make 'wst' data member private, and expose two public
getter/setter (Getwst and Fillwst).

> void main()
> {
> usewstring Obj;
> Obj.Fillwst(L"WideString");
> WCHAR* outstr= (WCHAR*) Obj.Getwst().c_str();
> _putws(outstr);

_putws parameter is a const wchar_t *, so I think that you could just do
(without removing const qualifier):

_putws( Obj.Getwst().c_str() );

http://msdn.microsoft.com/en-us/library/tf52y4t1.aspx


or you could modify the Getwst() prototype like this:

const wchar_t * Getwst() const
{
return wst.c_str();
}

and just do:

_putws( Obj.Getwst() );


HTH,
Giovanni


Tamas Demjen

unread,
Oct 15, 2008, 8:05:29 PM10/15/08
to

.c_str() returns const wchar_t*, but you can copy that into a vector,
which in turn can be modified:

std::wstring text(L"hello");
const wchar_t* text_ptr = text.c_str();
std::vector<wchar_t> buffer(text_ptr, text_ptr + text.size() + 1);
wchar_t* buffer_ptr = &buffer[0];

Tom

0 new messages