Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How do I convert a char to an unsigned int?

Reply
Thread Tools

How do I convert a char to an unsigned int?

 
 
DeMarcus
Guest
Posts: n/a
 
      10-25-2010
Hi!

How do I convert a char or wchar_t to an int in a proper and portable way?

If I do this

char wickedChar = '';
unsigned int myInt = c;

then myInt is a very big number, it's the sign bit of wickedChar that
does that.

Maybe I could do something like

unsigned int myInt = (unsigned char)c;

but the problem is that this is a template so I don't know if it's going
to be a char or wchar_t (or even something else).

How can I convert the char (or wchar_t) to an unsigned int in a portable
way?


Thanks,
Daniel
 
Reply With Quote
 
 
 
 
DeMarcus
Guest
Posts: n/a
 
      10-25-2010
On 10/25/2010 01:05 PM, Sam wrote:
> DeMarcus writes:
>
>> Hi!
>>
>> How do I convert a char or wchar_t to an int in a proper and portable
>> way?
>>
>> If I do this
>>
>> char wickedChar = '';
>> unsigned int myInt = c;
>>
>> then myInt is a very big number, it's the sign bit of wickedChar that
>> does that.
>>
>> Maybe I could do something like
>>
>> unsigned int myInt = (unsigned char)c;
>>
>> but the problem is that this is a template so I don't know if it's
>> going to be a char or wchar_t (or even something else).

>
> If that's your concern, provide the appropriate specializations for your
> template.
>


Basically it's something like this.

#ifdef SOME_FLAG
typedef boost::match_results<string::const_iterator> MyMatch;
#else
typedef boost::match_results<wstring::const_iterator> MyMatch;
#endif

// More about boost::match_results can be found here.
// http://www.cs.brown.edu/~jwicks/boos...h_results.html


void fnc( const MyMatch& match )
{
unsigned int charToInt = match[0].str()[0];
// ...
}

I did like this, which compiles and seems to work...

void fnc( const MyMatch& match )
{
unsigned int charToInt =
(unsigned MyMatch::char_type)match[0].str()[0];
// ...
}

.... but is it proper and portable C++ to cast like that?




 
Reply With Quote
 
 
 
 
Alf P. Steinbach /Usenet
Guest
Posts: n/a
 
      10-25-2010
* DeMarcus, on 25.10.2010 13:36:
> On 10/25/2010 01:05 PM, Sam wrote:
>> DeMarcus writes:
>>
>>> Hi!
>>>
>>> How do I convert a char or wchar_t to an int in a proper and portable
>>> way?
>>>
>>> If I do this
>>>
>>> char wickedChar = '';
>>> unsigned int myInt = c;
>>>
>>> then myInt is a very big number, it's the sign bit of wickedChar that
>>> does that.
>>>
>>> Maybe I could do something like
>>>
>>> unsigned int myInt = (unsigned char)c;
>>>
>>> but the problem is that this is a template so I don't know if it's
>>> going to be a char or wchar_t (or even something else).

>>
>> If that's your concern, provide the appropriate specializations for your
>> template.
>>

>
> Basically it's something like this.
>
> #ifdef SOME_FLAG
> typedef boost::match_results<string::const_iterator> MyMatch;
> #else
> typedef boost::match_results<wstring::const_iterator> MyMatch;
> #endif
>
> // More about boost::match_results can be found here.
> // http://www.cs.brown.edu/~jwicks/boos...h_results.html
>
>
> void fnc( const MyMatch& match )
> {
> unsigned int charToInt = match[0].str()[0];
> // ...
> }
>
> I did like this, which compiles and seems to work...
>
> void fnc( const MyMatch& match )
> {
> unsigned int charToInt =
> (unsigned MyMatch::char_type)match[0].str()[0];
> // ...
> }
>
> ... but is it proper and portable C++ to cast like that?


At first sight this seems like meaningless technobabble.

