将 2 个 ASCII char 值转换为 short int

Posted

技术标签:

【中文标题】将 2 个 ASCII char 值转换为 short int【英文标题】:Converting 2 ASCII char values into short int 【发布时间】:2014-11-26 23:23:05 【问题描述】:

我需要将两个 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

感谢您的建议。

【问题讨论】:

在转换之前尝试将您的字符转换为无符号字符。 那么欢迎来到 Stack Overflow!作为新用户,您可能需要阅读Introductory Tour To Stack Overflow 以了解该网站的简要概述。 听起来您也可能错误地输出了值(例如,使用%x 代替short); short 通常是 16 位值,但您的输出显示 32 位。 【参考方案1】:

所有窄数据类型在算术之前都被提升为int。你在很多地方做错的方式。

首先您的数据是unsigned char,但在函数中您将它们设置为charchar 可能已在您的计算机上签名,因此您会得到以前没有的负值。 这些负值将符号扩展为int,然后将它们存储到short, 而不是unsigned short

让你的类型正确,这将起作用。

【讨论】:

可能想添加有关打印short的注释。 @chux,在那种情况下,我只是认为他应该所有类型都无符号,所以%x 是正确的格式。【参考方案2】:

代码过于复杂,无法正确处理符号扩展,并且无法在计算中提升到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

【讨论】:

【参考方案3】:

将循环更改为

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

char 类型是 signedunsigned,具体取决于编译器。如果是signed,0x80 到 0xFF 之间的所有字节都被认为是负数,当通过默认的 int 提升规则转换为 int 时,它们的值将是 0xFFFFFF80 到 0xFFFFFFFF(32 位 int)。因此,在将它们提升为整数之前,您必须将它们转换为无符号值。您的keychar 数组被声明为unsigned char,因此无需将任何内容添加到您的代码中。 在现代编译器和处理器上,指针运算通常不比数组索引快,但更难阅读,因此对于琐碎的代码应避免使用它。

【讨论】:

以上是关于将 2 个 ASCII char 值转换为 short int的主要内容,如果未能解决你的问题,请参考以下文章

char[] 转换成 ascii 和十进制值 (double) java

c语言怎样实现将一个数值(int型)转换为各位对应的ASCII码

在 C 中将 ascii char[] 转换为十六进制 char[]

C语言char类型数据是否远远不止ASCII码

SQL字符串转换函数

C语言中a[i]=(char)(97+i)啥意思?