将char *转换为c ++中的结构

时间:2019-02-20 13:48:13

标签: c++ struct reinterpret-cast

我具有以下结构

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

并且我有以下一行char *类型

line = "1Netherlands3240382"

如何将这行内容隐藏到结构中。性能非常重要,因为我需要处理大量数据。

我使用过reinterpret_cast,但是该结构的数组元素或非null终止。

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 :(得分:1)

  

我使用过reinterpret_cast

reinterpret_cast不能用于此目的。您的用法具有不确定的行为。可以很好地定义以下内容:

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

注意事项:

  • 字符串不是以null结尾的!
  • sizeof(RType)必须为1
  • 输入缓冲区不能短于sizeof r

  

但是我得到的却是以下内容

r.m_recordname = "Netherlands3240382"

Netherlands3240382不适合成员m_recordname的内部,因此不可能是对象的状态。问题必须出在生成输出的方式上。我的怀疑是,尽管该字符串不是空终止的,但仍被视为该字符串。

答案 1 :(得分:0)

假设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);

答案 2 :(得分:0)

严格来说,标准没有保证struct元素之间的填充,只是开头没有填充。因此,即使您的 specific 结构不太可能具有填充内容-为了安全起见,(我假设)所有字符类型,您都可以执行以下操作:

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应该很好地内联。