"#ifdef" can't be used to decide on template specialization, "unsigned" can't be
used to alter a named type, and I haven't heard of boost:match_results.

But perhaps you could explain what you're doing and present some /valid/ code?


Cheers,

- Alf

--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      10-25-2010
DeMarcus wrote:

>
> void fnc( const MyMatch& match )
> {
> unsigned int charToInt = match[0].str()[0];
> // ...
> }
>
> I did like this, which compiles and seems to work...
>
> void fnc( const MyMatch& match )
> {
> unsigned int charToInt =
> (unsigned MyMatch::char_type)match[0].str()[0];
> // ...
> }
>
> ... but is it proper and portable C++ to cast like that?


No, it's not!

Why don't you define a separate function ToInt, and overload that for
the character types you need?


Bo Persson


 
Reply With Quote
 
DeMarcus
Guest
Posts: n/a
 
      10-26-2010
On 10/25/2010 07:31 PM, Bo Persson wrote:
> DeMarcus wrote:
>
>>
>> void fnc( const MyMatch& match )
>> {
>> unsigned int charToInt = match[0].str()[0];
>> // ...
>> }
>>
>> I did like this, which compiles and seems to work...
>>
>> void fnc( const MyMatch& match )
>> {
>> unsigned int charToInt =
>> (unsigned MyMatch::char_type)match[0].str()[0];
>> // ...
>> }
>>
>> ... but is it proper and portable C++ to cast like that?

>
> No, it's not!
>
> Why don't you define a separate function ToInt, and overload that for
> the character types you need?
>
>
> Bo Persson
>
>


You mean something like this?

unsigned int ToInt( char c )
{
unsigned int i = (unsigned char)c;
return i;
}

unsigned int ToInt( wchar_t c )
{
unsigned int i = (unsigned wchar_t)c;
return i;
}

 
Reply With Quote
 
DeMarcus
Guest
Posts: n/a
 
      10-26-2010
On 10/25/2010 06:04 PM, Alf P. Steinbach /Usenet wrote:
> * DeMarcus, on 25.10.2010 13:36:
>> On 10/25/2010 01:05 PM, Sam wrote:
>>> DeMarcus writes:
>>>
>>>> Hi!
>>>>
>>>> How do I convert a char or wchar_t to an int in a proper and portable
>>>> way?
>>>>
>>>> If I do this
>>>>
>>>> char wickedChar = '';
>>>> unsigned int myInt = c;
>>>>
>>>> then myInt is a very big number, it's the sign bit of wickedChar that
>>>> does that.
>>>>
>>>> Maybe I could do something like
>>>>
>>>> unsigned int myInt = (unsigned char)c;
>>>>
>>>> but the problem is that this is a template so I don't know if it's
>>>> going to be a char or wchar_t (or even something else).
>>>
>>> If that's your concern, provide the appropriate specializations for your
>>> template.
>>>

>>
>> Basically it's something like this.
>>
>> #ifdef SOME_FLAG
>> typedef boost::match_results<string::const_iterator> MyMatch;
>> #else
>> typedef boost::match_results<wstring::const_iterator> MyMatch;
>> #endif
>>
>> // More about boost::match_results can be found here.
>> //
>> http://www.cs.brown.edu/~jwicks/boos...h_results.html
>>
>>
>> void fnc( const MyMatch& match )
>> {
>> unsigned int charToInt = match[0].str()[0];
>> // ...
>> }
>>
>> I did like this, which compiles and seems to work...
>>
>> void fnc( const MyMatch& match )
>> {
>> unsigned int charToInt =
>> (unsigned MyMatch::char_type)match[0].str()[0];
>> // ...
>> }
>>
>> ... but is it proper and portable C++ to cast like that?

>
> At first sight this seems like meaningless technobabble.
>
> "#ifdef" can't be used to decide on template specialization, "unsigned"
> can't be used to alter a named type, and I haven't heard of
> boost:match_results.
>
> But perhaps you could explain what you're doing and present some /valid/
> code?
>
>
> Cheers,
>
> - Alf
>



