Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сравнить типы (структуры)? Как сравнить для типы (структуры) 
:(
    Опции темы
mephistotel77
Дата 20.5.2010, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 12.4.2010

Репутация: нет
Всего: нет



Добрый день. Есть такой код: СИшный
test_sev.h
Код

typedef struct _valcfg
{
   const char *name; // Имя параметра
   const char *value; // Значение параметра
   const char *opttype; // Тип параметра
} valcfg;

typedef struct _config
{
   valcfg *cmd;      // Команда
   valcfg *cnffile;   // Путь к конфигу
   stack *ipstack;  // Указатель на список структур, содержащих IP-адреса 
   valcfg *genport; // Порт для адресов
} config;

typedef struct _stack
{
   ipconfig *val; // Указатель на структуру
   stack *next;  //Указатель на след.элемент
} stack;

typedef _ipconfig
{
   const char *ipaddr; // Указатель на строку, содерж. IP
   const char *ipport;  // Указатель на строку, содерж. порт
} ipconfig;
valcfg* findvalcfg(config *cfg, char *val); 

Необходимо реализовать функцию findvalcfg,  которая на вход принимает строку val и конфиг, в котором надо искать. 
Естественно, что логика такая:
Пройтись по всех указателям, если указатель указывает на тип valcfg, то 
Код

if (cfg->valcfg.value == val)
{
   // Что-то делаем
}

если указывает на что-то другое (на ipconfig), то пропускаем.
Как это можно реализовать? А точнее, как мне узнать на какой типа указывает указатель и как сравнить два типа, чтобы узнать что это нужный тип valcfg, а не ipconfig.
PS:
Для лучшего понимания объясню предысторию. Хочется "умно" разбирать опции командой строки.
1. Перемена мест опции не влияла на выполнение программ (а с getopt это не так)
2. Учитывался приоритет:
   а) приоритет у опций командной строки наивысший
   б) опции, взятые из файла не могут перезатирать опции командной строки, но могут затирать встроенные в программу опции (забитые в коде)
   в) опции, забитые в коде имеют низший приоритет
И хочется делать, например, так:
test -i 192.168.1.1:8080 192.169.2.2 192.168.1.3:1835 192.168.2.4 -p 9999
где -i - IP-адреса в формате [IP-адрес] или [IP-адрес:порт]
       -p - порт, применяется только для тех IP-шников, у которых не задан IP
Таким образом у 192.169.2.2 и 192.168.2.4 будет порт 9999.
Проблема возникает, когда мы получаем опции из файла в формате <имя_перем> <значение> 
(например ipaddr 192.168.3.4). Т.к. строку ipaddr надо сравнить с полями value, для этого нужно пробежаться по структуре config.

Это сообщение отредактировал(а) mephistotel77 - 20.5.2010, 17:20
PM MAIL   Вверх
djamshud
Дата 20.5.2010, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



Если си, в начало каждой структуры можно положить инт - значение типа.
Код

enum {IFCONFIG,SYSCONFIG,BLABLABLA,...};

struct ifconfig{
int type;
...
};

...

struct ifconfig ifconfig={IFCONFIG,...};
struct sysconfig sysconfig={SYSCONFIG,...};


В плюсах можно много проще: базовый класс конфиг, от него наследники. Проверка на тип:
Код

if(dynamic_cast<ifconfig*>(conf_object)!=0){that is ifconfig struct;}


Это сообщение отредактировал(а) djamshud - 20.5.2010, 16:54


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
mephistotel77
Дата 20.5.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 12.4.2010

Репутация: нет
Всего: нет



Т.е. я правильное понял, что вы предлагаете сделать что-то вроде:
Код

config *cfg;
while (((*cfg)++) != NULL) // Кстати... эта строчка сработает? 
                                   // Можно перемещаться по структуре, содер. разные типы|структуры в теле, через указатель?
{
   if (*cfg.type == VALCFG)
   {
   
   }
   // если if (*cfg.cmd) или if (*cfg.genport) - то значит мы уже знаем тип, раз получаем его поле. 
   //
}

Верно? А нет каких-то способов попроще?
И если есть предложения по изменению самих структур... может стоит  переписать базовые структуры, 
с удовольствием выслушаю мнения по этому поводу, чтобы не делать таких "хуков".
PM MAIL   Вверх
djamshud
Дата 20.5.2010, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



