доступ к элементу структуры - командная строка - PullRequest
0 голосов
/ 22 октября 2010


это может быть простой проблемой, но я не могу понять это.У меня есть такая структура.

<code>
struct emp 
{
  int empid;
  string fname;
}
emp e[10];

У меня есть некоторые данные в e [10].

<code>
e[0].empid = 1 , e[0].fname = "tanenbaum"
e[1].empid = 2 , e[1].fname = "knuth"
.....

Теперь, если я дал такую ​​команду ввода, как это:

<code>
emp , empid

Теперь мне нужно получить доступ к структуре emp.empid.Если у меня есть 10 других структур, мне нужно получить к ним доступ, когда входные данные дают одинаковый тег структуры и член структуры.Здесь я не могу понять, как присоединить строковые переменные (emp, empid) к элементам структуры (emp.empid).заранее спасибо. РЕДАКТИРОВАТЬ Вот моя программа.

<code>
int main(int argc, char *argv[])
{
  char *tag_name = argv[1]; //emp (structure tag name)
  char *member_name = argv[2]; // empid (structure member name)
  int data = argv[3]; //value: 2
  /* I need some mechanism that will convert those tag_name.member_name
     to original structure memmber access<br>
     tag_name(emp).member_name(empid) == value (2)
     Is there any way to map like this
*/
return ;
}

Ответы [ 3 ]

1 голос
/ 22 октября 2010
  1. Создайте базовый класс для обработки вашей структуры.Назовите его QueryHandlerBase.

  2. Извлекайте классы для каждого типа структуры, которую вы хотите запросить.Для emp это может называться EmpQueryHandler.

  3. Создать карту между именами структур и обработчиками:

std::map<std::string, QueryHandlerBase *>

  1. Передать запрошенное имя структуры на карту, чтобы получить указатель на обработчик.

  2. Передать запрошенное имя поля в обработчик.Он будет предназначен для того, чтобы знать поля этой конкретной структуры и делать с ней что-то полезное (например, отображать записи и т. Д.).идет ...

    #include <iostream>
    #include <map>
    #include <vector>
    #include <string>
    
    struct emp 
    {
      int empid;
      std::string fname;
    };
    
    class QueryHandlerBase
    {
    public:
    
        virtual void FieldQuery(std::string const &FieldName,
                                std::string const &FieldVal) = 0;
    
    };
    
    class EmpQueryHandler : public QueryHandlerBase
    {
    public:
    
        void AddRecord(int empid, std::string const &fname)
        {
            emp x;
    
            x.empid = empid;
            x.fname = fname;
    
            m_DataVec.push_back(x);
        }
    
        virtual void FieldQuery(std::string const &FieldName,
                                std::string const &FieldVal)
        {
            std::vector<emp>::iterator i;
            i = m_DataVec.begin();
    
            while (i != m_DataVec.end())
            {
                if (FieldName == "empid")
                {
            // do something useful
                }
    
                if (FieldName == "fname")
                {
                    // do something useful
                    if ((*i).fname == FieldVal)
                    {
                        std::cout << (*i).empid << " " << (*i).fname << std::endl;
                    }
                }
    
                ++i;
            }
        }
    
    private:
        std::vector<emp>    m_DataVec;
    };
    
    
    int main()
    {
        std::map<std::string, QueryHandlerBase *> tables;
        EmpQueryHandler *pEmp = new EmpQueryHandler;
    
        // make a map entry for your database table
        tables["emp"] = pEmp;
    
        // populate some records
        pEmp->AddRecord(1, "Bob");
        pEmp->AddRecord(2, "Shiela");
        pEmp->AddRecord(3, "Elroy");
        pEmp->AddRecord(4, "Victoria");
    
        // perform a query
        tables["emp"]->FieldQuery("fname", "Shiela");
    
        return 0;
    }
    
1 голос
/ 22 октября 2010

