按名称访问结构变量

Posted

技术标签:

【中文标题】按名称访问结构变量【英文标题】:Access struct variable by its name 【发布时间】:2016-03-15 01:39:49 【问题描述】:

我正在尝试创建可以处理 CSV 文件中提供的数据的程序。

到目前为止,我已经制作了这个 CSV 文件的结构,并且能够用它的数据填充向量。

我试图实现的是允许用户输入传感器名称并使用给定的传感器列表进行检查。

我想要做的是在用户输入传感器名称后,使用数据访问已经创建的向量并显示该特定传感器的数据。

这是我制作的结构:

typedef struct SensorReadings 
    int Month;
    int Day;
    double Dp;                  // Dew Point Temperature
    double Dta;                 // Wind Direction (10min Avg)
    double Dts;                 // Wind Direction (10min SD)
    double EV;                  // Evaporation (Year to Date)
    double QFE;                 // Barometric Pressure
    double QFF;                 // Barometric Pressure (QFE*Kqff)
    double QNH;                 // Barometric Pressure (Aviation Standard)
    double RF;                  // Rainfall (Year to Date)
 SensorReadings;

这是代码,我提示用户输入传感器名称:

std::cout << std::endl << std::endl << "Available Sensors: " << std::endl;
std::cout << "Dp Dta Dts EV QFE QFF QNH RF" << std::endl  << std::endl;
do 
    std::cout << "Please select Sensor you want to work with: ";
    std::cin >> selectedSensor;

    isSensorValid = std::find(std::begin(availableSensors), std::end(availableSensors), selectedSensor) != std::end(availableSensors);
 while(!isSensorValid);

我还做了一个方法来获取全年数据的平均每日价值:

double getAverageReadings(int wDay, int wMonth) 
    std::vector<SensorReadings> pData = fm.parsedFile;
    double DewPointTemperature = 0.0;
    for(int r = 0; r < pData.size(); r++) 
        if(pData[r].Month == wMonth) 
            if(pData[r].Day == wDay) 
                if(pData[r].Dp >= 100)
                    DewPointTemperature = DewPointTemperature + cWTKW(pData[r].Dp);
            
        
    
    return DewPointTemperature;

此功能允许我获取 露点温度 的每个月每一天的日平均值,我想做的是能够做类似的事情这个:

double getAverageReadings(int wDay, int wMonth, std::string selectedSensor) 
    /*
        Magic to convert std::string to actual Structure parameter
        Pseudo: 
        param Sensor = convert(selectedSensor, to SensorReadingsParam);
    */
    std::vector<SensorReadings> pData = fm.parsedFile;
    double averageReadingsForSensor = 0.0;
    for(int r = 0; r < pData.size(); r++) 
        if(pData[r].Month == wMonth) 
            if(pData[r].Day == wDay) 
                if(pData[r].Sensor >= 100)
                    averageReadingsForSensor = averageReadingsForSensor + cWTKW(pData[r].Sensor);
            
        
    
    return averageReadingsForSensor;

我以前从未使用过“动态”参数,所以我在寻求帮助。

感谢您的关注以及对此主题的任何帮助!

【问题讨论】:

【参考方案1】:

您有两个基本选择:

    不要为每个“传感器”声明一个显式变量,而是使用std::map

    typedef struct SensorReadings 
        int Month;
        int Day;
        std::map<std::string, double> sensor_value;
     SensorReadings;
    

并将每个传感器值存储在地图中,以传感器名称为键,即sensor_value["Dp"]sensor_value["Dta"] 等。

然后,给定一个传感器名称std::string sensor_name,您可以轻松地在地图中查找该传感器的值(当然,在检查它是否存在之后)。

    第二个选项是维护一个单独的传感器名称列表,以及指向相应类成员的指针,例如:

    static struct 
       const char *name;
       double SensorReadings::*value;
     sensor_names[]=
        "Dp", &SensorReadings::Dp ,
        "Dta", &SensorReadings::Dta ,
    ;
    

您可以使用此表将传感器名称映射到类成员。这有点丑陋,但它是可行的。我更喜欢使用第一个选项,我自己。

【讨论】:

感谢您的快速回复。但是,内存使用存在一个小问题。它从 14Mb 上升到 173Mb,处理时间从 27 秒变为现在未知(仍在运行)。有趣的是,解析是在 8 核 CPU 上进行的。也许我已经注意到 csv 文件包含大约 500k 行,平均行长为 105-130 个符号 是的,也许你应该提到这一点。这就是为什么我给出了第二个选项,它不需要更改类,以换取更多的工作来按名称访问类成员。另一种可能是您加载此数据的代码效率不高。 是的,现在尝试一下,我会在脚本升级完成后将问题标记为已回答(希望它能正常工作)

以上是关于按名称访问结构变量的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript对象:按名称作为字符串访问变量属性[重复]

如何使用字段名称的变量访问命名元组的字段?

如何按名称过滤键,然后使用 jq 访问嵌套对象

访问结构体的成员

C语言结构体变量字节对齐问题总结

当从扩展符号访问对象时如何访问 Javascript 对象的嵌套按名称属性...?