0

I had the following code:

wchar_t recordsText[64] = L"Records: ";
std::wstringstream ss2;
ss2 << c;
wcsncat_s(recordsText, ss2.str().c_str(), sizeof(ss2.str().c_str()));
((CButton*)GetDlgItem(IDC_RECORDS))->SetWindowTextW(recordsText);

It worked pretty well, but i want to put it into a function... nothing easier i thought. but i get an stupid error.

my function was this one:

BOOL refreshTextField(CButton* item, wchar_t* label, long long* number){
    std::wstringstream ss;
    ss << number; 
    wcsncat_s(label, ss.str().c_str(), sizeof(ss.str().c_str()));
    item->SetWindowTextW(label);
    return true;
}

but the wcsncat_s doesnt like my "label" because its an array and the function is called like this:

refreshTextField(((CButton*)GetDlgItem(IDC_SENT_PACKAGES)), L"Packages send:  ", &sentPackages);

(btw: i know it shouldn't be casted to a CButton because it's an edit-field :-D , but that doesnt matter at the moment.)

the problem is the wchar_t array, i dont know how to get it into my function correctly. hope you can give me a quit answer.

i already tried this:

BOOL refreshTextField(CButton* item, wchar_t** label, long long* number){
    //...
    wcsncat_s(*label, sizeof(*label), ss.str().c_str(), sizeof(ss.str().c_str()));
    //....
}

and this:

BOOL refreshTextField(CButton* item, wchar_t* label, long long* number){
    //...
wcsncat_s(label, sizeof(*label), ss.str().c_str(), sizeof(ss.str().c_str()));
    //....
}

EDIT:

So the solution was this:

call:

refreshTextField(mySelectedUIItem, L"testlabel", sizeof(L"testlabel"), 4);

function:

BOOL refreshTextField(CButton* item, wchar_t* label, size_t lableSize, long long* number)
{
    std::wstringstream ss;
    ss << number;
    wcsncat_s(label, labelSize, ss.str().c_str(), ss.str().length());
    //...
}
Laokoon
  • 1,241
  • 4
  • 24
  • 47
  • Shouldn't any XXsncat function get an integer parameter telling the size of the array? Check the parameter list. http://msdn.microsoft.com/de-de/library/w6w3kbaf(v=vs.80).aspx – harper Jan 22 '13 at 11:54
  • @harper nope. `wcsncat_s` receives an **array** `wchar_t (&strDest)[size]` where `size` is a template argument – borisbn Jan 22 '13 at 12:12
  • @borisbn As I wrote in my answer: You can't pass an array to a function. So even wcsncat_s will not receive any sized array. There is no template neither in the question nor at the documentation. Please see the link a my other comment. – harper Jan 23 '13 at 07:38
  • @harper we are both right. There are two overloaded `wcsncat_s` - "your" variant with pointer and size and "my" with template and array. Find all occurance of `wcsncat_s` at link you gave =) BTW, there **is** call to template function in a very first snippet in the question – borisbn Jan 23 '13 at 08:42
  • @borisbn You're right I missed the very useful function template. I edited my answer appropriately. – harper Jan 23 '13 at 11:53
  • Looks like you're writing a pointer to a stream. Is that what you want? Anyhow, since you're using MFC anyway, have you checked out the `CString::Format()` function? – Ulrich Eckhardt Jan 24 '13 at 21:32

3 Answers3

1

{Edit}

When you want to use the function template, you must match all parameter types. So you must pass the length of the string instead of a second copy of the c_str() result to the wcsncat_s template:

wcsncat_s(recordsText, ss2.str().c_str(), ss2.str().length());

This will resolve to the prototype

template <size_t size>
errno_t _mbsncat_s(
   unsigned char (&strDest)[size],
   const unsigned char *strSource,
   size_t count
); // C++ only

{/Edit}

Without the template the following applies:

You can't pass an array to a function. The function will only accept the pointer. The array can be well accessed with the pointer inside the function. But you lose the information about the array size.

Since the pointer only points to the first element of the array you can't use

sizeof(*somePointer);

because this gives you the size of the first array element.

You need to change the parameter list of refreshTextField. Since the label argument points to an output variable you need the size of the variable as an additional parameter. e.g.:

BOOL refreshTextField(CButton* item, wchar_t* label, size_t lableSize, long long* number)
{
    std::wstringstream ss;
    ss << number;
    wcsncat_s(label, labelSize, ss.str().c_str(), ss.str().length());
    //...
}
harper
  • 13,345
  • 8
  • 56
  • 105
  • `sizeof(ss2.str().length())` is an error too. sizeof result of function length is always 4 (or 8 on 64bit). Just remove sizeof – borisbn Jan 23 '13 at 12:09
0

sizeof(ss2.str().c_str())

The result of function c_str() is wchar_t*. sizeof( wchar_t* ) is 4 or 8 bytes (on 32 or 64 bit system resp.). You should use wstring::length() function instead:

wcsncat_s( label, ss.str().c_str(), ss.str().length() );
borisbn
  • 4,988
  • 25
  • 42
0

try with this

BOOL refreshTextField(CButton* item, wchar_t[] label, long long* number){
    //...
   wcsncat_s(label, ss.str().c_str(), sizeof(ss.str().c_str()));
    //....
}

http://www.cplusplus.com/faq/sequences/arrays/sizeof-array/

Narkha
  • 1,197
  • 2
  • 12
  • 30
  • look at my answer. Usage of `sizeof(ss.str().c_str())` **is error** – borisbn Jan 22 '13 at 12:13
  • look the prototipe, `wchar_t[] label`. http://www.cplusplus.com/faq/sequences/arrays/sizeof-array/#cpp – Narkha Jan 22 '13 at 12:17
  • check the second parameter of wcsncat. – harper Jan 22 '13 at 12:19
  • @Narkha in your answer you 1) do not call sizeof( **label** ) 2) you cant do it, because `label` is a pointer, but not array ( `wchar_t[] label` in function parameter list **is a pointer** ) 3) you call sizeof for **pointer** `ss.str().c_str()` – borisbn Jan 22 '13 at 12:25