a char and unsigned char question again 
Author Message
 a char and unsigned char question again

Hi.

How do I convert a value of type unsigned char (that comes from getchar,
for example), to char? Simply casting or assigning might cause an
implementation-defined signal to be raised if the value is outside the
range and char is signed. So what can I do?

Martin



Wed, 15 Dec 2004 17:51:09 GMT  
 a char and unsigned char question again

Quote:

> Hi.

> How do I convert a value of type unsigned char
> (that comes from getchar, for example), to char?
> Simply casting or assigning might cause an
> implementation-defined signal to be raised if the value is outside the
> range and char is signed. So what can I do?

getchar returns int.
EOF is the only value returned by getchar that I'm aware of
which is outside the range of char.

--
 pete



Wed, 15 Dec 2004 19:09:55 GMT  
 a char and unsigned char question again

Quote:
> Hi.

> How do I convert a value of type unsigned char (that comes from getchar,
> for example), to char? Simply casting or assigning might cause an
> implementation-defined signal to be raised if the value is outside the
> range and char is signed. So what can I do?

getchar() returns an int. If you're absolutely paranoid about assigning the
value to a plain char, then compare the value to CHAR_MIN and the smaller of
INT_MAX and CHAR_MAX.

--
Peter



Wed, 15 Dec 2004 19:37:02 GMT  
 a char and unsigned char question again


Quote:
>Hi.

>How do I convert a value of type unsigned char (that comes from getchar,
>for example), to char? Simply casting or assigning might cause an
>implementation-defined signal to be raised if the value is outside the
>range and char is signed. So what can I do?

It is one of those things that in practice you simply don't worry about.
There would be too much pain in a C implementation that generated
a signal when converting values to char, I'm not aware of any useful
implementations like this that exist and nor are they likely to. There's
far too much code around that would be broken, e.g. things like

    char str[10];
    int ch;

    if ((ch = getchar()) != EOF)
         str[0] = ch;
    ...

It is good to try to write code as standard as possible but some things
just aren't worth it.

--
-----------------------------------------


-----------------------------------------



Wed, 15 Dec 2004 19:33:08 GMT  
 a char and unsigned char question again

Quote:



>> Hi.

>> How do I convert a value of type unsigned char (that comes from getchar,
>> for example), to char? Simply casting or assigning might cause an
>> implementation-defined signal to be raised if the value is outside the
>> range and char is signed. So what can I do?

> getchar() returns an int. If you're absolutely paranoid about assigning
> the value to a plain char, then compare the value to CHAR_MIN and the
> smaller of INT_MAX and CHAR_MAX.

But if the value is outside this range, what can I do? For example, if
I want to append the character to a string and I don't want to discard
characters whose value is greater than CHAR_MAX. I somehow have to
convert the values to the correct negative value (given char is signed).
But there seems to be no way to do this correctly. Does that mean I'm
forced to use unsigned char strings throughout my program? That would
be bad because many library functions expect char strings, not unsigned
char strings.

Martin



Wed, 15 Dec 2004 20:17:41 GMT  
 a char and unsigned char question again

Quote:



>>Hi.

>>How do I convert a value of type unsigned char (that comes from getchar,
>>for example), to char? Simply casting or assigning might cause an
>>implementation-defined signal to be raised if the value is outside the
>>range and char is signed. So what can I do?

> It is one of those things that in practice you simply don't worry about.
> There would be too much pain in a C implementation that generated
> a signal when converting values to char, I'm not aware of any useful
> implementations like this that exist and nor are they likely to. There's
> far too much code around that would be broken, e.g. things like

>     char str[10];
>     int ch;

>     if ((ch = getchar()) != EOF)
>          str[0] = ch;
>     ...

I had something like that in mind. It is not strictly conforming.
You could change str to unsigned char[10], but then you can't even use
strlen(str), for example.

Quote:
> It is good to try to write code as standard as possible but some things
> just aren't worth it.

It must be possible to write correct code without worrying so much;
it seems strange why that is apparently impossible here...

Martin



Wed, 15 Dec 2004 20:26:50 GMT  
 a char and unsigned char question again

Quote:


>> Hi.

>> How do I convert a value of type unsigned char
>> (that comes from getchar, for example), to char?
>> Simply casting or assigning might cause an
>> implementation-defined signal to be raised if the value is outside the
>> range and char is signed. So what can I do?

> getchar returns int.

Yes, but unless the value is EOF, it is an unsigned char value
cast to int. (I admit that my phrase "comes from getchar" was
not precise.)

Quote:
> EOF is the only value returned by getchar that I'm aware of
> which is outside the range of char.

On my system, char ranges from -128 to +127.
But getchar returns EOF or values from 0 to 255.


Wed, 15 Dec 2004 20:37:19 GMT  
 a char and unsigned char question again

Quote:

> But if the value is outside this range, what can I do? For
> example, if I want to append the character to a string and
> I don't want to discard characters whose value is greater
> than CHAR_MAX. I somehow have to convert the values to the
> correct negative value (given char is signed). But there
> seems to be no way to do this correctly. Does that mean I'm
> forced to use unsigned char strings throughout my program?
> That would be bad because many library functions expect
> char strings, not unsigned char strings.

Perhaps you could apply the sort of logic that I used in this function:

void toupperstr(char *s)
{
  for(;*s;s++)
  {
    int c = toupper((unsigned char)*s);
    if(c > CHAR_MAX) c -= UCHAR_MAX + 1;
    *s = c;
  }

Quote:
}

I'm not really sure whether my "if" line is strictly conforming; I suppose
it's possible that UCHAR_MAX+1 overflows.

--
Simon.



Wed, 15 Dec 2004 21:24:07 GMT  
 a char and unsigned char question again
On Sat, 29 Jun 2002 14:26:50 +0200, Martin F. said:

Quote:

>>>How do I convert a value of type unsigned char (that comes from getchar,
>>>for example), to char?

>>     char str[10];
>>     int ch;

>>     if ((ch = getchar()) != EOF)
>>          str[0] = ch;

> I had something like that in mind. It is not strictly conforming.

Yes it is. You're worrying about something that could only happen
if getchar() returns a value outside the range of int. And it's
well defined to be a value which can be stored in a char if the
call doesn't return EOF.

Quote:
> You could change str to unsigned char[10], but then you can't even use
> strlen(str), for example.

You don't need to , but you could, change char to unsigned char.
And if you did, you could still use strlen() et al.

Quote:
>> It is good to try to write code as standard as possible but some things
>> just aren't worth it.

> It must be possible to write correct code without worrying so much;
> it seems strange why that is apparently impossible here...

This is, to my mind, correct code, unless someone wrote a messed
up version of getchar() which could return values outside the
range INT_MIN...UCHAR_MAX.

Dave.

--
           David Neary,
     E-Mail: bolsh at gimp dot org
CV: http://www.redbrick.dcu.ie/~bolsh/CV/CV.html



Wed, 15 Dec 2004 22:01:48 GMT  
 a char and unsigned char question again
Martin F. said:

Quote:
> > I had something like that in mind. It is not strictly
> > conforming.

Dave Neary replied:

Quote:
> Yes it is. You're worrying about something that could
> only happen if getchar() returns a value outside the
> range of int.

getchar returns int, it's patently impossible for the value to be outside
the range of int. It is however far more likely for the value to be outside
the range of char, which is the problem here.

Quote:
> And it's well defined to be a value which can be stored
> in a char if the call doesn't return EOF.

Where is it defined as such? Chapter and verse, please.

7.19.7.1 The fgetc function
"the fgetc function obtains that character as an unsigned char converted to
an int"

The range of unsigned char converted to an int is often outside that of a
signed char.

Quote:
> You don't need to , but you could, change char to
> unsigned char. And if you did, you could still use
> strlen() et al.

If he did change char to unsigned char, then the pointer would not be
suitable for passing to the strlen function.

Quote:
> This is, to my mind, correct code, unless someone
> wrote a messed up version of getchar() which could
> return values outside the range INT_MIN...UCHAR_MAX.

You are right that a correct getchar function cannot return values outside
the range INT_MIN...UCHAR_MAX. But the problem is for part of that range:
namely that between CHAR_MAX and UCHAR_MAX.

--
Simon.



Wed, 15 Dec 2004 22:29:24 GMT  
 a char and unsigned char question again

Quote:


>> But if the value is outside this range, what can I do? For
>> example, if I want to append the character to a string and
>> I don't want to discard characters whose value is greater
>> than CHAR_MAX. I somehow have to convert the values to the
>> correct negative value (given char is signed). But there
>> seems to be no way to do this correctly. Does that mean I'm
>> forced to use unsigned char strings throughout my program?
>> That would be bad because many library functions expect
>> char strings, not unsigned char strings.

> Perhaps you could apply the sort of logic that I used in this function:

