Преобразование двух значений 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
так что на самом деле ничего не нужно добавлять в ваш код. На современных компиляторах и процессорах арифметика указателей обычно не быстрее индексации массивов, но труднее для чтения, поэтому избегайте ее для тривиального кода.