MistyD
MistyD

Reputation: 17243

Copy the contents of CStringArray to std::vector

As the question states I would like to copy the contents of a CStringArray into a std::vector<std::string>.
Any suggestions?

Upvotes: 4

Views: 5559

Answers (3)

xMRi
xMRi

Reputation: 15375

Because CStringArray is also allocated in a linear array, there is no need for a loop. Simply use the insert function and define the start and the end element of the CStringArray!


typedef std::basic_string<TCHAR> tstring;

int _tmain(int argc, TCHAR* argv[])
{
    CStringArray array;
    array.Add(_T("Test1"));
    array.Add(_T("Test2"));
    array.Add(_T("Test3"));
    array.Add(_T("Test4"));
    
    vector<tstring> vec;
    vec.insert(vec.begin(), &array[0], &array[array.GetSize() - 1] + 1);

    return 0;
}

Upvotes: 6

Mr.C64
Mr.C64

Reputation: 42994

CStringArray contains CStrings. In Unicode builds (which have been the default since VS2005, and should be considered for modern C++ Windows software), CString stores Unicode UTF-16 strings.

Instead, std::vector<std::string> contains std::strings, which can store ANSI or MBCS strings, or UTF-8 strings, but not Unicode UTF-16 strings.

So, to properly perform this conversion, you have to think first how to convert from CString to std::string.

An option could be to use the CT2A conversion helper (or CW2A, if you consider only Unicode builds, and CString as storing always UTF-16 strings).

However, note that the conversion from Unicode (CString) to "ANSI" can be lossy. A non-lossy conversion could be from UTF-16 to UTF-8 (to convert from a Unicode UTF-16 to a Unicode UTF-8 string, it's possible to use CW2A with CP_UTF8 conversion flag).

Anyway, assuming that the default conversion performed by CT2A is acceptable for you, you can consider simple code like the following: just iterate through the CStringArray, convert current CString to std::string using CT2A, and push_back the resulting string to the std::vector; note that thanks to C++11/14 move semantics, returning a std::vector<std::string> from the function is not a performance problem.

std::vector<std::string> CStringArrayToStdVector(const CStringArray& source)
{
    std::vector<std::string> result;
    result.reserve(source.GetCount());

    for (INT_PTR i = 0; i < source.GetCount(); ++i)
    {
        result.push_back(std::string(CT2A(source.GetAt(i))));
    }

    return result;
}

Upvotes: 3

bvj
bvj

Reputation: 3392

#include <string>
#include <vector>

#if defined(UNICODE) || defined(_UNICODE)
typedef std::wstring string;
#else
typedef std::string string;
#endif

typedef std::vector<string> StringVector;

void CmfcstrarDlg::OnBnClickedButton1()
{

    CStringArray strs;
    strs.Add(_T("one"));
    strs.Add(_T("two"));
    strs.Add(_T("three"));

    StringVector copy;

    for (int n = 0; n < strs.GetCount(); n++)
    {
        const CString& s = strs.GetAt(n);
        copy.push_back(string(s));
    }

    StringVector::const_iterator citer = copy.cbegin();
    for (; citer != copy.cend(); citer++)
    {
        OutputDebugString(citer->c_str());
        OutputDebugString(_T("\n"));
    }

}

Upvotes: 2

Related Questions