#include <iostream>

typedef char MySignedChar;

int main()
{
MySignedChar c = 200;

// When doing this I get a very big number.
unsigned int i = c;

std::cout << "Char to int: " << i << std::endl;

// When doing this I get the number I want.
unsigned int i2 = (unsigned MySignedChar)c;

std::cout << "Char to int again: " << i2 << std::endl;

return 0;
}


The boost::match_results can be found here.
http://www.cs.brown.edu/~jwicks/boos...h_results.html

I'm using it like this.

wstring myFormat( const boost::wsmatch& what )
{
uint32 charToInt = (unsigned wsmatch::char_type)what[0].str()[0];
std::cout << charToInt << std::endl;

// ... create replacement ...
return replacement;
}

wstring encode( const wstring& text )
{
const boost::wregex expression( "[^a-zA-Z0-9]" );

return boost::regex_replace( text, expression, myFormat );
}

If there's a better way to do search-and-replace, preferably with
something C++0x compliant, I'm interested in that.



 
Reply With Quote
 
Alf P. Steinbach /Usenet
Guest
Posts: n/a
 
      10-26-2010
* DeMarcus, on 26.10.2010 09:27:
> On 10/25/2010 06:04 PM, Alf P. Steinbach /Usenet wrote:
>> * DeMarcus, on 25.10.2010 13:36:
>>> On 10/25/2010 01:05 PM, Sam wrote:
>>>> DeMarcus writes:
>>>>
>>>>> Hi!
>>>>>
>>>>> How do I convert a char or wchar_t to an int in a proper and portable
>>>>> way?
>>>>>
>>>>> If I do this
>>>>>
>>>>> char wickedChar = '';
>>>>> unsigned int myInt = c;
>>>>>
>>>>> then myInt is a very big number, it's the sign bit of wickedChar that
>>>>> does that.
>>>>>
>>>>> Maybe I could do something like
>>>>>
>>>>> unsigned int myInt = (unsigned char)c;
>>>>>
>>>>> but the problem is that this is a template so I don't know if it's
>>>>> going to be a char or wchar_t (or even something else).
>>>>
>>>> If that's your concern, provide the appropriate specializations for your
>>>> template.
>>>>
>>>
>>> Basically it's something like this.
>>>
>>> #ifdef SOME_FLAG
>>> typedef boost::match_results<string::const_iterator> MyMatch;
>>> #else
>>> typedef boost::match_results<wstring::const_iterator> MyMatch;
>>> #endif
>>>
>>> // More about boost::match_results can be found here.
>>> //
>>> http://www.cs.brown.edu/~jwicks/boos...h_results.html
>>>
>>>
>>> void fnc( const MyMatch& match )
>>> {
>>> unsigned int charToInt = match[0].str()[0];
>>> // ...
>>> }
>>>
>>> I did like this, which compiles and seems to work...
>>>
>>> void fnc( const MyMatch& match )
>>> {
>>> unsigned int charToInt =
>>> (unsigned MyMatch::char_type)match[0].str()[0];
>>> // ...
>>> }
>>>
>>> ... but is it proper and portable C++ to cast like that?

>>
>> At first sight this seems like meaningless technobabble.
>>
>> "#ifdef" can't be used to decide on template specialization, "unsigned"
>> can't be used to alter a named type, and I haven't heard of
>> boost:match_results.
>>
>> But perhaps you could explain what you're doing and present some /valid/
>> code?
>>
>>
>> Cheers,
>>
>> - Alf
>>

>
>
> #include <iostream>
>
> typedef char MySignedChar;
>
> int main()
> {
> MySignedChar c = 200;
>
> // When doing this I get a very big number.
> unsigned int i = c;
>
> std::cout << "Char to int: " << i << std::endl;
>
> // When doing this I get the number I want.
> unsigned int i2 = (unsigned MySignedChar)c;
>
> std::cout << "Char to int again: " << i2 << std::endl;
>
> return 0;
> }


