Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy the contents of CStringArray to std::vector

Tags:

c++

stl

mfc

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

like image 756
MistyD Avatar asked Oct 21 '25 12:10

MistyD


2 Answers

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;
}
like image 125
xMRi Avatar answered Oct 24 '25 02:10

xMRi


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;
}
like image 28
Mr.C64 Avatar answered Oct 24 '25 02:10

Mr.C64