none
Convert wstring to string

Answers

  • 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
    • Marked as answer by RuchiraM Tuesday, January 05, 2010 4:07 PM
    Monday, January 04, 2010 10:32 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.
    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 04, 2010 6:07 PM

All replies

  • http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/4814a1ad-42b1-4f05-a65b-7b9f6189c92a
    Wednesday, December 30, 2009 9:37 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:42 PM
  • I am using Visual studio 2005
    Wednesday, December 30, 2009 9:46 PM
  • What type of C++ project is this?
    Wednesday, December 30, 2009 9:52 PM
  • application(.exe) using MFC in a shared dll
    Wednesday, December 30, 2009 9:54 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
    • Proposed as answer by Jijo Raj Thursday, December 31, 2009 6:43 AM
    Wednesday, December 30, 2009 10:00 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:12 PM
    • Proposed as answer by Jijo Raj Thursday, December 31, 2009 6:43 AM
    Wednesday, December 30, 2009 10:30 PM
  • 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.com
    Please 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 04, 2010 6:55 AM
  • 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 04, 2010 4:52 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 04, 2010 5: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.
    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 04, 2010 6:07 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.
    Monday, January 04, 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.

    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
    • Marked as answer by RuchiraM Tuesday, January 05, 2010 4:07 PM
    Monday, January 04, 2010 10:32 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
    Tuesday, January 05, 2010 4:07 PM