views:

73

answers:

3

I have an array of WCHAR[]s. How can I join them?

I know the array length.

[L"foo", L"bar"] => "foo, bar"
+4  A: 

Loop over those strings and add them to a std::wstring:

std::wstring all;

wchar_t *data[] = { L"foo", ... };
size_t data_count = sizeof(data) / sizeof(*data);

for (size_t n = 0; n < data_count; ++n)
{
    if (n != 0)
        all += L", ";
    all += data[n];
}
R Samuel Klatchko
+1 as it is the basis of my answer. Though I would replace the loop handling with what I have.
Billy ONeal
You should change `int n` to an unsigned type (preferably size_t). Otherwise compilers will complain.
Billy ONeal
@BillyONeal - thanks for calling out the `int` / `size_t` issue.
R Samuel Klatchko
A: 

Does your system have wsprintf()? Example:

wchar_t *a = { L"foo", L"bar" };
wchar_t joined[1000];

wsprintf(joined, "%S, %S", a[0], a[1])
Carl Norum
A: 

Slightly improved version of R Samuel Klatchko's solution.

wchar_t *data[] = { L"foo", ... };
size_t data_count = sizeof(data) / sizeof(*data);

wchar_t result[STUFF];

wcscpy(result, data[0]);
for (std::size_t n = 1; n < data_count; ++n)
{
    wcscat(result, L", ");
    wcscat(result, data[n]);
}

The improvement is that no if branch dependency is in the loop. I have converted to the C standard library's wcsXXXX functions, but I'd use a std::wstring if it is available.

EDIT:

Assuming

I know the array length.

means, "I know the number of strings I'd like to join", then you can't use what I've posted above, which requires you know the final destination string length at compile time.

If you don't know at compile time, use this which works otherwise (and contains the loop improvement I was talking about):

wchar_t *data[] = { L"foo", ... };
size_t data_count = sizeof(data) / sizeof(*data);

std::wstring result(data[0]); //Assumes you're joining at least one string.
for (std::size_t n = 1; n < data_count; ++n)
    result.append(L", ").append(data[n]);
Billy ONeal
I would definitely use a std::wstring, unless you know how big to make STUFF. You should also add a null terminator.
zdan
@zdan: The OP explicitly specified that he knows the length. wcscpy and wcscat add appropriate NULL terminators -- none are required.
Billy ONeal
-1 for inviting a buffer overflow and for using the Shlemiel the painter's algorithm (http://www.joelonsoftware.com/articles/fog0000000319.html).
dan04
@dan04: I agree that it'd be better to use a std::wstring. I'm posting this as an example of how the same thing might be accomplished using the C standard library. So long as the strings aren't huge, it's not going to matter anyway. (Shlemiel the Painter's Algorithm is the biggest reason the C string handling system sucks!). As for the buffer overrun, it's not going to buffer overrun if the OP knows the length in advance, as he has indicated.
Billy ONeal
@Billy: I interpreted the array length to be the number of input array elements, not the resulting output buffer size. Point taken about wcscat.
zdan
@zdan: Good point. I've edited my answer.
Billy ONeal