хранение и чтение данных int в массив char - PullRequest
4 голосов
/ 17 ноября 2011

Я пытаюсь сохранить два целых числа в массив символов в C ++.Вот код ..

char data[20];
*data = static_cast <char> (time_delay);   //time_delay is of int type
*(data + sizeof(int)) = static_cast<char> (wakeup_code);  //wakeup_code is of int type

Теперь на другом конце программы я хочу отменить эту операцию.То есть из этого массива char мне нужно получить значения time_delay и wakeup_code.

Как мне это сделать ??

Спасибо, Ник

PS: язнаю, что это глупый способ сделать это, но поверьте мне, это ограничение.

Ответы [ 5 ]

3 голосов
/ 17 ноября 2011

Если вы работаете с архитектурой ПК x86, то нет проблем с выравниванием (кроме скорости), и вы можете преобразовать char * в int *, чтобы выполнить преобразования:

char data[20];
*((int *)data) = first_int;
*((int *)(data+sizeof(int))) = second_int;

и тот же синтаксис можно использовать для чтения из data, просто поменяв местами =.

Обратите внимание, однако, что этот код не переносим, ​​потому что существуют архитектуры, в которых невыровненная операция может быть не просто медленной, ана самом деле незаконно (сбой).В этих случаях, вероятно, самый хороший подход (который также дает вам возможность управления порядком байтов в случае, если data является частью протокола связи между различными системами) - это явное построение целых чисел в коде по одному символу за раз:

first_uint = ((unsigned char)data[0] |
              ((unsigned char)data[1] << 8) |
              ((unsigned char)data[2] << 16) |
              ((unsigned char)data[3] << 24));
data[4] = second_uint & 255;
data[5] = (second_uint >> 8) & 255;
data[6] = (second_uint >> 16) & 255;
data[7] = (second_uint >> 24) & 255;
3 голосов
/ 17 ноября 2011

Я думаю, что когда вы пишете static_cast<char>, это значение преобразуется в 1-байтовый символ, поэтому, если оно не помещается в символ для начала, вы потеряете данные.

ЧтоЯ бы использовал *((int*)(data+sizeof(int))) и *((int*)(data+sizeof(int))) для чтения и записи целых чисел в массив.

*((int*)(data+sizeof(int))) = wakeup_code;
....
wakeup_code = *((int*)(data+sizeof(int)));

В качестве альтернативы вы также можете написать:

reinterpret_cast<int*>(data)[0]=time_delay;
reinterpret_cast<int*>(data)[1]=wakeup_code;
1 голос
/ 17 ноября 2011

Попробуйте следующее:

union IntsToChars {
struct {
int time_delay;
int wakeup_value;
} Integers;
char Chars[20];
};

extern char* somebuffer;

void foo()
{
    IntsToChars n2c;
    n2c.Integers.time_delay = 1;
    n2c.Integers.wakeup_value = 2;
    memcpy(somebuffer,n2c.Chars,sizeof(n2c));  //an example of using the char array containing the integer data
    //...
}

Использование такого объединения должно устранить проблему выравнивания, если только данные не передаются на машину с другой архитектурой.

1 голос
/ 17 ноября 2011

Я не пробовал, но должно работать следующее:

char data[20];
int value;

memcpy(&value,data,sizeof(int));
0 голосов
/ 17 ноября 2011
#include <sstream>
#include <string>
int main ( int argc, char **argv) {
    char ch[10];
    int i = 1234;

    std::ostringstream oss;
    oss << i;
    strcpy(ch, oss.str().c_str());

    int j = atoi(ch);
}
...