Преобразование двух значений ASCII-символов в короткие int

Мне нужно конвертировать два ascii char ценность в один short int, Это моя функция:

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;
        }
}

Однако, когда я иду и распечатываю значения, я часто получаю кучу FFFF в начале. Копирование с моего терминала:

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

И это оригинальное число, которое я пытаюсь преобразовать:

  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}

Спасибо за совет.

3 ответа

Код неоправданно сложен и не может правильно обрабатывать расширение знака и не позволяет продвигать int в расчетах.

Предложить:

// 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

Ваш вопрос был неясен, возможно, вы хотите принять каждый последующий 2 char и набить их в short затем

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

- или даже проще -

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

Все узкие типы данных повышены до int до арифметики. То, как вы делаете это неправильно во многих местах.

  • Сначала ваши данные unsigned char но в функции вы их как char,
  • Наверное char подписан на вашей машине, так что вы получите отрицательные значения там, где раньше не было.
  • Эти отрицательные значения получают знак расширения int и вы храните их в short, вместо unsigned short,

Получите ваши типы правильно, и это будет работать.

Измените ваш цикл на

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

char Тип, в зависимости от компилятора, либо signed или же unsigned, Если это signedвсе байты от 0x80 до 0xFF считаются отрицательными числами и при преобразовании в int по умолчанию правило продвижения int их значение будет от 0xFFFFFF80 до 0xFFFFFFFF (32 бита int). Поэтому вы должны преобразовать их в беззнаковое значение, прежде чем они будут преобразованы в целое число. Ваш keychar массив объявлен как unsigned char так что на самом деле ничего не нужно добавлять в ваш код. На современных компиляторах и процессорах арифметика указателей обычно не быстрее индексации массивов, но труднее для чтения, поэтому избегайте ее для тривиального кода.

Другие вопросы по тегам