Share via


Convert wstring to string

Question

Wednesday, December 30, 2009 9:18 PM

Hi!
How can I convert a variable of type wstring to string ?
thanks!

All replies (15)

Monday, January 4, 2010 6:07 PM ✅Answered

The worst possible code:

    std::wstring wstr = L"badcode";  
    BSTR bstr = SysAllocString(wstr.c_str());
    _bstr_t bstr1(bstr);
    std::string str(bstr1);
    SysFreeString(bstr);

Try that.

This will actually not compile because the _bstr_t constructor that takes a BSTR also takes a bool parameter specifying whether the string is to be copied or attached. If you want to use _bstr_t then just do

std::wstring wstr = L"badcode";  
_bstr_t bstr1(wstr.c_str());
std::string str(bstr1);

The _bstr_t will take care of SysAllocString() and SysFreeString().

A similar idea is to use CStringA

std::wstring wstr = L"badcode";  
CStringA s(wstr.c_str());
std::string str(s);

But I prefer using CW2A, which says what it does and does what it says (without relying on implicit conversion features of _bstr_t or CString):

std::wstring wstr = L"badcode";  
std::string str(CW2A(wstr.c_str()));

David Wilkinson | Visual C++ MVP


Monday, January 4, 2010 10:32 PM ✅Answered | 1 vote

I agree with removing the BSTR part. But I don't agree with the won't compile part.  There are 5 different constructors for _bstr_t.

Six in my VC9 documentation:

_bstr_t( ) throw( );
 
_bstr_t(
   const _bstr_t& s1
) throw( );

_bstr_t(
   const char* s2
);

_bstr_t(
   const wchar_t* s3
);

_bstr_t(
   const _variant_t& var
);

_bstr_t(
   BSTR bstr,
   bool fCopy
);

And the last one takes two parameters.

But you are right, your code compiles, I think because it uses one of the other constructors.

David Wilkinson | Visual C++ MVP


Wednesday, December 30, 2009 9:37 PM

http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/4814a1ad-42b1-4f05-a65b-7b9f6189c92a


Wednesday, December 30, 2009 9:42 PM

I used

System::String ^ strArg2 =

gcnew System::String( (szArglist[i+1]).c_str() );

 

but got the following errors. Please help

error C2653: 'System' : is not a class or namespace name

 error C2065: 'String' : undeclared identifier

 error C2065: 'strArg2' : undeclared identifier

 error C2065: 'gcnew' : undeclared identifier

 error C2653: 'System' : is not a class or namespace name


Wednesday, December 30, 2009 9:46 PM

I am using Visual studio 2005


Wednesday, December 30, 2009 9:52 PM

What type of C++ project is this?


Wednesday, December 30, 2009 9:54 PM

application(.exe) using MFC in a shared dll


Wednesday, December 30, 2009 10:00 PM

System is probably not recognized if you are not using managed C++.

See this discussion:

http://stackoverflow.com/questions/258050/how-to-convert-cstring-and-stdstring-stdwstring-to-each-other


Wednesday, December 30, 2009 10:12 PM

The worst possible code:

    std::wstring wstr = L"badcode";  
    BSTR bstr = SysAllocString(wstr.c_str());
    _bstr_t bstr1(bstr);
    std::string str(bstr1);
    SysFreeString(bstr);

Try that.


Wednesday, December 30, 2009 10:30 PM

Read this article.


Monday, January 4, 2010 6:55 AM

Hello RuchiraM,

Have you got any progress on this issue with the suggestions? If there is anything else we can help, welcome to post here.

Regards,
Rong-Chun Zhang
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg@microsoft.comPlease remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.


Monday, January 4, 2010 4:52 PM

Hi! Rong-Chun,
Unfortunately, no, I am still not able to do this. I have not tried the solution by gsumm

std::wstring wstr = L"badcode";  
    BSTR bstr = SysAllocString(wstr.c_str());
    _bstr_t bstr1(bstr);
    std::string str(bstr1);
    SysFreeString(bstr);

I was wondering, is there not an easier and cleaner way to convert this. I am using the CommandLineToArgvW function which has parameters of type LPWSTR. I need to parse them out and use them in some sort of an if-else control structure in which they need to be passes as strings or CStrings.
Is there a better way to do this ?

Thanks in advance.
Ruchira


Monday, January 4, 2010 5:12 PM

This situation remains totally unclear to me. You are getting UNICODE command line arguments....is there a reason why the program is not set to use UNICODE to begin with? Seems to be the most straightforward solution to me.  (It would be the "easier and cleaner" way, in my opinion.) Yes, UNICODE is a bit messy at first, but after you resign yourself to using it, it becomes very transparent to you as a developer. Having to straddle the ANSI/UNICODE divide is sometimes vexing to me as a developer, too.

Of course, I'm not that new or naive, so...

  1. You can get the CL in ANSI using GetCommandLineA, as opposed to GetCommandLineW, provided the CL is actually ANSI. I'm sure you've already eliminated this one.

  2. You could use WideCharToMultiByte, but...that's still pretty messy looking.

  3. You could use the code provided by writing a conversion function that took the array left by CommandLineToArgW and returned an array of ANSI strings. The function itself would look a mess, but this is messy stuff, after all.


Monday, January 4, 2010 9:57 PM

I agree with removing the BSTR part. But I don't agree with the won't compile part.  There are 5 different constructors for _bstr_t.


Tuesday, January 5, 2010 4:07 PM

David,
I was able to get it working with

std::wstring wstr = L"badcode";  
std::string str(CW2A(wstr.c_str()));

Thanks so much for all your help.
regards

Ruchira