如何使用C ++读取文件并基于输入文件构建数据结构?

时间:2018-02-14 14:38:47

标签: c++ data-oriented-design

我想这应该是可能的。我试过但找不到一个好的答案。我基本上想要制作一个动态结构。我想读一个文件,告诉我我的结构将包含的数据类型。基于这些值,我想构建一个结构。我想为此使用C ++。我们可以将oracle视为一个示例,我们提供一个csv文件,它可以识别它们应该是什么类型,并创建该特定数据类型的列。

有人可以帮我解决这个问题吗?

更新:我想我应该添加一些代码来解释我的问题陈述。所以我们走了:

//PLC Data Block Sturcture.
//Todo: try to construct this structure from a file or something
struct MMSDataHeader{
    bool          bHeader_Trigger;      //2
    unsigned char MachineTimeStamp[8];  //8
    std::string   Header_MachineID;     //12
    std::string   Header_Station;       //12
    int           Header_MessageID;     //2
    int           Header_MessageSequenceNo; //2
    int           Header_NumberOfProperties; //2
    int           MeasurementType;          //2
    bool          Response_Acknowledge;     //2
};
typedef struct MMSDataHeader MMSDataHeader;

int PLCBox::GetHeader(){

   MMSDataHeader local_PLCData = { 0 };
  int res = -1;

  std::cout << "Reading Head :";
  if ((p_s7Client_ == NULL))  {
    std::cerr << "TSnap7Client is not connected.\n";
  }

  res = p_s7Client_->DBRead(nb_db_num_, 0, k_header_size, (void *)(&buffer_));    
  //synchronous mode: default mode
  //inFile.read(buffer_, sizeof(buffer_));
  memcpy(&local_PLCData.bHeader_Trigger, buffer_, 1);
  memcpy(local_PLCData.MachineTimeStamp, buffer_ + 2, 8);
  memcpy(&local_PLCData.Header_MachineID, buffer_ + 10, 12);
  memcpy(&local_PLCData.Header_Station, buffer_ + 22, 12);
  memcpy(&local_PLCData.Header_MessageID, buffer_ + 34, 2);
  memcpy(&local_PLCData.Header_MessageSequenceNo, buffer_ + 36, 2);
  memcpy(&local_PLCData.Header_NumberOfProperties, buffer_ + 39, 2);
  memcpy(&local_PLCData.MeasurementType, buffer_ + 40, 2);
  memcpy(&local_PLCData.Response_Acknowledge, buffer_ + 42, 1);

  nb_props = local_PLCData.Header_NumberOfProperties;
  _b_read_trigger = local_PLCData.bHeader_Trigger;

  return local_PLCData.Header_NumberOfProperties;
}

此代码现在适用于我,并在我调用GetHeader时解决了我的目的。正如大家所见,它正在寻找PLC的确切字节和结构。我想建立一个系统,使得结构可以从一个文件制作,以便应该替换文件,然后系统应该自己工作。我想我可以探索一些关于工厂设计模式的事情来做到这一点。现在我可以为我的数据结构构建确定文件的类型和文件的内容。有没有人在那边做过类似的事情。

3 个答案:

答案 0 :(得分:0)

不可能在运行时构建C ++数据类型,因为C ++是一种静态类型语言。您最好使用Python或其他动态类型语言。但是,如果您将问题视为查找与键关联的值的任务,那么它是可行的,但结果是&#34;结构&#34;将无法与静态定义的C ++类型一样快。

对于单级结构(没有子结构),您可以使用任何类型的key-&gt;值类,您可能需要这些类:std::map<std::string, std::pair<type, std::uniq_ptr<...>>>。也就是说,作为字符串的键被映射到第一对成员标识值的类型的对,第二对包含指向值本身的通用指针。如果您希望支持的类型数量有限,则可以编写动态调度程序,以对存储值的实际数据类型进行引用。

如果允许输入类型包含子结构,事情会变得更加复杂。但鉴于存在半结构化数据的语言(参见XML,JSON等),您可以找到适用于任意复杂结构化数据的现成解决方案。

答案 1 :(得分:0)

嗯,你几乎总能做点什么 - 但你可能会使用错误的语言。 C ++是强类型的,正如Max指出的那样 - 其他语言,例如,PHP不是 - 并且实际上可以改变类型。你可以做什么,就像滚动你自己的语言一样,是覆盖你的数学运算符,如+, - 等,这样你就有了一个基类来获取数据 - 并确定它是浮点数,字符串,整数等等然后你使用的对象就像是一个数字。它们都将是你结构中的对象,但是数学的覆盖等等。很多工作要做 - 但是有关于重写数学运算符等的例子。

答案 2 :(得分:0)

正如其他人所说,它无法完成,至少不会以最终结构或类的方式使用具有正确类型的成员变量。

您可以做的是解析文件并从值的格式猜测数据类型,然后创建相应的类型(您必须为要支持的所有类型实现该类型),最后定义数据结构它存储具有不同类型的所有值(例如,位置为索引的向量,并使用boost :: any作为值)。

作为旁注:
请注意,您可以在同一位置使用不同类型的值,例如如果一个值一次写为'123',一次写为'83 .45'。第一个值可能存储为某种整数,而第二个值则会产生浮点数或双精度。