> void toupperstr(char *s)
> {
>   for(;*s;s++)
>   {
>     int c = toupper((unsigned char)*s);
>     if(c > CHAR_MAX) c -= UCHAR_MAX + 1;
>     *s = c;
>   }
> }

> I'm not really sure whether my "if" line is strictly conforming; I suppose
> it's possible that UCHAR_MAX+1 overflows.

That is a solution to my problem. I think it is safe unless UCHAR_MAX ==
INT_MAX. I suggest rewriting the "if" line this way:
    if (c > CHAR_MAX) c = c - UCHAR_MAX - 1;

This all is annoying and wastes CPU time. Why isn't plain char just
the same as unsigned char...

Martin



Wed, 15 Dec 2004 23:19:50 GMT  
 a char and unsigned char question again
On Sun, 30 Jun 2002 00:29:24 +1000, Simon Biber said:

Quote:
> Dave Neary replied:
>> [The value returned by getchar() is] well defined to be a
>> value which can be stored in a char if the call doesn't
>> return EOF.

> Where is it defined as such? Chapter and verse, please.

> 7.19.7.1 The fgetc function
> "the fgetc function obtains that character as an unsigned char converted to
> an int"

> The range of unsigned char converted to an int is often outside that of a
> signed char.

Hmmm... yes, you're correct, of course. I don't know what I was
thinking. We can do this, though... can't we?

int i;
unsigned char uc;
char ch;

if((i = getchar())!=EOF)
{
#if defined ( TRY1 )
  uc = i;
  ch = uc;
#elif defined ( TRY2 )
  ch = (unsigned char)i;
#endif

Quote:
}

Or is assigning an unsigned char to a char forbidden?

Quote:
>> You don't need to , but you could, change char to
>> unsigned char. And if you did, you could still use
>> strlen() et al.

> If he did change char to unsigned char, then the pointer would not be
> suitable for passing to the strlen function.

Again, I was hasty, & wrong :)

Thanks for the corrections.

Dave.

--
           David Neary,
     E-Mail: bolsh at gimp dot org
CV: http://www.redbrick.dcu.ie/~bolsh/CV/CV.html



Wed, 15 Dec 2004 23:24:50 GMT  
 a char and unsigned char question again

Quote:

> We can do this, though... can't we?

> int i;
> unsigned char uc;
> char ch;

> if((i = getchar())!=EOF)
> {
> #if defined ( TRY1 )
>   uc = i;

This conversion is OK.

Quote:
>   ch = uc;
> #elif defined ( TRY2 )
>   ch = (unsigned char)i;

These two both are problematic.

Quote:
> #endif
> }

> Or is assigning an unsigned char to a char forbidden?

Assigning an unsigned char to a char involves a conversion, just as in the
int to char case. If char is signed, and the value is greater then
CHAR_MAX, then you have exactly the same problem.

--
Simon.



Wed, 15 Dec 2004 23:57:53 GMT  
 a char and unsigned char question again

Quote:


(snip)

>> Perhaps you could apply the sort of logic that I used in this function:

>> void toupperstr(char *s)
>> {
>>   for(;*s;s++)
>>   {
>>     int c = toupper((unsigned char)*s);
>>     if(c > CHAR_MAX) c -= UCHAR_MAX + 1;
>>     *s = c;
>>   }
>> }

>> I'm not really sure whether my "if" line is strictly conforming; I
>> suppose it's possible that UCHAR_MAX+1 overflows.

> That is a solution to my problem. I think it is safe unless UCHAR_MAX ==
> INT_MAX. I suggest rewriting the "if" line this way:
>     if (c > CHAR_MAX) c = c - UCHAR_MAX - 1;

Or even:
    if (c > CHAR_MAX) c = -(int)(unsigned char)-c;


Fri, 17 Dec 2004 04:20:59 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Sorting a Huge Unicode File use strcmp(unsigned char *, unsigned char *)

2. Sorting a Huge Unicode File use strcmp(unsigned char *, unsigned char *)

3. Sorting a Huge Unicode File use strcmp(unsigned char *, unsigned char *)

4. char, unsigned char, signed char

5. bytes to unsigned char, unsigned short, unsigned int, ...

6. NewBie: difference between char* and unsigned char*

7. copying unsigned long into char[4] or char*

8. Char* array to Unsigned Char*

9. unsigned char * typecasting to char *

10. Difference between char and unsigned char

11. converting const char* to unsigned char[1024]

12. COM with ATL - char * vs unsigned char *

 

 
Powered by phpBB® Forum Software