Strings in .NET C++ WinForm project

  • Thread starter Thread starter Kim Hellan
  • Start date Start date
K

Kim Hellan

I come from C# development, but I have to make a .NET WinForm application in
C++.
I'm having some troubles handling strings in C++, which seems a lot more
problematic than in C#.
Lets say I want to construct a string like this which combines string
variables, plain strings and strings from WinForm controls:

string startStr = "<just starting>";
string newStr = startStr + myControl1->Text + "getting further" +
myControl2->Text + "the end";

In C# this is no problem, but in C++ I get all kinds of errors.
Any advice on how to handle this, would be much appreciated.

Thanks,
Kim
 
I come from C# development, but I have to make a .NET WinForm application in
C++.
I'm having some troubles handling strings in C++, which seems a lot more
problematic than in C#.
Lets say I want to construct a string like this which combines string
variables, plain strings and strings from WinForm controls:

string startStr = "<just starting>";
string newStr = startStr + myControl1->Text + "getting further" +
myControl2->Text + "the end";

In C# this is no problem, but in C++ I get all kinds of errors.
Any advice on how to handle this, would be much appreciated.

It would help if you would actually post the compiler errors. My crystal
ball is in for repairs at the moment.

But I can still give you the following hints:

1) string in C++ is used for the STL string class. What you call string in
C# is actually System::String in C++/CLI. This is guaranteed to cause at
least some part of your problems.

2) C++ can handle both ASCII and UNICODE strings.
"Hello" is ASCII, L"Hello" is unicode. Try prefixing your string literals
with L

--

Kind regards,
Bruno.
(e-mail address removed)
Remove only "_nos_pam"
 
Bruno van Dooren said:
It would help if you would actually post the compiler errors. My crystal
ball is in for repairs at the moment.

But I can still give you the following hints:

1) string in C++ is used for the STL string class. What you call string in
C# is actually System::String in C++/CLI. This is guaranteed to cause at
least some part of your problems.

2) C++ can handle both ASCII and UNICODE strings.
"Hello" is ASCII, L"Hello" is unicode. Try prefixing your string literals
with L

Kind regards,
Bruno.

I was more after how you actually handle combined strings in C++, not the
actual compiler errors.
But lets say I use std::string, which resembles "string" in C# and I do:

std::string baseStr = "<Hello>";
textKeyFile->Text = baseStr.c_str() + textCustomerName->Text;

then you get a "Cannot add two pointers" error, because both are pointers
obviously. Or if you do:

std::string baseStr = "<Hello>";
textKeyFile->Text = baseStr + textCustomerName->Text;

you get other errors since the two string are different types.

So I guess what I'm asking is, what type of C++ string should all strings be
converted to before I start adding them all together?

/Kim
 
Kim said:
I was more after how you actually handle combined strings in C++, not the
actual compiler errors.
Yep, but the compiler errors would help us understand your problem!!
But lets say I use std::string, which resembles "string" in C#

No it doesn't! std::string is native code, ansi string (not Unicode)
and has an API that is quite different from System::String. If you want
to deal with WinForms (and therefore maanged code) stick with
System::String^.
and I do:
std::string baseStr = "<Hello>";
textKeyFile->Text = baseStr.c_str() + textCustomerName->Text;

then you get a "Cannot add two pointers" error, because both are pointers
obviously.

There are 2 errors here :
- the c_str() member function return a const char*. From there, you're
into the realm of native pointers, and pointer arithmetic will replace
"usual" string concatenation semantic.
- What is textCustomerName? I suspect this is a .NET object, and
therefore textCustomerName->Text is a System::String. You cannot
"simply" concatenate a std::string and a System::String^ !!
Try this instead:

System::String^ baseStr = "<Hello>"; //build a maanged string
textKeyFile->Text = baseStr + textCustomerName->Text; //exactly the
same as in C#!

Arnaud
MVP - VC
 
Kim said:
I was more after how you actually handle combined strings in C++, not the
actual compiler errors.
Yep, but the compiler errors would help us understand your problem!!
But lets say I use std::string, which resembles "string" in C#

No it doesn't! std::string is native code, ansi string (not Unicode)
and has an API that is quite different from System::String. If you want
to deal with WinForms (and therefore maanged code) stick with
System::String^.
and I do:
std::string baseStr = "<Hello>";
textKeyFile->Text = baseStr.c_str() + textCustomerName->Text;

