简体   繁体   中英

Converting 2 ASCII char values into short int

I need to converto two ascii char value into one short int . This is my function:

void char2short(char* pchar, short* pshort)
{
        int i;
        char* auxchar = pchar;
        short* auxshort = pshort;

        for(i = 0; i < KEYSIZE/2; i++)
        {
        *auxshort = (auxchar[0] << 8) | auxchar[1];
        auxshort++;
        auxchar += 2;
        }
}

However, when I go and print out the values, I often get a bunch of FFFF in the beggining. Copypasted from my terminal:

    FFFFFFF7    FFFFFC24
    3049    3E1B
    FFFFFFE3    5705
    FFFFFFBC    FFFFA960
    FFFFFFB1    FFFFFF84
    FFFFFFEB    FFFFFFAD
    FFFFFFDA    FFFFFFCC
    FFFFFFB8    FFFFFFB0
    FFFFFFC7    1125

And this is the orignal number I'm trying to convert:

  static unsigned char keychar[]={
            0x8C,0xF7,0xFC,0x24,0x30,0x49,0x3E,0x1B,0x6D,0xE3,0x57,0x05,
            0x67,0xBC,0xA9,0x60,0x58,0xB1,0xBD,0x84,0xDD,0xEB,0xE8,0xAD,
            0x69,0xDA,0x49,0xCC,0x49,0xB8,0x5D,0xB0,0x42,0xC7,0x11,0x25}

Thanks in advice.

All narrow data types are promoted to int before arithmetic. The way you are doing this wrong in many places.

  • First your data are unsigned char but in the function you have them as char .
  • Probably char is signed on your machine so you get negative values where there weren't before.
  • These negative values get sign expande to int and you store them into short , instead of unsigned short .

Get your types right, and this will work.

The code is unnecessarily complex and fails to properly handle sign extension and fails to allow for promotion to int in the calculations.

Suggest:

// call this function for each pair of char by:
for(int i = 0; i < sizeof(keychar); i+=2)
{
    char2short( &keychar[i], &myshort );
    //  process myshort
}

void char2short(char* pchar, short* pshort)
{
    short result = 0;

    if( ('0' <= pchar[0]) && ('9' >= pchar[0]) )
    { 
        result +=  pchar[0]- '0'; 
    } // end if

    if( ('0' <= pchar[1]) && ('9' >= pchar[1]) )
    { 
        result *= 10;
        result +=  pchar[0 - '0'; 
    } // end if

    *pshort = result;
} // end function: char2short

Your question was not clear, perhaps you want to take each successive 2 char and stuff them into a short then

void char2short(char* pchar, short* pshort)
{
    char result[2] = {'0','0'};

    result |= pchar[0];
    result <<= 8;
    result |= pchar[1];

    *pshort = (short)result;
} // end function: char2short

--or even simpler --

void char2short(char* pchar, short* pshort)
{
    *pshort = *(short*)pchar;
} // end function: char2short

Change your loop to

 for(i = 0; i < KEYSIZE/2; i++)
    auxshort[i] = (keychar[i*2] << 8) | keychar[i*2+1];

char type is, depending n the compiler, either signed or unsigned . If it is signed , the all bytes between 0x80 to 0xFF are considered negative numbers and when converted to int by the default int promotion rule, their value will be 0xFFFFFF80 to 0xFFFFFFFF (32 bit int). Therefore you have to convert them to unsigned value before they are promoted to integer. Your keychar array is declared as unsigned char so nothing is really necessary to be added to your code. On modern compilers and processors, pointer arithmetic is generally not faster than array indexing but is more difficult to read, so avoid it for trivial code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM