2

I have to concatenate wide C-style strings, and based on my research, it seems that something like _memccpy is most ideal (in order to avoid Shlemiel's problem). But I can't seem to find a wide-character version. Does something like that exist?

  • It would improve the question to show sample code where you set up and work with the strings in question – M.M Mar 13 '20 at 03:12
  • For reference, `wcscpy()` available since C95 and [VS2019](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-wcscpy-mbscpy?view=vs-2019). What compiler/version are you using? – chux - Reinstate Monica Mar 13 '20 at 07:14
  • @chux It appears that `wcscpy` doesn't return a pointer to the end of the copied string, which is the main optimization offered by `_memccpy`. –  Mar 13 '20 at 17:14

1 Answers1

3

Does something like that exist?

The C standard library does not contain a wide-character version of Microsoft's _memccpy(). Neither does it contain _memccpy() itself, although POSIX specifies the memccpy() function on which MS's _memccpy() appears to be modeled.

POSIX also defines wcpcpy() (a wide version of stpcpy()), which copies a a wide string and returns a pointer to the end of the result. That's not as fully featured as memccpy(), but it would suffice to avoid Shlemiel's problem, if only Microsoft's C library provided a version of it.

You can, however, use swprintf() to concatenate wide strings without suffering from Shlemiel's problem, with the added advantage that it is in the standard library, since C99. It does not provide the memccpy behavior of halting after copying a user-specified (wide) character, but it does return the number of wide characters written, which is equivalent to returning a pointer to the end of the result. Also, it can directly concatenate an arbitrary fixed number of strings in a single call. swprintf does have significant overhead, though.

But of course, if the overhead of swprintf puts you off then it's pretty easy to write your own. The result might not be as efficient as a well-tuned implementation from your library vendor, but we're talking about a scaling problem, so you mainly need to win on the asymptotic complexity front. Simple example:

/*
 * Copies at most 'count' wide characters from 'src' to 'dest', stopping after
 * copying a wide character with value 0 if that happens first. If no 0 is
 * encountered in the first 'count' wide characters of 'src' then the result
 * will be unterminated.
 * Returns 'dest' + n, where n is the number of non-zero wide characters copied to 'dest'.
 */
wchar_t *wcpncpy(wchar_t *dest, const wchar_t *src, size_t count) {
    for (wchar_t *bound = dest + count; dest < bound; ) {
        if ((*dest++ = *src++) == 0) return dest - 1;
    }
    return dest;
}
John Bollinger
  • 160,171
  • 8
  • 81
  • 157