then you get a "Cannot add two pointers" error, because both are pointers
obviously.

There are 2 errors here :
- the c_str() member function return a const char*. From there, you're
into the realm of native pointers, and pointer arithmetic will replace
"usual" string concatenation semantic.
- What is textCustomerName? I suspect this is a .NET object, and
therefore textCustomerName->Text is a System::String. You cannot
"simply" concatenate a std::string and a System::String^ !!
Try this instead:

System::String^ baseStr = "<Hello>"; //build a managed string
textKeyFile->Text = baseStr + textCustomerName->Text; //exactly the
same as in C#!

Arnaud
MVP - VC
 
No it doesn't! std::string is native code, ansi string (not Unicode)
and has an API that is quite different from System::String.

I know they are completely different internally and have different methods.
I meant for simple use like adding strings and getting string length, they
resemble each other.
I tried:
System::String^ baseStr = "<Hello>"; //build a managed string
textKeyFile->Text = baseStr + textCustomerName->Text;
like you suggested, but I get the errors:

error C2065: 'baseStr' : undeclared identifier // From line 2
error C2143: syntax error : missing ';' before '^' // From line 1
error C2143: syntax error : missing ';' before '^' // From line 1

Any ideas?

Thanks,
Kim
 
Kim Hellan said:
I tried:
System::String^ baseStr = "<Hello>"; //build a managed string
textKeyFile->Text = baseStr + textCustomerName->Text;

// textKeyFile and textCustomerName assumed defined somewhere else
// textKeyFile->Text assumed to have type System::String^
// textCustomerName->Text assumed to have type System::String^

using namespace System;

String ^ baseStr = L"<Hello>";
textKeyFile->Text = String::Concat(baseStr, textCustomerName->Text);

Sean
 
Kim Hellan said:
I know they are completely different internally and have different
methods. I meant for simple use like adding strings and getting string
length, they resemble each other.
I tried:
System::String^ baseStr = "<Hello>"; //build a managed string
textKeyFile->Text = baseStr + textCustomerName->Text;
like you suggested, but I get the errors:

error C2065: 'baseStr' : undeclared identifier // From line 2
error C2143: syntax error : missing ';' before '^' // From line 1
error C2143: syntax error : missing ';' before '^' // From line 1
I forgot "using namespace System".

Are you building C++/CLI (with Visual 2005) or Managed C++ (with Visual
2003) ?

Arnaud
MVP - VC
 
I'm using Managed C++ in VS 2003.
When creating the WinForm project the following was automatically added at
the top of the code file:
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

But I still get the
error C2065: 'baseStr' : undeclared identifier

The textKeyFile and textCustomerName are TextBox controls on my form.

If you think C++ development has gotten a lot better in VS 2005, let me
know, since I also got the possibility to use that if I really need to.

Thanks,
Kim
 
Kim H said:
I'm using Managed C++ in VS 2003.

Oh, well in that case, my previous answer isn't going to work. The ^ syntax
is part of C++/CLI, which requires VS 2005.

I think you need something like:

using namespace System;

If you think C++ development has gotten a lot better in VS 2005, let me
know, since I also got the possibility to use that if I really need to.

It is certainly a lot cleaner, although the code samples we've been
considering in this thread isn't really enough to highlight the differences.
FWIW, I found the Managed Extensions for C++ so ugly that I stuck with native
C++ until C++/CLI came around.

Sean
 
Kim H said:
I'm using Managed C++ in VS 2003.

Ok, the code I gave you is C++/CLI (with all the "^" instead of "*") and
therefore can be compiled only with VC 2005. For Managed C++ (Visual 2003),
you need to use the Concat method, as others have already pointed out.
If you think C++ development has gotten a lot better in VS 2005, let me
know, since I also got the possibility to use that if I really need to.
C++ targeting the .NET framework has indeed got much better in Visual 2005,
with C++/CLI replacing the ugly Managed C++ sytnax.

Arnaud
MVP - VC
 
Thank you, that helped.

One final question...
What is the "cleanest" way to get a System::String copied to a std::string
(or char* for that matter).

Thanks,
Kim
 
Kim H said:
Thank you, that helped.

One final question...
What is the "cleanest" way to get a System::String copied to a std::string
(or char* for that matter).

System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi, then copy
the result where you want and delete the buffer with FreeHGlobal.

It is not only the cleanest, it is also the only way ;-)

Arnaud
MVP - VC
 
Back
Top