C++: преобразовать unsigned long long int в vector‹char› и наоборот

Может ли кто-нибудь сказать мне, как преобразовать unsigned long long int в вектор и наоборот.

Для преобразования из unsigned long long int в вектор я попробовал следующее:

unsigned long long int x;
vector<char> buf(sizeof(x));
memcpy( &buf[0], &x, sizeof( x ) );

Когда я проверил x = 1234567890, это не удалось. Но когда я попробовал это для меньших значений x (скажем, 1-100), это сработало...

Для преобразования вектора в unsigned long long int я использовал:

   unsigned long long int =  (unsigned long long int)buf[0];

Может ли кто-нибудь сказать мне, как это сделать.


person veda    schedule 25.01.2012    source источник
comment
да, я пытаюсь разбить целое число на вектор‹char›, чтобы я мог отправить его с клиента на сервер и прочитать обратно.   -  person veda    schedule 25.01.2012
comment
Если вы хотите сделать это, вам, вероятно, следует подумать об объединении решения Mark B с шаблонными функциями, которые могут безопасно записывать/считывать тип любого размера в ваш вектор‹char›.   -  person Benj    schedule 25.01.2012


Ответы (3)


Просто помните, что копирование байтов не будет кросс-платформенным. Ваш memcpy выглядит нормально, так почему бы не воссоздать его на обратном пути? То, что вы написали, просто берет первый байт вектора и преобразует его в unsigned long long, что объясняет, почему это работает для небольших чисел.

Вместо этого попробуйте это, чтобы вернуть значение из вектора:

unsigned long long int x;
memcpy(&x, &buf[0], sizeof(x));
person Mark B    schedule 25.01.2012
comment
Хе-хе, и если вы попробуете его текущий подход в системе с прямым порядком байтов, buf[0] будет содержать что-либо, только если у вас действительно большое значение x. - person Benj; 25.01.2012

Вместо memcpying непосредственно в вектор вы можете использовать std::vector::assign для выполнения копирования.

#include <iostream>
#include <vector>

int main()
{
  unsigned long long int x = 0x0807060504030201;
  std::vector<char> v;

  v.assign( reinterpret_cast<char *>( &x ), reinterpret_cast<char *>( &x ) + sizeof( x ) );

  for( auto i = v.begin(); i != v.end(); ++i ) {
    std::cout << std::hex << static_cast<int>( *i ) << ' ';
  }
  std::cout << std::endl;

  // To convert back
  auto y = *reinterpret_cast<unsigned long long int *>( &v[0] );
  std::cout << "y = " << std::hex << std::showbase << y << std::endl;

  return 0;
}

Выход:

1 2 3 4 5 6 7 8 
y = 0x807060504030201
person Praetorian    schedule 25.01.2012
comment
Как сохранить в обратном порядке, я имею в виду вывод печати будет 8 7 6 5 4 3 2 1? - person rank1; 08.05.2013
comment
@cygi1989 Используйте std::reverse. После v.assign(...); добавить std::reverse(v.begin(), v.end()); - person Praetorian; 08.05.2013
comment
Большой. Можно ли назначить ему наименьший возможный вектор, скажем, у меня есть функция, которая возвращает наименьшее количество байтов, необходимых для хранения заданного целого числа. Как бы я это сделал? - person rank1; 08.05.2013
comment
@ cygi1989 Я не понимаю, о чем вы спрашиваете. Почему бы вам не опубликовать еще один вопрос? - person Praetorian; 08.05.2013

Вы должны изменить последнюю строку:

memcpy( &buf[0], reinterpret_cast<char*>(&x), sizeof( x ) );

Редактировать Я говорил ерунду, эта строка и так хороша, но ваше обратное преобразование плохое - вы конвертируете значение, а не указатель:

unsigned long long int val = *reinterpret_cast<unsigned long long int*>(&buf[0]);
person Björn Pollex    schedule 25.01.2012
comment
@MarkB: Я тоже это понял - на мгновение запутался. - person Björn Pollex; 25.01.2012