将枚举与字符串变量一起使用

发布于 2024-08-20 04:31:02 字数 776 浏览 3 评论 0原文

我正在尝试做这样的事情,

enum Data_Property
{
 NAME,
 DATETIME,
 TYPE,
};

struct Item_properties
{
  char* Name;
  char* DateTime;
  int Type;  
};

int main() {  
std::string data = "/Name Item_Name /DATETIME [TimeStamp] /TYPE [Integer value]";
std::list <std::string> known_properties;

known_properties.push_back("/Name");
known_properties.push_back("/DATETIME");
known_properties.push_back("/TYPE");

Item_properties item_p = extract_properties(data); //I use a function to get properties
                                                   //in a structure.

//here I want to use a switch-case statement to get the property by enum value
}

我需要知道有什么方法可以让它变得简单吗?或者我如何将 (/NAME /DATETIME /TYPE) 等属性键与枚举结合起来并避免使用 std::list 即known_properties?

I'm trying to do something like this,

enum Data_Property
{
 NAME,
 DATETIME,
 TYPE,
};

struct Item_properties
{
  char* Name;
  char* DateTime;
  int Type;  
};

int main() {  
std::string data = "/Name Item_Name /DATETIME [TimeStamp] /TYPE [Integer value]";
std::list <std::string> known_properties;

known_properties.push_back("/Name");
known_properties.push_back("/DATETIME");
known_properties.push_back("/TYPE");

Item_properties item_p = extract_properties(data); //I use a function to get properties
                                                   //in a structure.

//here I want to use a switch-case statement to get the property by enum value
}

I need to know is there any way i can make it any simple? or how would i combine property keys like (/NAME /DATETIME /TYPE) with an enum and avoid using a std::list i.e known_properties?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

流年已逝 2024-08-27 04:31:02

据我所知,C++ 枚举中没有任何东西类似于 C# 枚举属性。但我可能是错的。

鉴于此,我建议使用映射将数据属性映射到项目属性。您只需构建此地图一次。您还可以将字符串表示形式与项目和数据属性相关联。这应该可以更轻松地构建项目属性对象。我认为列表不是完成此任务的理想数据结构。

As far as I know, there is nothing in C++ enums that is like C# enum attributes. I could be wrong though.

Given that, I'd suggest using a map to map the data property to item property. You should only have to build this map once. You can also associate the string representations to the item and data properties. This should make it easier to get the item properties objects built. I don't think a list would be an ideal data structure for this task.

情场扛把子 2024-08-27 04:31:02

首先,我要说的是,总有另一种选择,这是我的哲学之一。

让我们看一下大局。您正在尝试从字符串中读取ItemItem 是数据的容器。在面向对象的术语中,Item 希望每个数据从字符串中加载自己的数据。 Item 不需要知道如何加载数据,因为它可以从每个数据请求此信息。

您的数据实际上比 C++ 简单 POD 类型更复杂、更智能。 (简单的 POD 类型没有字段名称。) 因此,您需要创建类来表示这些(或封装额外的复杂性)。相信我,从长远来看,这会更好。

下面是重构 Name 成员的简单示例:

struct Name_Field
{
  std::string  value;  // Change your habits to prefer std:string to char *
  void load_from(const std::string& text,
                 const std::string::size_type& starting_position = 0)
  {
     value.clear();
     std::string::size_type position = 0;
     position = text.find("/Name", starting_position);
     if (position != std::string::npos) // the field name was found.
     {
         // Skip the next space
         ++position;

         // Check for end of text
         if (position < text.length())
         {
             std::string::size_t   end_position;
             end_position = text.find_first_not_of(" ", position);
             if (end_position != std::string::npos)
             {
                 value = text.substr(position, end_position - position);
             }
          }
      }
};

您现在可以将 load_from 添加到 Item 类:

struct Item
{
    Name_Field   Name;
    char *       DateTime;
    char *       Type;
    void load_from(const std::string& text)
    {
        std::string::size_t  position = 0;

        // Notice, the Name member is responsible for load its data,
        //    relieving Item class from knowing how to do it.
        Name.load_from(text, position);
    }
};

加载项目:

Item new_item;
new_item.load_from(data);

重构时,请注意常用方法。例如,您可能希望将 Name_FieldDateTime_Field 之间的通用方法放入基(父)类 Field_Base 中。这将简化您的代码和设计并支持可重用性。

First, let me say that there is always another alternative, one of my philosophies.

Let's look at the Big Picture. You are trying read an Item from string. The Item is a container of datums. In Object Oriented terms, the Item would like each datum to load its own data from a string. The Item doesn't need to know how to load a datum, as it can request this from each datum.

Your datums are actually more complex and intelligent than the C++ simple POD types. (Simple POD types don't have field names.) So, you need to create classes to represent these (or to encapsulate the extra complexity). Trust me, this will be better in the long run.

Here is a simple example of Refactoring the Name member:

struct Name_Field
{
  std::string  value;  // Change your habits to prefer std:string to char *
  void load_from(const std::string& text,
                 const std::string::size_type& starting_position = 0)
  {
     value.clear();
     std::string::size_type position = 0;
     position = text.find("/Name", starting_position);
     if (position != std::string::npos) // the field name was found.
     {
         // Skip the next space
         ++position;

         // Check for end of text
         if (position < text.length())
         {
             std::string::size_t   end_position;
             end_position = text.find_first_not_of(" ", position);
             if (end_position != std::string::npos)
             {
                 value = text.substr(position, end_position - position);
             }
          }
      }
};

You can now add a load_from to the Item class:

struct Item
{
    Name_Field   Name;
    char *       DateTime;
    char *       Type;
    void load_from(const std::string& text)
    {
        std::string::size_t  position = 0;

        // Notice, the Name member is responsible for load its data,
        //    relieving Item class from knowing how to do it.
        Name.load_from(text, position);
    }
};

To load the item:

Item new_item;
new_item.load_from(data);

As you refactor, be aware of common methods. For example, you may want to put common methods between Name_Field and DateTime_Field into a base (parent) class, Field_Base. This will simplify your code and design as well as support re-usability.

懷念過去 2024-08-27 04:31:02

你看过Boost::program_options吗?这是一些示例代码:

#include "boost\program_options\parsers.hpp"
#include "boost\program_options\variables_map.hpp"
#include <iostream>
using std::cout;
using std::endl;

namespace po = boost::program_options;

int _tmain(int argc, _TCHAR* argv[])
{

    po::options_description desc("Allowed options");
    string taskName;
    desc.add_options()
        ("help", "produce help message")
        ("TaskName", po::value<string>(&taskName), "The project's prefix")
    ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);    

    if (vm.count("help")) {
        cout << desc << endl;
        return 1;
    }
    if (!vm.count("TaskName"))
    {
        cout << "Use \"DOTaskTests.exe --help\" for command line options" << endl;
        return 1;
    }
 }

Have you looked at Boost::program_options? Here's some example code:

#include "boost\program_options\parsers.hpp"
#include "boost\program_options\variables_map.hpp"
#include <iostream>
using std::cout;
using std::endl;

namespace po = boost::program_options;

int _tmain(int argc, _TCHAR* argv[])
{

    po::options_description desc("Allowed options");
    string taskName;
    desc.add_options()
        ("help", "produce help message")
        ("TaskName", po::value<string>(&taskName), "The project's prefix")
    ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);    

    if (vm.count("help")) {
        cout << desc << endl;
        return 1;
    }
    if (!vm.count("TaskName"))
    {
        cout << "Use \"DOTaskTests.exe --help\" for command line options" << endl;
        return 1;
    }
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文