从Vector生成类数据成员 [英] Generating class datamembers from a Vector

查看:71
本文介绍了从Vector生成类数据成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下C ++问题:

Please consider this C++ question:

#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;

class ParseURL{
    private:
        int qualify; // 0 means we qualify
    public:
        string node;
        string service;
        bool primary;
        bool health;
        string epoch;
        // methods
        ParseURL(string URL);
        ~ParseURL();
};


ParseURL::ParseURL(string URL){
    vector<string> g2 = {"node", "service", "primary", "health", "epoch"};

    for (string tag : g2){
        auto found = URL.find(tag);
        if ( found != string::npos ){
            auto cut_from = found + 1 + tag.size() ;
            auto meh = URL.substr(cut_from, URL.substr(cut_from).find("&") );
            // is there a way we can avoid these lines below?
            if (tag.find("node",0) == 0){
                this->node = meh;
            } else if (tag.find("service",0) == 0 ){
                this->service = meh;
            } else if (tag.find("epoch",0) == 0) {
                this->epoch = meh;
            } else if (tag.find("health",0) == 0){
                this->health = (meh == "OK");
            } else if (tag.find("primary",0) == 0 ){
                this->primary == (this->node == meh);
            }
        }
    }

}

ParseURL::~ParseURL(){
    cout << "Tearing Down the class\n";
}
int main(){
    char req[] = "GET /register?node=hostrpi3&service=potatoservice&primary=node1&health=OK&epoch=1559345106 HTTP";
    string Request = req;
    Request = Request.substr(Request.find_first_of(" ") );
    Request = Request.substr(0, Request.find(" HTTP"));
    ParseURL *a = new ParseURL(Request);

    cout.width(12);
    cout << "a->node: " << a->node << endl;
    cout.width(12);
    cout << "a->service: " << a->service << endl;
    cout.width(12);
    cout << "a->epoch: " << a->epoch << endl;
    cout.width(12);
    cout << "a->health: " << a->health << endl;
    cout.width(12);
    cout << "a->primary: " << a->primary << endl;

    delete(a);

    return 0;
}

我需要基于URL查询字符串表示一个对象,我需要这些标签用向量g2表示,如您所见,我在这些标记中为 ParseURL 制作了数据成员。

I need to represent a object based on URL Query Strings, the tags I need are represented in vector g2, and as you can see, I make datamembers for ParseURL out of those tags.

o / p如下:

   a->node: hostrpi3
a->service: potatoservice
  a->epoch: 1559345106
 a->health: 1
a->primary: 0
Tearing Down the class

尽管此版本有效,但仍可以改进。尽管在Vector中具有所有功能,但我还是对每个这些属性重复执行 tag.find 。我希望一定有更好的方法。您能指出正确的方向吗?谢谢!

Although this version works, it feels this can be improved much. Despite having it all in the Vector, I am repeatedly doing tag.find for each of those attributes. There must be a better way, I hope. Could you please point in the right direction? Thanks!

编辑1

谢谢,我按照以下建议更新了构造函数:

Thanks, I updated the constructor following the suggestions:

ParseURL::ParseURL(string URL){
    char tags[10][100] = {"node", "service", "primary", "health", "epoch"};

    int i = 0;
    for (auto tag : tags){
        auto found = URL.find(tag);
        if ( found != string::npos ){
            auto cut_from = found + 1 + strlen(tag);
            auto tag_info = URL.substr(cut_from, URL.substr(cut_from).find("&") );
            switch (i){
                case 0:
                    this->node = tag_info; 
                    break;
                case 1:
                    this->service = tag_info; 
                    break;
                case 2:
                    this->primary = (this->node == tag_info); 
                    break;
                case 3:
                    this->health = (tag_info == "OK"); 
                    break;
                case 4:
                    this->epoch = tag_info; 
                    break;
            }
        }
    i++;
    }
}

bash提供了变量的间接引用-是,一个变量可能包含另一个变量的名称:

bash for example, offers indirect reference of variables - that is, one variable may contain the name of another variable:

$ cat indirect.sh 
#!/bin/bash 

values="value1 value2"
value1="this is value1"
value2="this is value2"

for i in $values; do 
    echo "$i has value ${!i}"
done

$ ./indirect.sh 
value1 has value this is value1
value2 has value this is value2

我一直希望类似的情况存在,但我了解到这里有价值的教训。谢谢!

I was hoping something similar exists for cases like this, nevertheless, I learned valuable lessons here. thank you!

推荐答案

我相信问题可以分解:


  • URL解析,然后

  • 将结果分配给对象数据成员。

regex提供了紧凑而强大的解决方案,用于将URL键值对(参数)提取到地图中。

regex gives compact and robust solution for extracting URL key value pairs (parameters) into map:

#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <regex>

using namespace std;

int main()
{
    map<string, string> keyValues;
    string s = "GET /register?node=hostrpi3&service=potatoservice&primary=node1&health=OK&epoch=1559345106 HTTP";
    regex keyValueRegex("[?&](\\w+)=(\\w+)");
    auto pairsBegin = std::sregex_iterator(s.begin(), s.end(), keyValueRegex);
    auto pairsEnd = std::sregex_iterator();

    for (std::sregex_iterator i = pairsBegin; i != pairsEnd; ++i)
    {
        std::smatch match = *i;
        keyValues[match[1]] = match[2];
    }

    for (auto p : keyValues)
    {
        cout << p.first << " " << p.second << endl;
    }
}

给出输出:

epoch 1559345106
health OK
node hostrpi3
primary node1
service potatoservice

另一种方法(用于非常精细的URL解析)是使用cpp-netlib库(建议用于Boost包含)。

Another approach (for very granular URL parsing) is using cpp-netlib library (proposed for Boost inclusion).

这篇关于从Vector生成类数据成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