конвертировать (n первых байтов) беззнаковый указатель char в число с плавающей точкой и удвоить c ++ - PullRequest
0 голосов
/ 19 сентября 2018

Рассмотрим следующий код c ++:

unsigned char* data = readData(..);        //Let say data consist of 12 characters
unsigned int dataSize = getDataSize(...);  //the size in byte of the data is also known (let say 12 bytes)

struct Position 
{
   float pos_x;    //remember that float is 4 bytes
   double pos_y;   //remember that double is 8 bytes
}

Теперь я хочу заполнить переменную / экземпляр Position данными.

Position pos;
pos.pos_x = ?   //data[0:4[ The first 4 bytes of data should be set to pos_x, since pos_x is of type float which is 4 bytes
pos.pos_x = ?   //data[4:12[ The remaining 8 bytes of data should be set to pos_y which is of type double (8 bytes)

Я знаю, что в data первые байты соответствуют pos_x, а остальные * pos_y.Это означает, что 4 первых байта / символа данных должны использоваться для заполнения pos_x, а 8 оставшихся байтов - pos_y, но я не знаю, как это сделать.Любая идея?Благодарю.PS: я ограничен в C ++ 11

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Вы можете использовать обычный memcpy в качестве другого ответа.Я предлагаю упаковывать memcpy в функцию, которая также выполняет проверку ошибок для наиболее удобного и безопасного для типов использования.

Пример:

#include <cstring>
#include <stdexcept>
#include <type_traits>

struct ByteStreamReader {
    unsigned char const* begin;
    unsigned char const* const end;

    template<class T>
    operator T() {
        static_assert(std::is_trivially_copyable<T>::value, 
            "The type you are using cannot be safely copied from bytes.");
        if(end - begin < static_cast<decltype(end - begin)>(sizeof(T)))
            throw std::runtime_error("ByteStreamReader");
        T t;
        std::memcpy(&t, begin, sizeof t);
        begin += sizeof t;
        return t;
    }
};

struct Position {
   float pos_x;
   double pos_y;
};

int main() {
    unsigned char data[12] = {};
    unsigned dataSize = sizeof data;

    ByteStreamReader reader{data, data + dataSize};

    Position p;
    p.pos_x = reader;
    p.pos_y = reader;
}
0 голосов
/ 19 сентября 2018

Одна вещь, которую вы можете сделать, это скопировать байты данных.Для этого есть стандартная функция: std::memcpy.Пример использования:

assert(sizeof pos.pos_x == 4);
std::memcpy(&pos.pos_x, data, 4);
assert(sizeof pos.pos_y == 8);
std::memcpy(&pos.pos_y, data + 4, 8);

Обратите внимание, что простое копирование данных работает, только если данные находятся в том же представлении, что и процессор.Поймите, что разные процессоры используют разные представления.Поэтому, если ваш readData получает данные по сети, например, простая копия не очень хорошая идея.Наименьшее, что вам нужно сделать в таком случае, - это, возможно, преобразовать порядковый номер данных в исходный порядковый номер (вероятно, из большого порядкового номера, который обычно используется как порядковый номер сети).Преобразование из одного представления с плавающей запятой в другое намного сложнее, но, к счастью, IEE-754 довольно распространен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...