Well, as I wrote, you cannot use "unsigned" to alter a named type.

g++ just warns about (perhaps one can instruct it to treat that warning as an
error), while msvc and Comeau diagnose it as error, as is proper:


<g++>
x.cpp: In function 'int main()':
x.cpp:7: warning: overflow in implicit constant conversion
x.cpp:15: warning: long, short, signed or unsigned used invalidly for 'type name'
<g++>

<msvc>
x.cpp
x.cpp(7) : warning C4309: 'initializing' : truncation of constant value
x.cpp(15) : error C2146: syntax error : missing ')' before identifier 'MySignedChar'
x.cpp(15) : error C2059: syntax error : ')'
x.cpp(15) : error C2275: 'MySignedChar' : illegal use of this type as an expression
x.cpp(3) : see declaration of 'MySignedChar'
x.cpp(15) : error C2146: syntax error : missing ';' before identifier 'c'
<msvc

<comeau>
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 7: warning: integer conversion resulted in a change of sign
MySignedChar c = 200;
^

"ComeauTest.c", line 15: error: expected a ")"
unsigned int i2 = (unsigned MySignedChar)c;
^

1 error detected in the compilation of "ComeauTest.c".
<comeau>


> The boost::match_results can be found here.
> http://www.cs.brown.edu/~jwicks/boos...h_results.html


OK, thanks.


> I'm using it like this.
>
> wstring myFormat( const boost::wsmatch& what )
> {
> uint32 charToInt = (unsigned wsmatch::char_type)what[0].str()[0];
> std::cout << charToInt << std::endl;
>
> // ... create replacement ...
> return replacement;
> }
>
> wstring encode( const wstring& text )
> {
> const boost::wregex expression( "[^a-zA-Z0-9]" );
>
> return boost::regex_replace( text, expression, myFormat );
> }
>
> If there's a better way to do search-and-replace, preferably with something
> C++0x compliant, I'm interested in that.


This latter question depends on your criterion for "better", and exactly what
you're doing.

However, for the conversion to "unsigned" consider


typedef unsigned char UChar;

inline unsigned asUnsigned( char c ) { return UChar( c ); }
inline unsigned asUnsigned( wchar_t c ) { return unsigned( c ); }

STATIC_ASSERT( sizeof( unsigned ) >= sizeof( wchar_t ) );

where STATIC_ASSERT might be e.g. BOOST_STATIC_ASSERT.


Cheers & hth.,

- Alf




--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
DeMarcus
Guest
Posts: n/a
 
      10-26-2010
