【问题标题】:How to read a file and build a Data Structure based on the input file using C++?如何使用 C++ 读取文件并基于输入文件构建数据结构?
【发布时间】:2018-02-14 14:38:47
【问题描述】:

我想这应该是可能的。我试过但找不到一个好的答案。我基本上想制作一个动态结构。我想读取一个文件,它告诉我我的结构将包含的数据类型。基于这些价值观,我想建立一个结构。我想为此使用 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 中寻找准确的字节和结构。我想制作一个系统,以便可以从一个文件中制作结构,这样只有一个文件应该被替换,然后系统应该自己工作。我想我可以探索一些关于工厂设计模式的事情来做到这一点。现在我可以确定我的数据结构构造的文件类型和文件内容。有没有人在那边做过类似的事情。

【问题讨论】:

  • 我觉得不可能,C++在编译时需要知道类型;这里有一些答案说您可以使用 boost 变体和其他元编程技巧。
  • 你需要某种方式来表示每种类型的数据和一个容器来保存它。
  • 你尝试了哪些方法,又是如何失败的?
  • 在互联网上搜索“c++ 工厂设计模式”。
  • @ThomasMatthews:谢谢,是的,我实际上正在寻找那个答案。我正在努力。如果您有任何可以解决我的问题的好例子,请指导我。

标签: c++ data-oriented-design


【解决方案1】:

不太可能在运行时构建 C++ 数据类型,因为 C++ 是一种静态类型语言。您最好使用 Python 或其他动态类型语言。但是,如果您将此问题视为一项与键关联的值的任务,这是可行的,但生成的“结构”将远不及静态定义的 C++ 类型。

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

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

【讨论】:

  • 我也想到了键值对的想法。感谢您的指导。谢谢。我已经用我目前正在做的代码更新了我的问题
【解决方案2】:

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

【讨论】:

  • 是的,我已经在 python 中完成了。但目前在我的项目中,我需要用 C++ 来完成。 :(
【解决方案3】:

正如其他人所说,这是不可能的,至少不能以最终得到具有正确类型的成员变量的结构或类的方式。

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

附注:
请注意,您最终可能会在同一位置获得不同类型的值,例如如果一个值曾经被写为“123”,一次被写为“83.45”。第一个值可能会存储为某种整数,而第二个值可能会导致浮点数或双精度数。

【讨论】:

  • 谢谢。是的,我现在有了一个想法。我将从文件中获取数据类型名称和字节数,并按照大家建议的方式处理它。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2012-07-02
  • 2021-02-13
  • 1970-01-01
相关资源
最近更新 更多