将uint16_t转换为十进制并将其按位存储在char数组中。检索uint16_t变量中的数据时出错

乱码
int main()  
{  
    unsigned char ptr[9];  
    uint16_t dat = 128, s;  
    int i, j = 1, k;  

    ptr[0] = ptr[0] & 0;  
    j = -1;  

    for(i = 0;i <= 15;i++)  
    {  
        if(i % 8 == 0)
            j++;

        s = dat << i;  

        if (s & (1 << 15))  
            ptr[j] |= 1 << (7 - i%8);  
        else  
            ptr[j] |= 0 << (7 - i%8);  
    }  

    j = -1;  
    s &= 0;  

    for(i = 0;i <= 15;i++)  
    {         
        if(i % 8 == 0)  
            j++;  
        s |= (ptr[j] & (1 << (7 - i%8))) << (15 - i);  // <-----------  
        s |= (ptr[j] & (1 << i%8)) << (15 - i); // Correction
    }

    printf("%d", s);  

    return(0);
}

我试图通过先转换为二进制然后将其一点一点地复制到数组中,将16个字节的整数包装到字符数组中。但是,我在标记行上遇到了麻烦。我得到16834作为输出。我在这里做错了什么?

乔纳森·勒夫勒(Jonathan Leffler)

如所写,输出是不确定的,因为您从未设置ptr[1]为已知值。在我的Mac上,这是您的代码的次要变体(主要是添加了一些,标头,空格和printf()语句):

#include <stdint.h>
#include <stdio.h>

int main(void)
{
    unsigned char ptr[9];
    uint16_t dat = 128, s;
    int i, j = 1;

    ptr[0] = ptr[0] & 0;
    j = -1;
    printf("0x%.2X 0x%.2X\n", ptr[0], ptr[1]);

    for (i = 0; i <= 15; i++)
    {
        if (i % 8 == 0)
            j++;

        s = dat << i;

        if (s & (1 << 15))
            ptr[j] |= 1 << (7 - i % 8);
        else
            ptr[j] |= 0 << (7 - i % 8);
    }
    printf("0x%.2X 0x%.2X\n", ptr[0], ptr[1]);

    j = -1;
    s &= 0;

    for (i = 0; i <= 15; i++)
    {
        if (i % 8 == 0)
            j++;
        s |= (ptr[j] & (1 << (7 - i % 8))) << (15 - i);  // <-----------
    }

    printf("0x%.2X\n", s);
    printf("%d\n", s);

    return(0);
}

显示输出:

0x00 0xF4
0x00 0xF4
0x5510
21776

当修改成用ptr[0] = ptr[0] & 0;ptr[0] = ptr[1] = 0;,所述输出为:

0x00 0x00
0x00 0x80
0x4000
16384

您很不幸,您的计算机将堆栈清零了。发现未初始化变量之类的错误会变得更加困难。