On 10/26/2010 10:26 AM, Alf P. Steinbach /Usenet wrote:
> * DeMarcus, on 26.10.2010 09:27:
>> On 10/25/2010 06:04 PM, Alf P. Steinbach /Usenet wrote:
>>> * DeMarcus, on 25.10.2010 13:36:
>>>> On 10/25/2010 01:05 PM, Sam wrote:
>>>>> DeMarcus writes:
>>>>>
>>>>>> Hi!
>>>>>>
>>>>>> How do I convert a char or wchar_t to an int in a proper and portable
>>>>>> way?
>>>>>>
>>>>>> If I do this
>>>>>>
>>>>>> char wickedChar = '';
>>>>>> unsigned int myInt = c;
>>>>>>
>>>>>> then myInt is a very big number, it's the sign bit of wickedChar that
>>>>>> does that.
>>>>>>
>>>>>> Maybe I could do something like
>>>>>>
>>>>>> unsigned int myInt = (unsigned char)c;
>>>>>>
>>>>>> but the problem is that this is a template so I don't know if it's
>>>>>> going to be a char or wchar_t (or even something else).
>>>>>
>>>>> If that's your concern, provide the appropriate specializations for
>>>>> your
>>>>> template.
>>>>>
>>>>
>>>> Basically it's something like this.
>>>>
>>>> #ifdef SOME_FLAG
>>>> typedef boost::match_results<string::const_iterator> MyMatch;
>>>> #else
>>>> typedef boost::match_results<wstring::const_iterator> MyMatch;
>>>> #endif
>>>>
>>>> // More about boost::match_results can be found here.
>>>> //
>>>> http://www.cs.brown.edu/~jwicks/boos...h_results.html
>>>>
>>>>
>>>> void fnc( const MyMatch& match )
>>>> {
>>>> unsigned int charToInt = match[0].str()[0];
>>>> // ...
>>>> }
>>>>
>>>> I did like this, which compiles and seems to work...
>>>>
>>>> void fnc( const MyMatch& match )
>>>> {
>>>> unsigned int charToInt =
>>>> (unsigned MyMatch::char_type)match[0].str()[0];
>>>> // ...
>>>> }
>>>>
>>>> ... but is it proper and portable C++ to cast like that?
>>>
>>> At first sight this seems like meaningless technobabble.
>>>
>>> "#ifdef" can't be used to decide on template specialization, "unsigned"
>>> can't be used to alter a named type, and I haven't heard of
>>> boost:match_results.
>>>
>>> But perhaps you could explain what you're doing and present some /valid/
>>> code?
>>>
>>>
>>> Cheers,
>>>
>>> - Alf
>>>

>>
>>
>> #include <iostream>
>>
>> typedef char MySignedChar;
>>
>> int main()
>> {
>> MySignedChar c = 200;
>>
>> // When doing this I get a very big number.
>> unsigned int i = c;
>>
>> std::cout << "Char to int: " << i << std::endl;
>>
>> // When doing this I get the number I want.
>> unsigned int i2 = (unsigned MySignedChar)c;
>>
>> std::cout << "Char to int again: " << i2 << std::endl;
>>
>> return 0;
>> }

>
> Well, as I wrote, you cannot use "unsigned" to alter a named type.
>
> g++ just warns about (perhaps one can instruct it to treat that warning
> as an error), while msvc and Comeau diagnose it as error, as is proper:
>
>
> <g++>
> x.cpp: In function 'int main()':
> x.cpp:7: warning: overflow in implicit constant conversion
> x.cpp:15: warning: long, short, signed or unsigned used invalidly for
> 'type name'
> <g++>
>
> <msvc>
> x.cpp
> x.cpp(7) : warning C4309: 'initializing' : truncation of constant value
> x.cpp(15) : error C2146: syntax error : missing ')' before identifier
> 'MySignedChar'
> x.cpp(15) : error C2059: syntax error : ')'
> x.cpp(15) : error C2275: 'MySignedChar' : illegal use of this type as an
> expression
> x.cpp(3) : see declaration of 'MySignedChar'
> x.cpp(15) : error C2146: syntax error : missing ';' before identifier 'c'
> <msvc
>
> <comeau>
> Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
> Copyright 1988-2008 Comeau Computing. All rights reserved.
> MODE:strict errors C++ C++0x_extensions
>
> "ComeauTest.c", line 7: warning: integer conversion resulted in a change
> of sign
> MySignedChar c = 200;
> ^
>
> "ComeauTest.c", line 15: error: expected a ")"
> unsigned int i2 = (unsigned MySignedChar)c;
> ^
>
> 1 error detected in the compilation of "ComeauTest.c".
> <comeau>
>
>
>> The boost::match_results can be found here.
>> http://www.cs.brown.edu/~jwicks/boos...h_results.html