РЕДАКТИРОВАТЬ: Используя указатель на член-оператор, вы можете достичь того, что вы хотели.Вам нужно создать небольшую базу данных, используя std :: map.

Ниже приведена рабочая программа.

#include <iostream>
#include <string>
#include <map>
using namespace std;
struct emp 
{
  int empid;
  int salary;
};

int main(int argc, char *argv[])
{
    //member map stores member varialbe names and corresponding offsets.
    map<string, int emp::*> memberMap; //It can store offsets of only integer members.

    //tagMap stores tag names and object pointer
    map<string, emp *> tagMap;

    //Allocate for 10 records
    emp *e = new emp[10];
    //Store sample data in those records.
    for(int i = 0; i < 10; i++)
    {
        e[i].empid = (i+1) * 10;
        e[i].salary = (i+1) * 1000;
    }

    //Populate tag map with tag names and corresponding object pointers
    //As of now, we have only emp structure.
    //You can add more structures similar to below.
    tagMap.insert(pair<string, emp *>("emp", e));

    //Get the offsets of member variables of emp structure.
    int emp::*offset_empid = &emp::empid;
    int emp::*offset_salary = &emp::salary;

    //Populate member map with member names and corresponding offsets
    memberMap.insert(pair<string, int emp::*>("empid", offset_empid));
    memberMap.insert(pair<string, int emp::*>("salary", offset_salary));

    //Am passing tag name in argv[1], member name in argv[2] and record id in argv[3] from
    //command line
    string tagName = argv[1]; //tag name
    string memberName = argv[2]; //member name
    int recordId = atoi(argv[3]);//record id

    //Access member specified like below.
    cout<<"Employee details requested are : "<<endl;
    cout<<memberName<<"\t"<<(tagMap[tagName]+recordId)->*memberMap[memberName];

    //Free the allocated memory.
    delete []e;
}

Ввод:

emp salary 2

Вывод:

Запрашиваемая информация о сотруднике: зарплата 3000

Я надеюсь, что вы можете понять программу, используя комментарии, которые я написал.

Входные данные: я предоставляю tagName, fieldName и recordId.

Выходные данные: я получаю запрошенное значение поля из запрошенного идентификатора записи.

1 голос
/ 22 октября 2010

По сути, вы должны создавать ассоциации в своем коде.Разобрать входные данные в значениях структуры / поля (например, inputtringstream >> структура >> разделитель >> поле), а затем получить что-то вроде:

if (structure == "emp")
    if (field == "empid")
        ...do something with emp[which_one].empid...
...

Если вам необходимо отделить эти шаги разрешения ссылки откод, который использует значения, тогда вы можете захотеть, чтобы приведенный выше код (то есть «сделать что-то») установил функтор, который вы можете вызывать позже, когда вам нужно фактическое значение.При таком же подходе вы могли бы потенциально улучшить каждую структуру с помощью API, который знает о ее полях:

struct Emp
{
    // boost::any can directly return an int, string, double etc...
    // you could hack your own union to do this if you needed, or provide
    // some common base class around these types
    boost::any get(const std::string& identifier) const;

    // this one might use std::ostringstream to convert any non-string fields
    // into a textual representation, but e.g. you can loose precision
    // from floating point values
    std::string get(const std::string& identifier) const;
};

Затем вы можете поместить различные методы доступа в одну карту ...

struct Field_Access
{
    virtual boost::any get(const std::string& identifier) const = 0;

    virtual bool set(const std::string& identifier, const std::string& value) = 0;
    virtual bool set(const std::string& identifier, const int& value) = 0;
};

struct Emp : Field_Access
{
    ...
};

std::map<std::string, Field_Access*> accessors;

... populate accessors ...
accessors["emp"] = emp;

accessors["emp"][which_one].get("empid");

Возможности довольно безграничны, и ваш вопрос недостаточно конкретен, чтобы дать очень целеустремленный совет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...