Problems working with strings in MC++

  • Thread starter Thread starter John E Katich
  • Start date Start date
J

John E Katich

Being an old MFC guy, I'm having a heck of a time working with MC++. Can
anybody tell me why the following code outputs 65 instead of an A. And yes
I know 65 is the hex value for A, but why is it getting converted? And how
to I get an A to be outputted?


char c = 'A';
StringBuilder *s = new StringBuilder;
s->Append(c);
Console::WriteLine(s);

Thanks
JEK
 
John said:
Being an old MFC guy, I'm having a heck of a time working with MC++. Can
anybody tell me why the following code outputs 65 instead of an
A. And yes I know 65 is the hex value for A, but why is it getting
converted? And how to I get an A to be outputted?


char c = 'A';
StringBuilder *s = new StringBuilder;
s->Append(c);
Console::WriteLine(s);

Because char maps to System.UInt8, not System.Char.

Try

wchar_t c = L'A';
StringBuilder *s = new StringBuilder;
s->Append(c);
Console::WriteLine(s);

-cd
 
Carl Daniel said:
Because char maps to System.UInt8, not System.Char.

Try

wchar_t c = L'A';
StringBuilder *s = new StringBuilder;
s->Append(c);
Console::WriteLine(s);

-cd

Sorry Carl, No help;

This is a simple fragment of the real sitiuation. The <char c> is really
being returned from a COM object, therefore it cannot be defined as anything
other than a char. BTW, your code also yields 65.

JEK
 

Considering that ordinary C++ predates MFC (though the C++ standard
doesn't), some of us who saw C++ learn how to choose overloads depending on
char vs. int also wonder why MC++ lacks that ability. Anyway...

Decimal. Hex is 0x41.
Because char maps to System.UInt8, not System.Char.

Last I saw, char maps to System.Int8 or System.Byte or something like that.
Of course C programmers have to take care not to depend on whether char's
values are signed or unsigned, but MC++ programmers often have to find out
which MC++ type is actually being used.
Try

wchar_t c = L'A';
StringBuilder *s = new StringBuilder;
s->Append(c);
Console::WriteLine(s);

wchar_t maps onto System.UInt16.

Try:

char c = 'A'; // or wchar_t c = L'A'; /// or _TCHAR c = _T('A');
StringBuilder *s = new StringBuilder;
s->Append(Char(c));
Console::WriteLine(s);

I'm not actually sure if this will work. Char('A') worked for me but I
didn't try it with a variable. Char('\0') has a minor bug but works OK at
execution time.
 
Norman Diamond said:
Considering that ordinary C++ predates MFC (though the C++ standard
doesn't), some of us who saw C++ learn how to choose overloads depending
on char vs. int also wonder why MC++ lacks that ability. Anyway...

Decimal. Hex is 0x41.


Last I saw, char maps to System.Int8 or System.Byte or something like
that. Of course C programmers have to take care not to depend on whether
char's values are signed or unsigned, but MC++ programmers often have to
find out which MC++ type is actually being used.


wchar_t maps onto System.UInt16.

Try:

char c = 'A'; // or wchar_t c = L'A'; /// or _TCHAR c = _T('A');
StringBuilder *s = new StringBuilder;
s->Append(Char(c));
Console::WriteLine(s);

I'm not actually sure if this will work. Char('A') worked for me but I
didn't try it with a variable. Char('\0') has a minor bug but works OK at
execution time.
Hi Norman,

Char c = 'A' instead of char = 'A' works...

Thanks

JEK
 
Hi Carl,
Because char maps to System.UInt8, not System.Char.

Try

wchar_t c = L'A';
StringBuilder *s = new StringBuilder;
s->Append(c);
Console::WriteLine(s);

Last I remember, that will only work if compiling with /Zc:wchar_t, because
otherwise, wchar_t maps to UInt16 :)
 
Tomas said:
Hi Carl,


Last I remember, that will only work if compiling with /Zc:wchar_t,
because otherwise, wchar_t maps to UInt16 :)

No doubt. I take it for granted since /Zc:wchar_t is the default in VC
2005.

-cd
 
John said:
Thanks Jeff, that's the answer..

Use Char c = 'A' instead char c = 'A'..

What's interesting is char c = 'A' works in C#

char is a keyword in both C++ and C#. In C++, char is defined as a single
byte (the smallest addressible unit of storage). In .NET, this maps to
System.UInt8, while in C#, char is defined as the "platform character type",
or System.Char.

Char, on the other hand, is not a keyword/built-in, but the name of a value
type in the System namespace, so it has the same meaning in both languages.

The solution of declaring variables of type Char won't help your case of
getting character data from a COM object or other legacy code that's
returning character strings using the C/C++ char type. You can get away
with a cast to convert a single char to Char, but to convert strings, you'll
want to use the functions in the System.Runtime.InteropServices.Marshal
class. Specifically, you might want to read up on:

StringToHGlobalAnsi
StringToHGlobalUni
StringToHGlobalAuto
StringToBSTR
PtrToStringAuto
PtrToStringAnsi
PtrToStringUni
PtrToStringBSTR

-cd
 
Carl Daniel said:
char is a keyword in both C++ and C#. In C++, char is defined as a single
byte (the smallest addressible unit of storage). In .NET, this maps to
System.UInt8, while in C#, char is defined as the "platform character
type", or System.Char.

Char, on the other hand, is not a keyword/built-in, but the name of a
value type in the System namespace, so it has the same meaning in both
languages.

The solution of declaring variables of type Char won't help your case of
getting character data from a COM object or other legacy code that's
returning character strings using the C/C++ char type. You can get away
with a cast to convert a single char to Char, but to convert strings,
you'll want to use the functions in the
System.Runtime.InteropServices.Marshal class. Specifically, you might
want to read up on:

StringToHGlobalAnsi
StringToHGlobalUni
StringToHGlobalAuto
StringToBSTR
PtrToStringAuto
PtrToStringAnsi
PtrToStringUni
PtrToStringBSTR

-cd

What about a struct and a pointer to a struct that is returned by a COM
object. What is the best handle them in manaaged code?

JEK
 
John said:
What about a struct and a pointer to a struct that is returned by a
COM object. What is the best handle them in manaaged code?

One of the great advantages of MC++ is that you can just use unmanaged types
freely.

If you need to pass a native struct to a framework library, or some other
existing IL code (i.e. not MC++ code that you're writing), then you either
need to define a managed equivalent and copy the struct over member by
member (possibly doing string conversions on the way), or you may be able to
define a managed struct that's layout compatible with the unmanaged struct
by using explicit layout attributes on the managed struct.

-cd
 
Back
Top