0

I'm trying to use the StringCchCat function:

    HRESULT X;
    LPWSTR _strOutput =  new wchar_t[100];
    LPCWSTR Y =L"Sample Text";
    X = StringCchCat(_strOutput, 100, Y);

But for some reason I keep getting the "E_INVALIDARG One or more arguments are invalid." error from X. _strOutput Is also full of some random characters.

This is actually part of a bigger program. So what I'm trying to do is to concatenated the "sample text" to the empty _strOutput variable. This is inside a loop so it is going to happen multiple times. For this particular example it will be as if I'm assigning the Text "Sample Text" to _strrOutput.

Any Ideas?

Math4123
  • 1,267
  • 4
  • 12
  • 23
  • You are not initializing the contents of your `new wchar_t[100]`, so you end up with an initial string full of garbage (and a probable buffer overflow underway). `StringCchCat()` understandably refuses to concatenate anything to such a string (from [the docs](https://msdn.microsoft.com/en-us/library/windows/desktop/ms647518.aspx), it thinks "the destination buffer is already full"). – Frédéric Hamidi Feb 14 '15 at 18:03
  • So do I initialize it with spaces? or something else? – Math4123 Feb 14 '15 at 18:04
  • Depends. Do you want it to be an empty string, a string full of spaces, or something else? What exactly are you trying to achieve? – Frédéric Hamidi Feb 14 '15 at 18:05
  • I've updated the question. Hope it helps, I want an to concatenate "Sample Text" to an empty string – Math4123 Feb 14 '15 at 18:06
  • Well... why? Why not just copy the string instead of concatenating to an empty string? – Frédéric Hamidi Feb 14 '15 at 18:09
  • Its actually part of a loop. Its gonna happen 100 times. – Math4123 Feb 14 '15 at 18:09
  • Use StringCchCatW() for WCHAR strings. StringCchCat() is for TCHAR – Edward Falk Jan 11 '17 at 20:59

3 Answers3

2

If it's part of a loop, a simple *_strOutput = 0; will fix your issue.

If you're instead trying to copy a string, not concatenate it, there's a special function that does this for you: StringCchCopy.

Edit: As an aside, if you're using the TCHAR version of the API (and you are), you should declare your strings as TCHAR arrays (ie LPTSTR instead of LPWSTR, and _T("") instead of L""). This would keep your code at least mildly portable.

Blindy
  • 65,249
  • 10
  • 91
  • 131
  • 1
    `_T()` is for the C runtime, for use with `_TCHAR`. The Windows API uses `TEXT()` with `TCHAR` instead. And you should not really be promoting `TCHAR` anymore. Betterto suggest using the Unicode API instead, in this case `StringCchCatW`. – Remy Lebeau Feb 14 '15 at 18:23
  • Sure, hence the if. Choose one of the three versions of the Windows API and stick with it. Mixing and matching is a good way to ruin a guy's week a few years down the line. – Blindy Feb 14 '15 at 18:26
1

String copy/concat functions look for null terminators to know where to copy/concat to. You need to initialize the first element of _strOutput to zero so the buffer is null terminated, then you can copy/concat values to it as needed:

LPWSTR _strOutput =  new wchar_t[100];
_strOutput[0] = L'\0`; // <-- add this
X = StringCchCat(_strOutput, 100, Y);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
1

I'm writing this answer to notify you (so you see the red 1 at the top of any Stack Overflow page) because you had the same bug yesterday (in your message box) and I now realize I neglected to say this in my answer yesterday.

Keep in mind that the new[] operator on a built-in type like WCHAR or int does NOT initialize the data at all. The memory you get will have whatever garbage was there before the call to new[], whatever that is. The same happens if you say WCHAR x[100]; as a local variable. You must be careful to initialize data before using it. Compilers are usually good at warning you about this. (I believe C++ objects have their constructors called for each element, so that won't give you an error... unless you forget to initialize something in the class, of course. It's been a while.)

In many cases you'll want everything to be zeroes. The '\0'/L'\0' character is also a zero. The Windows API has a function ZeroMemory() that's a shortcut for filling memory with zeroes:

ZeroMemory(array, size of array in bytes)

So to initialize a WCHAR str[100] you can say

ZeoMemory(str, 100 * sizeof (WCHAR))

where the sizeof (WCHAR) turns 100 WCHARs into its equivalent byte count.

As the other answers say, simply setting the first character of a string to zero will be sufficient for a string. Your choice.

Also just to make sure: have you read the other answers to your other question? They are more geared toward the task you were trying to do (and I'm not at all knowledgeable on the process APIs; I just checked the docs for my answer).

Community
  • 1
  • 1
andlabs
  • 11,290
  • 1
  • 31
  • 52