>с удовольствием выслушаю мнения по этому поводу, чтобы не делать таких "хуков".

Я честно говоря вообще не очень понял, зачем так сложно разбирать argv. То есть, зачем - понял, почему так - нет. На все флаги легко можно среагировать и одним простым проходом по аргументам. Когда-то я писал это, найду - выложу.

>Кстати... эта строчка сработает?

Что такое config *cfg не понятно... Если это буфер, куда друг за дружкой вкатаны структуры, то нет. Нужно читать первые четыре байта, опрелять тип и привести текущий кусок с нему, дальше уже и работать. Потом опять вытаскивать тип и т.д., пока не пройдетесь по всему буферу. Но эта задача для вас, как я понимаю, будет весьма сложна. Лучше перепроектирвать.

>Можно перемещаться по структуре, содер. разные типы|структуры в теле, через указатель?

Можно, но проще привести "непонятный указатель" к указателю на конкретную структуру, а дальше работать с обычными полями.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
mephistotel77
Дата 20.5.2010, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 12.4.2010

Репутация: нет
Всего: нет



Что такое 
Код
config *cfg
 описано в коде в первом сообщении:
Код

typedef struct _config
{
   valcfg *cmd;      // Команда
   valcfg *cnffile;   // Путь к конфигу
   stack *ipstack;  // Указатель на список структур, содержащих IP-адреса 
   valcfg *genport; // Порт для адресов
} config;

В структуре забиты указатели на те опции, которые есть у программы и которые разбираются. 
cfg - это указатель на структуру, которая содержит все конфигурационные параметры (аргументы программы и т.п.). Т.е. фактически 
это список указателей на структуры. 
Так можно (*cfg)++ сделать? 
Просто cfg++ как я понял просто перепрыгнет на след. такую структуру, которой на самом деле нет.

Она заполняется не только из командной строки, но также и из файла, если указать опцию -f. 

При этом надо учитывать, что сначала могут сохраняться опции командной строки в конфиг, а потом читаться конфигурационный файл, который может некоторые настройки перезаписать (например вшитые), но не может перезаписывать опции из командной строки. Поэтому структура так усложнилась. Но я, конечно, с удовольствием посмотрю на лучшую реализацию. Особенно если она делает аналогичные по функциональности вещи.
PM MAIL   Вверх
djamshud
Дата 20.5.2010, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 8
Всего: 39



>Просто cfg++ как я понял просто перепрыгнет на след. такую структуру, которой на самом деле нет.

Так нельзя. Чтобы делать так, в си организует некое подобие наследования.

Код

struct base{
int type;
};

struct ipconfig{
int type;
char *....
....
};


Потом создается массив указателей на base, в который на самом деле вносят указатели на нужные структуры. Ну а дальше все просто: проходимся по массиву, смотрим тип, приводим указатель к нужной структуре и вуаля.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
KOHCEPBATOP
Дата 20.5.2010, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 21.4.2010

Репутация: нет
Всего: 1



Цитата(djamshud @  20.5.2010,  19:56 Найти цитируемый пост)
struct base{
int type;
};


Можно еще так
Код

struct base{
   int type; // тип структуры
   int size; // размер структуры
};

Тогда реализовать переход к следующему экземпляру будет проще.

Код

char * ptr = (char*)...;
while(1)
   {
   base * pbase = (base *)ptr;
   if (pbase->type == ENDCFG) // последний элемент
      {
          break;
      };
   switch(pbase->type )      {
   case VALCFG:
      {
         valcfg * pvalcfg = (valcfg*)ptr;
         ........
      };
       break;
   case STACKCFG:
      {
         stackcfg * pstackcfg = (stackcfg*)ptr;
         ........
      };
      break;
   };
   ptr += pbase->size; // перемещаемся на следующую структуру
};


PM MAIL   Вверх
mephistotel77
Дата 24.5.2010, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 12.4.2010

Репутация: нет
Всего: нет



Спасибо большое. М-да... сразу понимаешь все прелести ООП=)) На C такие извраты получаются...=((
Тему пока не закрываю, пока буду допиливать прогу, может кто (или сам) что дополнит. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1031 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.