преобразовать char * в структуру в c ++ - PullRequest
0 голосов
/ 20 февраля 2019

У меня следующая структура

struct record{
RType m_rectype;
char m_recordname[11];
char m_recordNo;
char m_record_date[6];
}

, и у меня есть следующая строка типа char * type

line = "1Netherlands3240382"

Как мне преобразовать эту строку в структуру.Производительность важна, так как у меня есть огромные данные для обработки.

Я использовал reinterpret_cast, но элементы массива структуры или ноль не завершены.

record r = reinterpret_cast<const record* >(line)

Редактировать: окончательные результаты должны бытьследующим образом

r.m_rectype = "1"
r.m_recordname = "Netherlands"
r.m_recordNo = "3"
r.m_record_date = "240382"

но вместо этого я получаю следующее

r.m_rectype = "1"
r.m_recordname = "Netherlands3240382"
r.m_recordNo = "3"
r.m_record_date = "240382"

Спасибо

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

Предполагая, что RType является типом перечисления с поддержкой char (или псевдонимом для некоторого типа char), вы можете memcpy ввести свои данные в record объект.Возможно, вы также сможете заставить ваш компилятор делать то, что вы намереваетесь с reinterpret_cast.

Проблема, с которой вы столкнулись, звучит так, будто вы наблюдаете значения в этом record Объект через функции, которые принимают строки с нулевым символом в конце.Вместо этого вы должны использовать функции, которые принимают длину.

printf("r.m_rectype = \"%d\"", r.m_rectype);
printf("r.m_recordname = \"%11.11s\"", r.m_recordname);
printf("r.m_recordNo = \"%d\"", r.m_recordNo);
printf("r.m_record_date = \"%6.6s\"", r.m_record_date);
0 голосов
/ 20 февраля 2019

Строго говоря, Стандарт не дает никаких гарантий относительно заполнения между элементами struct, за исключением того, что в начале не будет заполнения.Таким образом, даже если ваша конкретная структура вряд ли будет иметь отступы - будучи (я предполагаю) всеми типами символов, для безопасности вы можете сделать что-то вроде этого:

template<typename Pod>
char const* pod_copy(char const* p, Pod& pod)
{
    static_assert(std::is_pod_v<Pod>, "Must be Plain Old Data type");

    std::copy(p, p + sizeof(pod), reinterpret_cast<char*>(&pod));
    return p + sizeof(pod);
}

struct record{
    RType m_rectype;
    char m_recordname[11];
    char m_recordNo;
    char m_record_date[6];
};

int main()
{
    record r;

    auto line = "1Netherlands3240382";

    auto p = line;

    p = pod_copy(p, r.m_rectype);
    p = pod_copy(p, r.m_recordname);
    p = pod_copy(p, r.m_recordNo);
    p = pod_copy(p, r.m_record_date);

    // .. rest of program
}

Это должнобудьте очень быстрыми, потому что pos_copy должен хорошо работать.

0 голосов
/ 20 февраля 2019

Я использовал reinterpret_cast

reinterpret_cast не может быть использовано для этого.Ваше использование имеет неопределенное поведение.Было бы хорошо определено следующее:

record r; // create a record object
std::memcpy(&r, line, sizeof r);

Предостережения:

  • Строки не заканчиваются нулем!
  • sizeof(RType) должно быть 1
  • Входной буфер не должен быть короче sizeof r.

, но вместо этого я получаю следующее

r.m_recordname = "Netherlands3240382"

Netherlands3240382 не помещается внутри элемента m_recordname, и, следовательно, это не может быть состоянием объекта.Проблема должна заключаться в том, как генерируется вывод.Я подозреваю, что строка обрабатывается так, как если бы она была завершена нулем, несмотря на то, что это не так.

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