Re: concatenate WCHAR*



"Kerby" <kerby@xxxxxxxxxxxxx> wrote in message
news:uDKXLapPFHA.3336@xxxxxxxxxxxxxxxxxxxxxxx
> how can i concatenate string using this code:
>
> LPWSTR SayHello(strName)
> {
> wchar_t * kPreffix = L"Hello ";
> LPWSTR kTemp = strName;
> int n = MAX_PATH;
>
> //ws1 - destination string
> // ws2 - source string ; n - numbers of charaters to append
> wchar_t *wcsncat(wchar_t *kTemp, const wchar_t *kPreffix, size_t n);
>
> return kTemp;
> }
>
> what i want to do is something like this:
> i want to add "Hello " to strName.
>
> ex. if the parameter strName = "Red"
> then output would be "Hello Red"
>

Generally speaking, it's unsafe to do that. I presume strName is of type
LPWSTR. Since you don't know how much memory has been allocated to it, it's
not safe to prepend another string to it.

Also, I'm not sure you understand what kTemp is. As you have it, it's just
an alias for strName-- that is, it's a pointer to the same string as strName
is. It's not a copy of the string that strName points to. So, it really has
no purpose.

Anyway, you don't want to append the string in a local copy and then return
a pointer to that copy, since it will be deallocated when it goes out of
scope at the end of the function, and dereferencing the pointer afterwards
will invoke undefined behavior.

One way to solve this here is to dynamically allocate the memory for the new
string, like this:

LPWSTR SayHello(LPCWSTR strName)
{
if (!strName) return 0; // do nothing for null pointer
static const wchar_t hello = L"Hello ";
static const size_t helloLen = strlen(hello);
wchar_t* result = (wchar_t*)(malloc(sizeof(wchar_t) * (helloLen +
strlen(strName) + 1)));
wcscpy(result, hello);
wcscpy(result + helloLen, strName); // quicker than wcscat since we
don't have to find the end of the string
return result;
}

However, this then requires the caller to deallocate the memory when they're
done with it. It also means they have to understand *how* the memory was
allocated (i.e. with malloc and not, say, C++'s new[]) so that they can call
the corresponding deallocation function (in this case, free).

In situations like this, one of two options is usually preferred:
- Pass the address of the destination buffer, and the maximum size, as
parameters into the routine. This gives the caller the responsibility both
to allocate and deallocate the buffer, and so they can do it however they
choose (e.g. on the stack, on the heap, etc).
- In C++, use a class that encapsulates the dynamic allocation, such as
std::wstring in this case.


.



Relevant Pages

  • Re: Saving to a specific file with a specific file name
    ... Dim strName As String ... 'Remove cell marker from string ... ChangeFileOpenDirectory (strPath) ...
    (microsoft.public.word.vba.general)
  • Re: INSERT INTO statement
    ... Dim StrSQL as String ... Dim strName As String ... O Wilson wrote: ...
    (microsoft.public.access.gettingstarted)
  • Re: Referencing subform during module code
    ... This would work at the form level, but not at the subform. ... Dim strName As String ...
    (comp.databases.ms-access)
  • Re: INSERT INTO statement
    ... get treated as if it were a division problem. ... Dim StrSQL as String ... Dim strName As String ...
    (microsoft.public.access.gettingstarted)
  • Re: accessing C++ functions
    ... LPWSTR should be a pointer ... it means LONG POINTER toWIDE / double byte STRING. ... It is probably due to the types I'm declaring for the structure ...
    (microsoft.public.dotnet.languages.vb)