>
> OK, thanks.
>
>
>> I'm using it like this.
>>
>> wstring myFormat( const boost::wsmatch& what )
>> {
>> uint32 charToInt = (unsigned wsmatch::char_type)what[0].str()[0];
>> std::cout << charToInt << std::endl;
>>
>> // ... create replacement ...
>> return replacement;
>> }
>>
>> wstring encode( const wstring& text )
>> {
>> const boost::wregex expression( "[^a-zA-Z0-9]" );
>>
>> return boost::regex_replace( text, expression, myFormat );
>> }
>>
>> If there's a better way to do search-and-replace, preferably with
>> something
>> C++0x compliant, I'm interested in that.

>
> This latter question depends on your criterion for "better", and exactly
> what you're doing.
>


Basically I want to do search-and-replace, preferably using
std::tr1::regex. With "better" I mean something compliant to
std::tr1::regex since, as I understand (correct me if I'm wrong), there
are some things with boost::regex that won't go into std::tr1::regex.

I think it's some legacy thing called boost xpressive.

http://www.boost.org/doc/libs/1_40_0..._substitutions


> However, for the conversion to "unsigned" consider
>
>
> typedef unsigned char UChar;
>
> inline unsigned asUnsigned( char c ) { return UChar( c ); }
> inline unsigned asUnsigned( wchar_t c ) { return unsigned( c ); }
>
> STATIC_ASSERT( sizeof( unsigned ) >= sizeof( wchar_t ) );
>
> where STATIC_ASSERT might be e.g. BOOST_STATIC_ASSERT.
>
>
> Cheers & hth.,
>
> - Alf
>


Thanks!



 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      10-26-2010
DeMarcus wrote:
> On 10/25/2010 07:31 PM, Bo Persson wrote:
>> DeMarcus wrote:
>>
>>>
>>> void fnc( const MyMatch& match )
>>> {
>>> unsigned int charToInt = match[0].str()[0];
>>> // ...
>>> }
>>>
>>> I did like this, which compiles and seems to work...
>>>
>>> void fnc( const MyMatch& match )
>>> {
>>> unsigned int charToInt =
>>> (unsigned MyMatch::char_type)match[0].str()[0];
>>> // ...
>>> }
>>>
>>> ... but is it proper and portable C++ to cast like that?

>>
>> No, it's not!
>>
>> Why don't you define a separate function ToInt, and overload that
>> for the character types you need?
>>
>>
>> Bo Persson
>>
>>

>
> You mean something like this?
>
> unsigned int ToInt( char c )
> {
> unsigned int i = (unsigned char)c;
> return i;
> }
>
> unsigned int ToInt( wchar_t c )
> {
> unsigned int i = (unsigned wchar_t)c;
> return i;
> }


Yes, except that wchar_t already is unsigned (and that you cannot add
or remove signedness - it really should have been unsigned_char to be
regular and avoid keywords that look like two words).


Bo Persson


 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      10-26-2010
Pete Becker wrote:
> On 2010-10-26 13:22:22 -0400, Bo Persson said:
>
>>
>> Yes, except that wchar_t already is unsigned (and that you cannot
>> add or remove signedness - it really should have been
>> unsigned_char to be regular and avoid keywords that look like two
>> words).

>
> wchar_t does not have to be unsigned. It has to have "[t]he same
> size, signedness, and alignment requirements as one of the other
> integral types...".


Right. I just haven't seen a case where it was signed.

And you still cannot ask for an unsigned version, even if it is
signed.


Bo Persson


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Casting from const pair<const unsigned char*, size_t>* to constpair<unsigned char*, size_t>* Alex Vinokur C++ 9 10-13-2008 05:05 PM
Padding bits and char, unsigned char, signed char Ioannis Vranos C++ 11 03-28-2008 10:47 PM
Linking error LNK2001 - "__declspec(dllimport) private: void __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Tidy(unsigned short)" (__imp_?_Tidy@?$basic_string@DU?$char_ sharmadeep1980@gmail.com C++ 1 07-07-2006 07:27 AM
void*, char*, unsigned char*, signed char* Steffen Fiksdal C Programming 1 05-09-2005 02:33 AM



Advertisments