На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Как перебрать элементы структуры
    Есть например структура, где все элементы POD. Как перебрать в цикле элементы структуры ?

    Нигде не нашел ответа. Вернее много ответов, что нет надежного способа.
    Есть вариант написать макрос, но по-моему это как-то не спортивно ))

    http://qaru.site/questions/130341/is-there...rent-types-in-c
      Цитата Mr.Brooks @
      Есть вариант написать макрос, но по-моему это как-то не спортивно ))

      А перебирать в цикле элементы структуры спортивно? :D

      Мне просто интересно стало - а зачем такое понадобилось?

      Добавлено
      Заведи себе какой нибудь union и запихни его в массив, и перебирай. Ну это конечно если мой скилл "телепатия" не сбойнул.

      Добавлено
      Про какой нибудь union можешь тут почитать(первое что выдал гугл по запросу union) https://ru.stackoverflow.com/questions/6235...%B8%D0%B5-union
      Сообщение отредактировано: KILLER -
        Цитата
        Мне просто интересно стало - а зачем такое понадобилось?

        Это в продолжение темы Undo - Redo
        Правило: один вопрос - один топик, вот и соблюдаю.

        Я хочу структуру уменьшить в размере за счет того, что например поле char name[64]; может содержать 64 байта а реально содержит нужных пусть 15.
        некоторые поля вообще не задействованы =0 для конкретного случая. Получается что можно сохранить текущее мгновенное состояние структуры с большой экономией.
        Для чего уменьшать - см. тему Undo - Redo
        Для чего перебор полей структуры - если я напишу функции StructureToString() и StringToStructure() то удобно чтобы они перебирали все элементы.
        Тогда внесение изменений в структуру (добавление новых полей) не потребует переделки этих функций.
        Сообщение отредактировано: Mr.Brooks -
          Цитата Mr.Brooks @
          Я хочу структуру уменьшить в размере за счет того, что например поле char name[64]; может содержать 64 байта а реально содержит нужных пусть 15.
          некоторые поля вообще не задействованы =0 для конкретного случая. Получается что можно сохранить текущее мгновенное состояние структуры с большой экономией.

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

          Цитата Mr.Brooks @
          Это в продолжение темы Undo - Redo

          Сорри, не читал. По этому не в теме. :unsure: Если будет время, гляну.

          Добавлено
          Цитата Mr.Brooks @
          если я напишу функции StructureToString() и StringToStructure() то удобно чтобы они перебирали все элементы.

          У тебя сколько элементов в структуре? Обычно структура представляет из себя некий блок данных, которые сгруппированы в один тип по общему признаку.
          Например там структура:
          ExpandedWrap disabled
            struct Patient
            {
            fname
            lname
            sname
            age
            billingcode
            addresss
            phone
            altphone
            ...
            };

          Таких полей может быть очень много, и структура может быть вполне себе POD типом. Ну будет она допустим в сумме(sizeof если натравить) весить к примеру 5 килобайт. Дальше ты смотришь - если тебе критично по памяти, значит ты либо что то урезаешь, либо извращаешься с указателями.
          Но один хрен, это никакой не массив, и типы данных могут быть разные. Как ты собрался преобразовывать в цикле например int в string ? Как ты поймешь что ты работаешь с типом Int? Я просто не понимаю что ты хочешь сделать. Ну уменьшить размер структуры - ладно, это понятно. Но как тебе поможет перебор полей структуры чтобы преобразовать ее в String? Вообще то это нужно каждое поле отдельно сериализовывать, либо писать всю структуру в string(тогда нафиг там цикл нужен?). Что то я всеравно не понимаю что ты хочешь.
          Сообщение отредактировано: KILLER -
            Цитата KILLER @
            Тогда юзай не POD структуру, а структуру в которой каждое поле представляет из себя указатель на нужный тебе тип данных.
            Или, если не нужен оперативный доступ к данным (доступ редок или вообще может не состояться) можно использовать какой-нибудь метод сериализации с пропуском полей, имеющих значение по умолчанию. Или какой-нибудь другой способ упаковки/сжатия.
              Цитата
              Тогда юзай не POD структуру...

              Говорят POD структуру удобнее записать/прочитать с диска.
              Вот код который это должен делать (нашел на просторах интернета). Но не создается бинарник ??
              Создание именно бинарника это ключ к моей задаче. Если можно поля последовательно записать на диск, то значит можно записать и в память, или не так ?
              ExpandedWrap disabled
                #include <iostream>
                #include <fstream>
                #include <string.h>
                 
                using namespace std;
                 
                struct Structur
                { // в структуре всякая всячина :
                  char name[10];
                  int Int;
                  double Double;
                };
                 
                int main()
                {
                // заполняем структуры
                  Structur str[10];
                  for ( int i=0; i<10; i++ )
                  {
                    strcpy(str[i].name, "Structur");
                    str[i].Int = i;
                    str[i].Double = i/100.;  // точка после 100
                    cout<<str[i].name<<" "<<str[i].Int<<" "<<str[i].Double<<endl;
                  }
                  cout<<endl;
                 
                // запись в текстовый файл
                  ofstream fout("Text.txt");
                  for( int i=0; i<10; i++ )
                    fout<<str[i].name<<" "<<str[i].Int<<" "<<str[i].Double<<"\n";
                  fout.clear();
                 
                // запись в бинарный файл
                  fout.open("Bin.dat",ios_base::binary);
                  for ( int i=0; i<10; i++ )
                    fout.write((char *) &str[i], sizeof str[i]);
                  fout.close();
                 
                // считывание из текстового файла в структуры
                  ifstream fin("Text.txt");
                  for ( int i=0; i<10; i++ )
                  {
                    fin>>str[i].name>>str[i].Int>>str[i].Double;
                    cout<<str[i].name<<" "<<str[i].Int<<" "<<str[i].Double<<endl;
                  }
                  fin.clear();
                  cout<<endl;
                 
                //считываем из бинарного файла в структуру
                  fin.open("Bin.dat", ios_base::binary);
                  for ( int i=0; i<10; i++ )
                  {
                    fin.read((char*) &str[i], sizeof str);
                    cout<<str[i].name<<" "<<str[i].Int<<" "<<str[i].Double<<endl;
                  }
                  fin.close(); // <--- этой строки в оригинале не было я добавил, но ее добавление ни на что не повлияло
                  cin.get();
                  return 0;
                }

              Программа выполняется, студия не выдаёт ошибок, почему нет бинарника на диске ?
              Сообщение отредактировано: Mr.Brooks -
                Цитата Mr.Brooks @
                Есть например структура, где все элементы POD. Как перебрать в цикле элементы структуры ?

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

                Цитата Mr.Brooks @
                Я хочу структуру уменьшить в размере за счет того, что например поле char name[64]; может содержать 64 байта а реально содержит нужных пусть 15.
                некоторые поля вообще не задействованы =0 для конкретного случая. Получается что можно сохранить текущее мгновенное состояние структуры с большой экономией.

                Цитата Mr.Brooks @
                Говорят POD структуру удобнее записать/прочитать с диска.
                Тут уж выбирай, либо экономия места, либо удобные запись/чтение.
                  Цитата Mr.Brooks @
                  Говорят POD структуру удобнее записать/прочитать с диска.

                  Удобнее, только как ты ее саожмешь в цикле я понять не могу. У тебя будет 10 полей по 4 байта(int все например), ты задашь толь 3 из них. У тебя структура как весила 40 байт, там и будет весить. :-?
                    Цитата Mr.Brooks @
                    почему нет бинарника на диске ?
                    std::i(o)stream::clear() не нужна, она восстанавливает поток после ошибок. Либо вызывай std::i(o)stream::close() перед std::i(o)stream::open(), либо создавай другой объект.
                    Сообщение отредактировано: Qraizer -
                      А разве все эти стримы перед открытием нового потока не закрывает старый? Если закрывают, clear() может только навредить, сбрасывая состояние предыдущего потока и теряя всё, что в него записано.
                        Цитата amk @
                        А разве все эти стримы перед открытием нового потока не закрывает старый?
                        Нет. Потоковые open() переадресуют вызов буферизирующему классу, а для std::basic_filebuf<>::open() сказано ровно вот так:
                        Цитата basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode);
                        If is_open() != false, returns a null pointer. Otherwise, initializes the filebuf as required. ...
                          А буферизующий класс что при этом делает? Разве не логично для него сперва закрыть всё, а только потом открывать новый поток?
                            Именно это "returns a null pointer" он и делает.
                              Цитата Mr.Brooks @
                              Есть например структура, где все элементы POD. Как перебрать в цикле элементы структуры ?
                              Ждать пока в плюсы завезут рефлексию. Вроде обещают, когда-нибудь.
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0513 ]   [ 16 queries used ]   [ Generated: 29.03.24, 11:08 GMT ]