convert char to short int via pointer?... 
Author Message
 convert char to short int via pointer?...

I got the following problem:

unsigned char * ptr;
short int value;

ptr = ...; /* Points to an array of raw data. */

value = (short int)*ptr;

Value is supposed to contain a short int constructed from *ptr plus
*ptr+1 in signed little endian format.

Does this work? And if not, how could it work?

Thanks,

Guido


--
      ////
    0(o o)0
-oOO--(_)--OOo--------------------------------------------------------
                 University of Bonn, Germany

        Tesch    URL:     http://www.*-*-*.com/ ~tesch
   oooO          Presently working at GMD, Sankt Augustin, Germany
  (   )  Oooo     http://www.*-*-*.com/ ;           Tel.: +49-2241-14-2714
---\ (---(   )--------------------------------------------------------
    \_)   ) /
         (_/



Sun, 17 Sep 2000 03:00:00 GMT  
 convert char to short int via pointer?...

Guido:

Quote:
>I got the following problem:

>unsigned char * ptr;
>short int value;

>ptr = ...; /* Points to an array of raw data. */

>value = (short int)*ptr;

>Value is supposed to contain a short int constructed from *ptr plus
>*ptr+1 in signed little endian format.

>Does this work? And if not, how could it work?

The problem is your data is raw.  You have to cook it first.

What's wrong with
   value = 5;
?
I've always liked the number 5.

There is a way that might do it for you:

unsigned char *ptr;
short int value;
short int v = 5;
...
ptr = (char *) &v;
value = (short int) *ptr;
printf("%d"\n",value);

But I think the other way is better.

--
C-FAQ ftp sites: ftp://ftp.eskimo.com ftp://rtfm.mit.edu
Hypertext C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-FAQ Book: ISBN 0-201-84519-9.
Want Software?  Algorithms?  Pubs? http://www.infoseek.com



Sun, 17 Sep 2000 03:00:00 GMT  
 convert char to short int via pointer?...



|> I got the following problem:
|>
|> unsigned char * ptr;
|> short int value;
|>
|> ptr = ...; /* Points to an array of raw data. */
|>
|> value = (short int)*ptr;
           ^^^^^^^^^^^^^^^
I'm not sure what you're trying to do here.  Essentially, this
assignment takes the unsigned char value of ptr[0] and assigns
it to value.  I don't think this is what you intended.

|> Value is supposed to contain a short int constructed from *ptr
|> plus *ptr+1 in signed little endian format.

It sounds as if what you're intending to do is something like

    unsigned char data[] = { BYTE1, BYTE2 };
    ptr = data;

    value = *(short *)ptr;

That is, take the unsigned char pointer value, cast it to a pointer
to short int, and then dereference, placing the result in value.

|> Does this work? And if not, how could it work?

It might work, but it's very unsafe.  Perhaps the worst problem
with this approach is alignment.  In C, pointers to char (and
equivalently, pointers to void) have the least-strict alignment
requirements; as a result, ptr may be properly aligned for access
to unsigned char, but it may *not* be aligned for access to a
short int.  (In this case, the cast will result in undefined
behavior; a common result of this is a "bus error".)

A safer way to do what you're trying to accomplish is to use
the memcpy() function to physically copy the contents of the "raw
data" to the short object:

    memcpy(&value, ptr, sizeof(short));

(Remember to #include <string.h>.)

It is both unsafe and unportable to assume that ptr is properly
aligned to access objects of type short.  By copying the value
(instead of "interpreting" it, as it were) you remove any danger
due to alignment considerations.

Regards,

--
Chris Engebretson - Raytheon STX Corporation | Ph#: (605)594-6829
USGS EROS Data Center, Sioux Falls, SD 57198 | Fax: (605)594-6940

Opinions are not those of  Raytheon Systems Company  or the USGS.



Sun, 17 Sep 2000 03:00:00 GMT  
 convert char to short int via pointer?...

Quote:

> I got the following problem:

> unsigned char * ptr;
> short int value;

> ptr = ...; /* Points to an array of raw data. */

> value = (short int)*ptr;

> Value is supposed to contain a short int constructed from *ptr plus
> *ptr+1 in signed little endian format.

Well, that's easy: it's 2*(*ptr)+1. I assume that what you really meant
was *(ptr+1).

Quote:

> Does this work? And if not, how could it work?

        No, this doesn't work. It takes the unsigned char value that ptr points
to and converts it to a short. The cast is redundant: the compiler will
do the conversion when it assigns the value of *ptr to value.
        But you're on the right track. The key is that you have to get each of
the two values separately, and combine them to get the result.
        -- Pete


Sun, 17 Sep 2000 03:00:00 GMT  
 convert char to short int via pointer?...

Quote:



> |> I got the following problem:
> |>

 > |> unsigned char * ptr;
 > |> short int value;
 > |>
 > |> ptr = ...; /* Points to an array of raw data. */
 > |>
 > |> value = (short int)*ptr;
Quote:
>            ^^^^^^^^^^^^^^^
> I'm not sure what you're trying to do here.  Essentially, this
> assignment takes the unsigned char value of ptr[0] and assigns
> it to value.  I don't think this is what you intended.

> |> Value is supposed to contain a short int constructed from *ptr
> |> plus *ptr+1 in signed little endian format.

> It sounds as if what you're intending to do is something like

 >     unsigned char data[] = { BYTE1, BYTE2 };
 >     ptr = data;
 >
 >     value = *(short *)ptr;

Quote:

> That is, take the unsigned char pointer value, cast it to a pointer
> to short int, and then dereference, placing the result in value.

> |> Does this work? And if not, how could it work?

> It might work, but it's very unsafe.  Perhaps the worst problem
> with this approach is alignment.

There's a much worse problem: this code only works when the underlying
architecture represents unsigned int values in little-endian form. Note
that the only assurance we have from the problem statement is that the
unsigned char values pointed to by ptr represent the desired value in
little-endian form. We know nothing about the representation of unsigned
ints.

 >
 >     memcpy(&value, ptr, sizeof(short));
 >

Same problem: no guarantee that value is represented in little-endian
form. The only valid solution under the terms of the problem statement
is to pick up the two unsigned char values separately, and combine them
appropriately. You also have to look at UCHAR_MAX to know how to
interpret the high byte.
        -- Pete



Sun, 17 Sep 2000 03:00:00 GMT  
 convert char to short int via pointer?...



   [ regarding using the data stored in an array of 2 unsigned chars
     as a short int via a cast from (unsigned char *) to (short *) ]

|> > It might work, but it's very unsafe.  Perhaps the worst problem
|> > with this approach is alignment.
|>
|> There's a much worse problem: this code only works when the
|> underlying architecture represents unsigned int values in
|> little-endian form. Note that the only assurance we have from
|> the problem statement is that the unsigned char values pointed
|> to by ptr represent the desired value in little-endian form. We
|> know nothing about the representation of unsigned ints.

Right; I made the assumption that the little-endian "raw data" that
the original poster was referring to did indeed correspond to the
underlying representation used by his particular machine, most
likely "generated" by an existing short object.

|>  >     memcpy(&value, ptr, sizeof(short));
|>
|> Same problem: no guarantee that value is represented in
|> little-endian form. The only valid solution under the terms of
|> the problem statement is to pick up the two unsigned char
|> values separately, and combine them appropriately. You also have
|> to look at UCHAR_MAX to know how to interpret the high byte.

Indeed; if the code is intended to be independent of the underlying
architecture, then the problem becomes slightly more interesting.

As an aside, it might also be noted that if ptr points to memory
allocated by malloc() (or calloc() or realloc()), then the concerns
with alignment go away since these functions return pointers that
are suitably aligned for any data type.  However, given that the
"raw data" in question consists of only two bytes, this scenario
seems somewhat unlikely.  (And again, of course, if the "raw data"
is not in native format, none of this matters anyway.)

Regards,

--
Chris Engebretson - Raytheon STX Corporation | Ph#: (605)594-6829
USGS EROS Data Center, Sioux Falls, SD 57198 | Fax: (605)594-6940

Opinions are not those of  Raytheon Systems Company  or the USGS.



Sun, 17 Sep 2000 03:00:00 GMT  
 convert char to short int via pointer?...



Quote:
>I got the following problem:

>unsigned char * ptr;

Right, it is important that ptr is a pointer to *unsigned* char.

Quote:
>short int value;

>ptr = ...; /* Points to an array of raw data. */

>value = (short int)*ptr;

>Value is supposed to contain a short int constructed from *ptr plus
>*ptr+1 in signed little endian format.

I assume you mean *(ptr+1)

Quote:

>Does this work?

Have you tried it? What do you think it will do?

Quote:
>And if not, how could it work?

Consider the following

 value = ptr[0] | (ptr[1] << 8);

This assumes that a byte in your data stream is 8 bits and that the signed
integer formats are compatible (e.g. both are 2's complement).

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


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



Mon, 18 Sep 2000 03:00:00 GMT  
 
 [ 7 post ] 

 Relevant Pages 

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

2. Bitfields: char, short or int?

3. Converting to short int

4. Convert int to short?

5. char pointers vs. int pointers

6. converting char to pointer char

7. To convert unsigned char to unsigned short in VC++

8. Converting Unsigned short to char type!

9. Converting char arrary to short

10. To convert unsigned char to unsigned short in VC++

11. converting an char pointer to an integer pointer

12. int to char / char to int

 

 
Powered by phpBB® Forum Software