简体   繁体   English

将int存储在char数组中?

[英]Store an int in a char array?

I want to store a 4-byte int in a char array... such that the first 4 locations of the char array are the 4 bytes of the int. 我想在char数组中存储一个4字节的int ...这样char数组的前4个位置就是int的4个字节。

Then, I want to pull the int back out of the array... 然后,我想把int拉出数组......

Also, bonus points if someone can give me code for doing this in a loop... IE writing like 8 ints into a 32 byte array. 此外,如果有人可以给我代码在循环中执行此操作,奖励积分... IE写入8字节到32字节数组。

int har = 0x01010101;
char a[4];
int har2;

// write har into char such that:
// a[0] == 0x01, a[1] == 0x01, a[2] == 0x01, a[3] == 0x01 etc.....

// then, pull the bytes out of the array such that:
// har2 == har

Thanks guys! 多谢你们!

EDIT: Assume int are 4 bytes... 编辑:假设int是4个字节...

EDIT2: Please don't care about endianness... I will be worrying about endianness. 编辑2:请不要关心字节序...我会担心字节序。 I just want different ways to acheive the above in C/C++. 我只是想用不同的方法来实现C / C ++中的上述功能。 Thanks 谢谢

EDIT3: If you can't tell, I'm trying to write a serialization class on the low level... so I'm looking for different strategies to serialize some common data types. 编辑3:如果你不能说,我正在尝试在低级写一个序列化类......所以我正在寻找不同的策略来序列化一些常见的数据类型。

Unless you care about byte order and such, memcpy will do the trick: 除非你关心字节顺序等,否则memcpy会做到这一点:

memcpy(a, &har, sizeof(har));
...
memcpy(&har2, a, sizeof(har2));

Of course, there's no guarantee that sizeof(int)==4 on any particular implementation (and there are real-world implementations for which this is in fact false). 当然,不能保证sizeof(int)==4在任何特定的实现上(并且有实际的实现,这实际上是假的)。

Writing a loop should be trivial from here. 从这里写一个循环应该是微不足道的。

Not the most optimal way, but is endian safe. 不是最优化的方式,但是endian是安全的。


int har = 0x01010101;
char a[4];
a[0] = har & 0xff;
a[1] = (har>>8)  & 0xff;
a[2] = (har>>16) & 0xff;
a[3] = (har>>24) & 0xff;
int main() {
    typedef union foo {
        int x;
        char a[4];
    } foo;

    foo p;
    p.x = 0x01010101;
    printf("%x ", p.a[0]);
    printf("%x ", p.a[1]);
    printf("%x ", p.a[2]);
    printf("%x ", p.a[3]);

    return 0;
}

Bear in mind that the a[0] holds the LSB and a[3] holds the MSB, on a little endian machine. 请记住,a [0]在一个小端机器上保存LSB而a [3]保持MSB。

#include <stdio.h>

int main(void) {
    char a[sizeof(int)];
    *((int *) a) = 0x01010101;
    printf("%d\n", *((int *) a));
    return 0;
}

Keep in mind: 记住:

A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. 指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针。 If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. 如果生成的指针未针对指向类型正确对齐,则行为未定义。

Note: Accessing a union through an element that wasn't the last one assigned to is undefined behavior. 注意:通过不是最后一个元素的元素访问联合是未定义的行为。 (assuming a platform where characters are 8bits and ints are 4 bytes) A bit mask of 0xFF will mask off one character so (假设字符为8位且整数为4字节的平台)0xFF的位掩码将屏蔽掉一个字符

char arr[4];
int a = 5;

arr[3] = a & 0xff;
arr[2] = (a & 0xff00) >>8;
arr[1] = (a & 0xff0000) >>16;
arr[0] = (a & 0xff000000)>>24;

would make arr[0] hold the most significant byte and arr[3] hold the least. 会使arr [0]保持最重要的字节,而arr [3]保持最少。

edit:Just so you understand the trick & is bit wise 'and' where as && is logical 'and'. 编辑:只是让你理解这个技巧并且有点明智'和'其中&&是逻辑'和'。 Thanks to the comments about the forgotten shift. 感谢有关遗忘转变的评论。

Don't use unions, Pavel clarifies: 不要使用工会,帕维尔澄清:

It's UB, because C++ prohibits accessing any union member other than the last one that was written to. 这是UB,因为C ++禁止访问除写入的最后一个之外的任何工会成员。 In particular, the compiler is free to optimize away the assignment to int member out completely with the code above, since its value is not subsequently used (it only sees the subsequent read for the char[4] member, and has no obligation to provide any meaningful value there). 特别是,编译器可以使用上面的代码自由地完全int成员的赋值,因为它的值随后没有使用(它只看到char[4]成员的后续读取,并且没有义务提供任何有意义的价值)。 In practice, g++ in particular is known for pulling such tricks, so this isn't just theory. 在实践中,g ++尤其以提取这些技巧而闻名,所以这不仅仅是理论。 On the other hand, using static_cast<void*> followed by static_cast<char*> is guaranteed to work. 另一方面,使用static_cast<void*>后跟static_cast<char*>可以保证正常工作。

– Pavel Minaev - 帕维尔·米娜耶夫

You can also use placement new for this: 您还可以使用新的展示位置:

void foo (int i) {
  char * c = new (&i) char[sizeof(i)];
}
#include <stdint.h>

    int main(int argc, char* argv[]) {
        /* 8 ints in a loop */
        int i;
        int* intPtr
        int intArr[8] = {1, 2, 3, 4, 5, 6, 7, 8};
        char* charArr = malloc(32);

        for (i = 0; i < 8; i++) {
            intPtr = (int*) &(charArr[i * 4]);
          /*  ^            ^    ^        ^     */
          /* point at      |    |        |     */
          /*       cast as int* |        |     */
          /*               Address of    |     */
          /*            Location in char array */

            *intPtr = intArr[i]; /* write int at location pointed to */
        }

        /* Read ints out */
        for (i = 0; i < 8; i++) {
            intPtr = (int*) &(charArr[i * 4]);
            intArr[i] = *intPtr;
        }

        char* myArr = malloc(13);
        int myInt;
        uint8_t* p8;    /* unsigned 8-bit integer  */
        uint16_t* p16;  /* unsigned 16-bit integer */
        uint32_t* p32;  /* unsigned 32-bit integer */

        /* Using sizes other than 4-byte ints, */
        /* set all bits in myArr to 1          */
        p8 = (uint8_t*) &(myArr[0]);
        p16 = (uint16_t*) &(myArr[1]);
        p32 = (uint32_t*) &(myArr[5]);
        *p8 = 255;
        *p16 = 65535;
        *p32 = 4294967295;

        /* Get the values back out */
        p16 = (uint16_t*) &(myArr[1]);
        uint16_t my16 = *p16;

        /* Put the 16 bit int into a regular int */
        myInt = (int) my16;

    }
char a[10];
int i=9;

a=boost::lexical_cast<char>(i)

found this is the best way to convert char into int and vice-versa. 发现这是将char转换为int的最佳方法,反之亦然。

alternative to boost::lexical_cast is sprintf. boost :: lexical_cast的替代方案是sprintf。

char temp[5];
temp[0]="h"
temp[1]="e"
temp[2]="l"
temp[3]="l"
temp[5]='\0'
sprintf(temp+4,%d",9)
cout<<temp;

output would be :hell9 输出将是:hell9

union value {
   int i;
   char bytes[sizof(int)];
};

value v;
v.i = 2;

char* bytes = v.bytes;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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