81

CStringは非常に便利ですがstd::string、STL コンテナーとの互換性が高くなります。を使用してhash_mapいます。ただし、s をキーとしてhash_mapサポートしていないため、 を.CStringCStringstd::string

ハッシュ関数を書くのCStringはかなり時間がかかるようです。

CString -----> std::string

これどうやってするの?

std::string -----> CString:

inline CString toCString(std::string const& str)
{
    return CString(str.c_str()); 
}

私は正しいですか?


編集:

さらに質問があります:

wstringからへCString、またはその逆に変換するにはどうすればよいですか?

// wstring -> CString
std::wstring src;
CString result(src.c_str());

// CString -> wstring
CString src;
std::wstring des(src.GetString());

これに問題はありますか?

さらに、どうすれば からstd::wstringstd::string、またはその逆に変換できますか?

4

16 に答える 16

100

CodeGuruによると:

CStringstd::string:

CString cs("Hello");
std::string s((LPCTSTR)cs);

BUT: std::string常に a から構築できるとは限りませんLPCTSTR。つまり、コードは UNICODE ビルドでは失敗します。

/std::stringからしか構築できないため、VC++ 7.x 以降を使用するプログラマーは、仲介などの変換クラスを利用できます。LPSTRLPCSTRCT2CA

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);

std::stringtoCString : ( Visual Studio の CString FAQ から... )

std::string s("Hello");
CString cs(s.c_str());

CStringT文字列またはワイド文字列の両方から構築できます。char*ie (ie LPSTR) またはwchar_t*( ) から変換できLPWSTRます。

言い換えれば、char-specialization (of CStringT) ie CStringAwchar_t-specilization CStringW、およびTCHAR-specializationは、または wide-characterCStringから構築できます。charnull 終了 (null 終了はここで非常に重要です)文字列ソース。
IInspectableは、コメントの「null-termination」部分修正します。

NUL 終了は必要ありません
CStringT明示的な長さの引数を取る変換コンストラクターがあります。これは、文字が埋め込まれCStringTたオブジェクトからオブジェクトを構築できることも意味します。std::stringNUL

于 2008-11-03T07:05:03.017 に答える
36

std::basic_string<TCHAR>の代わりにを使用してそれを解決するstd::stringと、キャラクターの設定に関係なく正常に機能するはずです。

于 2008-11-03T09:36:36.503 に答える
6

長さを指定する変換CStringを使用するように変換する方が効率的です。std::string

CString someStr("Hello how are you");
std::string std(someStr, someStr.GetLength());

タイトなループでは、これによりパフォーマンスが大幅に向上します。

于 2011-06-03T13:49:14.753 に答える
5

より C++ に似たものが必要な場合は、これを使用します。Boostにもよりますが、それはあくまで例外です。それらを簡単に削除して、STL とWideCharToMultiByte()Win32 API 呼び出しのみに依存するようにすることができます。

#include <string>
#include <vector>
#include <cassert>
#include <exception>

#include <boost/system/system_error.hpp>
#include <boost/integer_traits.hpp>

/**
 * Convert a Windows wide string to a UTF-8 (multi-byte) string.
 */
std::string WideStringToUtf8String(const std::wstring& wide)
{
    if (wide.size() > boost::integer_traits<int>::const_max)
        throw std::length_error(
            "Wide string cannot be more than INT_MAX characters long.");
    if (wide.size() == 0)
        return "";

    // Calculate necessary buffer size
    int len = ::WideCharToMultiByte(
        CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()), 
        NULL, 0, NULL, NULL);

    // Perform actual conversion
    if (len > 0)
    {
        std::vector<char> buffer(len);
        len = ::WideCharToMultiByte(
            CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()),
            &buffer[0], static_cast<int>(buffer.size()), NULL, NULL);
        if (len > 0)
        {
            assert(len == static_cast<int>(buffer.size()));
            return std::string(&buffer[0], buffer.size());
        }
    }

    throw boost::system::system_error(
        ::GetLastError(), boost::system::system_category);
}
于 2009-07-12T15:05:24.737 に答える
1

これは、彼/彼女が解決策を提供したSalの回答のフォローアップです。

CString someStr("Hello how are you");
std::string std(somStr, someStr.GetLength());

これは、非典型的な C-String を std::string に変換する場合にも役立ちます。

私のユースケースは、事前に割り当てられたchar配列(C-Stringなど)を持っていましたが、NULで終了していません。(つまり、SHA ダイジェスト)。上記の構文により、char 配列の SHA ダイジェストの長さを指定できるため、std::string は終端の NUL char を探す必要がなくなります。これは、存在する場合と存在しない場合があります。

そのような:

unsigned char hashResult[SHA_DIGEST_LENGTH];    
auto value = std::string(reinterpret_cast<char*>hashResult, SHA_DIGEST_LENGTH);
于 2016-03-10T19:04:21.087 に答える
1

この投稿から( Mark Ransomに感謝します)

CString を文字列に変換する (VC6)

私はこれをテストしましたが、正常に動作します。

std::string Utils::CString2String(const CString& cString) 
{
    std::string strStd;

    for (int i = 0;  i < cString.GetLength();  ++i)
    {
        if (cString[i] <= 0x7f)
            strStd.append(1, static_cast<char>(cString[i]));
        else
            strStd.append(1, '?');
    }

    return strStd;
}
于 2018-08-21T08:55:32.547 に答える
0

私のために働く:

std::wstring CStringToWString(const CString& s)
{
    std::string s2;
    s2 = std::string((LPCTSTR)s);
    return std::wstring(s2.begin(),s2.end());
}

CString WStringToCString(std::wstring s)
{
    std::string s2;
    s2 = std::string(s.begin(),s.end());
    return s2.c_str();
}
于 2015-11-10T10:10:29.807 に答える
0

CString他のすべての回答は、結果を変数に格納するのではなく、その場で変換するという、私が探していたものに完全には対応していませんでした。

解決策は上記と似ていますが、名前のないオブジェクトをインスタンス化するには、もう 1 つの手順が必要です。例を挙げて説明しています。ここに必要な機能がありますstd::stringが、持っていCStringます。

void CStringsPlayDlg::writeLog(const std::string &text)
{
    std::string filename = "c:\\test\\test.txt";

    std::ofstream log_file(filename.c_str(), std::ios_base::out | std::ios_base::app);

    log_file << text << std::endl;
}

あなたが持っているときにそれを呼び出す方法はCString

std::string firstName = "First";
CString lastName = _T("Last");

writeLog( firstName + ", " + std::string( CT2A( lastName ) ) );     

最後の行は直接の型キャストではありませんが、名前のないstd::stringオブジェクトを作成し、CStringそのコンストラクターを介して を提供していることに注意してください。

于 2017-06-29T21:15:37.527 に答える
-1

他の文字列タイプ間で簡単に変換したい場合は、おそらく_bstr_tクラスの方が適切でしょうか?charwchar_tとの間の会話をサポートしBSTRます。

于 2009-02-20T09:28:20.363 に答える
-1

興味深いアプローチの 1 つは、コンストラクター内にキャストCStringすることです。これとは異なり、が定義されていても機能します。ただし、その場合、Unicode から ANSI への変換が実行されるため、ASCII 文字セットを超える高い Unicode 値は安全ではありません。このような変換は、プリプロセッサの定義に従います。https://msdn.microsoft.com/en-us/library/5bzxfsea.aspxCStringAstringstd::string s((LPCTSTR)cs);_UNICODE_CSTRING_DISABLE_NARROW_WIDE_CONVERSION

        CString s1("SomeString");
        string s2((CStringA)s1);
于 2017-10-17T19:58:20.967 に答える