您选择128作为测试值会给您带来生活上的困难;仅设置一位。在测试中,我将使用一种独特的模式,例如0x3CA5(C ++ 14二进制表示法中的0b0011'1100'1010'0101)。当我将代码更改为使用0x3CA5时,我得到了输出:

0x00 0x00
0x3C 0xA5
0x5411
21521

好消息:第一个循环复制这些位,以使数字的高字节在in中ptr[0],而低字节在in中ptr[1]坏消息:第二个循环似乎使事情变得糟透了。

这是第二个循环的检测版本:

    for (i = 0; i < 16; i++)
    {
        if (i % 8 == 0)
            j++;
        uint16_t s0 = s;
        s |= (ptr[j] & (1 << (7 - i % 8))) << (15 - i);  // <-----------
        printf("i: %2d, j: %d, 7-i%%8: %d, ptr[j]: 0x%.2X, &val: 0x%.2X, "
               "|val = 0x%.5X, s0: 0x%.4X, s: 0x%.4X\n",
               i, j, 7 - i % 8, ptr[j], (1 << (7 - i % 8)),
               (ptr[j] & (1 << (7 - i % 8))) << (15 - i),
               s0, s);
    }

输出为:

0x00 0x00
0x3C 0xA5
i:  0, j: 0, 7-i%8: 7, ptr[j]: 0x3C, &val: 0x80, |val = 0x00000, s0: 0x0000, s: 0x0000
i:  1, j: 0, 7-i%8: 6, ptr[j]: 0x3C, &val: 0x40, |val = 0x00000, s0: 0x0000, s: 0x0000
i:  2, j: 0, 7-i%8: 5, ptr[j]: 0x3C, &val: 0x20, |val = 0x40000, s0: 0x0000, s: 0x0000
i:  3, j: 0, 7-i%8: 4, ptr[j]: 0x3C, &val: 0x10, |val = 0x10000, s0: 0x0000, s: 0x0000
i:  4, j: 0, 7-i%8: 3, ptr[j]: 0x3C, &val: 0x08, |val = 0x04000, s0: 0x0000, s: 0x4000
i:  5, j: 0, 7-i%8: 2, ptr[j]: 0x3C, &val: 0x04, |val = 0x01000, s0: 0x4000, s: 0x5000
i:  6, j: 0, 7-i%8: 1, ptr[j]: 0x3C, &val: 0x02, |val = 0x00000, s0: 0x5000, s: 0x5000
i:  7, j: 0, 7-i%8: 0, ptr[j]: 0x3C, &val: 0x01, |val = 0x00000, s0: 0x5000, s: 0x5000
i:  8, j: 1, 7-i%8: 7, ptr[j]: 0xA5, &val: 0x80, |val = 0x04000, s0: 0x5000, s: 0x5000
i:  9, j: 1, 7-i%8: 6, ptr[j]: 0xA5, &val: 0x40, |val = 0x00000, s0: 0x5000, s: 0x5000
i: 10, j: 1, 7-i%8: 5, ptr[j]: 0xA5, &val: 0x20, |val = 0x00400, s0: 0x5000, s: 0x5400
i: 11, j: 1, 7-i%8: 4, ptr[j]: 0xA5, &val: 0x10, |val = 0x00000, s0: 0x5400, s: 0x5400
i: 12, j: 1, 7-i%8: 3, ptr[j]: 0xA5, &val: 0x08, |val = 0x00000, s0: 0x5400, s: 0x5400
i: 13, j: 1, 7-i%8: 2, ptr[j]: 0xA5, &val: 0x04, |val = 0x00010, s0: 0x5400, s: 0x5410
i: 14, j: 1, 7-i%8: 1, ptr[j]: 0xA5, &val: 0x02, |val = 0x00000, s0: 0x5410, s: 0x5410
i: 15, j: 1, 7-i%8: 0, ptr[j]: 0xA5, &val: 0x01, |val = 0x00001, s0: 0x5410, s: 0x5411
0x5411
21521

除了在价值观s0s是不是你想要的东西,而忽略了|val,值是我们期望的东西; 基本的迭代结构处于控制之下。但是,该|val列表明存在问题-出乎意料的是,需要在输出格式中使用5个十六进制数字!i - 15转变是不是把你想要和需要它们放置位。

从这里开始,您需要自己解决问题。我希望这样做是为您提供有关如何调试此类问题的一些见解。

顺便提一句,该问题已更新为提供:

s |= (ptr[j] & (1 << i%8)) << (15 - i); // Correction

在以0x3CA5作为初始值的测试工具中dat,产生输出:

0x00 0x00
0x3C 0xA5
i:  0, j: 0, 7-i%8: 7, ptr[j]: 0x3C, &val: 0x80, |val = 0x00000, s0: 0x0000, s: 0x0000
i:  1, j: 0, 7-i%8: 6, ptr[j]: 0x3C, &val: 0x40, |val = 0x00000, s0: 0x0000, s: 0x0000
i:  2, j: 0, 7-i%8: 5, ptr[j]: 0x3C, &val: 0x20, |val = 0x08000, s0: 0x0000, s: 0x8000
i:  3, j: 0, 7-i%8: 4, ptr[j]: 0x3C, &val: 0x10, |val = 0x08000, s0: 0x8000, s: 0x8000
i:  4, j: 0, 7-i%8: 3, ptr[j]: 0x3C, &val: 0x08, |val = 0x08000, s0: 0x8000, s: 0x8000
i:  5, j: 0, 7-i%8: 2, ptr[j]: 0x3C, &val: 0x04, |val = 0x08000, s0: 0x8000, s: 0x8000
i:  6, j: 0, 7-i%8: 1, ptr[j]: 0x3C, &val: 0x02, |val = 0x00000, s0: 0x8000, s: 0x8000
i:  7, j: 0, 7-i%8: 0, ptr[j]: 0x3C, &val: 0x01, |val = 0x00000, s0: 0x8000, s: 0x8000
i:  8, j: 1, 7-i%8: 7, ptr[j]: 0xA5, &val: 0x80, |val = 0x00080, s0: 0x8000, s: 0x8080
i:  9, j: 1, 7-i%8: 6, ptr[j]: 0xA5, &val: 0x40, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 10, j: 1, 7-i%8: 5, ptr[j]: 0xA5, &val: 0x20, |val = 0x00080, s0: 0x8080, s: 0x8080
i: 11, j: 1, 7-i%8: 4, ptr[j]: 0xA5, &val: 0x10, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 12, j: 1, 7-i%8: 3, ptr[j]: 0xA5, &val: 0x08, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 13, j: 1, 7-i%8: 2, ptr[j]: 0xA5, &val: 0x04, |val = 0x00080, s0: 0x8080, s: 0x8080
i: 14, j: 1, 7-i%8: 1, ptr[j]: 0xA5, &val: 0x02, |val = 0x00000, s0: 0x8080, s: 0x8080
i: 15, j: 1, 7-i%8: 0, ptr[j]: 0xA5, &val: 0x01, |val = 0x00080, s0: 0x8080, s: 0x8080
0x8080
32896

这不是完整的答案。

我想获得的价值dats我需要它,因为我必须通过UDP套接字发送char数组。因此,我将在一端将整数作为二进制存储在字符数组中,然后在另一端将其重新组装为整数。

您无需进行按位运算即可获得所需的结果。字节操作正常。

ptr[0] = dat >> 8;
ptr[1] = dat & 0xFF;  // You could get away without the '& 0xFF'

// Transmit over UDP

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

使用unsigned char(正在执行)很重要如果您使用纯色char(或更糟的是signed char),则必须担心符号位和符号扩展。

作为您进行位操作的练习,这有一些目的。值得您花一些时间来修复您的代码,以便它可以正常工作。作为一种处理数据以通过网络传输的方法,它不是一种很好的工作方式,一旦您了解了比特操作的所有知识,就应该抛弃它。

解决该问题的一种方法(按我的想象,不一定是最好的,但有效的一种方法)是修复lhs << (15 - i)移位的LHS,以使移位的LHS值为0或1。例如:

((ptr[j] & (1 << (7 - i % 8))) ? 1 : 0) << (15 - i)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将 uint16_t 十六进制数转换为 C 中的十进制数

来自分类Dev

将uint16_t *数组转换为std :: vector

来自分类Dev

字符数组中的uint16_t

来自分类Dev

如何通过转换类型指针将char数组转换为uint16_t?

来自分类Dev

在C中将char *转换为uint16_t

来自分类Dev

将未签名的字符*转换为uint16_t *

来自分类Dev

用C中的uint64_t数据填充uint16_t数组

来自分类Dev

将char *转换为uint16_t的安全且便携的方法

来自分类Dev

将char [2]转换为uint16_t进行套接字编程?

来自分类Dev

将char [2]转换为uint16_t进行套接字编程?

来自分类Dev

从位流读取uint16_t

来自分类Dev

在C中将uint8_t数组转换为uint16_t值

来自分类Dev

从unsigned int转换为uint16_t的转换错误

来自分类Dev

将uint8_t和uint16_t转换为NSMutableData

来自分类Dev

将uint8_t和uint16_t转换为NSMutableData

来自分类Dev

如何使用按位运算将3个整数值编码为uint16_t?

来自分类Dev

C++:如何从二进制文件中读取特定数量的字节并将其保存到 uint16_t?

来自分类Dev

使用指针将两个元素从uint8_t数组复制到uint16_t变量中

来自分类Dev

如何将uint16_t转换为宽字符串(std :: wstring)

来自分类Dev

将2 uint16_t转换为32浮点的IEEE-754格式

来自分类Dev

如何将uint16_t值分配给uint8_t数组?

来自分类Dev

在C中将uint16_t拆分为位

来自分类Dev

如何使用按位操作存储和读取uint16_t上的多个数字值?

来自分类Dev

将二进制文件读入std :: vector <uint16_t>而不是std :: vector <char>

来自分类Dev

在使用uint16_t和按位运算时会期望多少数字

来自分类Dev

比较void *与uint16_t

来自分类Dev

如何正确地从uint16_t变量中提取一个特定的位

来自分类Dev

为什么C编译器允许从uint16_t静默转换为枚举类型?

来自分类Dev

如何在C ++中将uint8_t和uint16_t转换为浮点数?

Related 相关文章

  1. 1

    将 uint16_t 十六进制数转换为 C 中的十进制数

  2. 2

    将uint16_t *数组转换为std :: vector

  3. 3

    字符数组中的uint16_t

  4. 4

    如何通过转换类型指针将char数组转换为uint16_t?

  5. 5

    在C中将char *转换为uint16_t

  6. 6

    将未签名的字符*转换为uint16_t *

  7. 7

    用C中的uint64_t数据填充uint16_t数组

  8. 8

    将char *转换为uint16_t的安全且便携的方法

  9. 9

    将char [2]转换为uint16_t进行套接字编程?

  10. 10

    将char [2]转换为uint16_t进行套接字编程?

  11. 11

    从位流读取uint16_t

  12. 12

    在C中将uint8_t数组转换为uint16_t值

  13. 13

    从unsigned int转换为uint16_t的转换错误

  14. 14

    将uint8_t和uint16_t转换为NSMutableData

  15. 15

    将uint8_t和uint16_t转换为NSMutableData

  16. 16

    如何使用按位运算将3个整数值编码为uint16_t?

  17. 17

    C++:如何从二进制文件中读取特定数量的字节并将其保存到 uint16_t?

  18. 18

    使用指针将两个元素从uint8_t数组复制到uint16_t变量中

  19. 19

    如何将uint16_t转换为宽字符串(std :: wstring)

  20. 20

    将2 uint16_t转换为32浮点的IEEE-754格式

  21. 21

    如何将uint16_t值分配给uint8_t数组?

  22. 22

    在C中将uint16_t拆分为位

  23. 23

    如何使用按位操作存储和读取uint16_t上的多个数字值?

  24. 24

    将二进制文件读入std :: vector <uint16_t>而不是std :: vector <char>

  25. 25

    在使用uint16_t和按位运算时会期望多少数字

  26. 26

    比较void *与uint16_t

  27. 27

    如何正确地从uint16_t变量中提取一个特定的位

  28. 28

    为什么C编译器允许从uint16_t静默转换为枚举类型?

  29. 29

    如何在C ++中将uint8_t和uint16_t转换为浮点数?

热门标签

归档