Reputation: 17243
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
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
Reputation: 42994
CStringArray
contains CString
s. 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::string
s, 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
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