Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Клуб профессиональных программистов :: Выпуск #69


Клуб профессиональных программистов "Весельчак У"
Информационная рассылка сайта и форума.  Выпуск No69 (2009-04-05).

Здравствуйте, уважаемые читатели!

Сегодня в выпуске:


Новости из раздела «Авторское ПО»: Serg79 продолжает доработку игры batty по мотивам одноименной программы для компьютера ZX-Spectrum.

Последние новости — от 16 марта 2009. Теперь игра запускается в оконном режиме. Оптимизировал реализацию фиксированного FPS. Ревизия в CVS — «19», ветка «http://svn.shelek.su/public/batty/batty_window». Собраный бинарник расположен здесь: batty.zip (37.2 КБ). Для запуска программы требуется DirectX 8.0 или выше.


Эта статья посвящена некоторым функциям, позволяющим нам работать с реестром. Сразу оговорюсь — к статье прикреплен класс CRegistryManip (см. раздел «Файлы»), в котором собраны некоторые примеры по применению вышеозначенных функций.


Содержание.


1. Краткое пояснение. Изначальная постановка задачи.

Была поставлена задача: создать пользовательский «MessageBox», который, кроме стандартных элементов типа «текст» и «кнопки», имел бы еще и «CheckBox», перевод которого в состояние «установлено» должен был бы приводить к тому, что это сообщение больше не будет показано.

Соответственно, эта информация должна быть сохранена в реестре. Причем в виде пары значений: «StringId» (все тексты должны быть внесены в «string table» из-за поддержки многоязычности в проекте) + «Flag» (т.е. состояние этого «CheckBox»).


Windows Register screenshot 1

Благодаря этому и появился вышеупомянутый класс для работы с реестром.


2. Общая информация.

2.1. Общий принцип построения реестра.

Реестр имеет иерархическую структуру, аналогичную каталогу (вложенные папки, деревья). Корневые элементы представляют собой установленные Майкрософтом константы.


HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

Каждый из корневых элементов — корневых ключей — имеет подключи — папки (далее — ключи или подключи), те, в свою очередь, тоже могут иметь свои подключи и т.д. В подключе, находящемся в этой цепочке, могут содержаться параметры и соответствующие им значения. Например:


Код:
HKEY_LOCAL_MACHINE
    |
    SOFTWARE
        |
        Microsoft
            |
            IE4
                |
                Setup
                    |
                    Path = "%programfiles%\Internet Explorer"

В примере:

  • HKEY_LOCAL_MACHINE — корневой ключ.
  • Path — параметр;
  • все остальные — подключи.

Windows Register screenshot 2


Windows Register screenshot 3

2.2. Наши возможности.

С помощью стандартных функций мы можем:

  • считывать и запоминать имена ключей и параметров;
  • считывать и запоминать значения параметров;
  • создавать и удалять ключи;
  • получать общую информацию о ключах и их параметрах.

Прочитать статью целиком Вы можете на нашем сайте в разделе «Windows».


  • Программирование
      • Задание: нарисовать график любой функции в декартовых координатах (x, y, z).
        Примерно знаю, как нарисовать сложную фигуру с помощью OpenGL, но не могу придумать, как их задать. Пусть, например, есть функция x^2 + y^2 + z^2 = R^2. Я знаю, что это шар, но посоветуйте, пожалуйста, как это графически нарисовать? :-/
      • Дерево используется для отображения графических элементов в редакторе. В момент редактирования его свойство Enabled ставится в false и пользователь не видит, какой именно узел (группу элементов) он редактирует. В нормальном режиме этот узел выделен простой селекцией, которая пропадает при выключении контрола.

        Любые предложения принимаются. От жирного текста, до выделения цветом текста или фона узла (node).

        ps иконок нет; HideSelection=false

        pps Можно простое средство, аналогичное Enabled=false, отрубающее все пользовательские операции с деревом: схлопывание, изменение выбраного узла и т.д.?
      • Дали задание:
        разработать программу, обеспечивающую изображение на экране дисплея определенного набора плоских и пространственнных геометрических фигур.
        Предусмотреть в программе возможности масштабирования фигур или их изображения по задаваемым размерам и построения 3-х проекций для определенной фигуры.
        Все предоставляемые услуги оформить в сервисное меню с библиотекой геометрических фигур

        Не знаю даже, с какой стороны подойти.
        Можно писать в борланд С++ (т.е. консоль), в билдере и визуале. Что лучше выбрать?
        Какие библиотеки лучше и проще использовать?
        Какие книги по теме посоветуете почитать?)
        Язык Си изучаю только 2 семестр, т.е. знания еще не очень глубокие. Можно использовать С++, но будут лишние вопросы при сдаче.
      • Изучаю потоки на примере простенькой игрушки - пакмене. Возникли проблемы со скоростью приложения: процессор загружается на ~100% и сама игрушка тормозит.

        Есть 5 разных существ (пакмен и враги), для каждого запускается по отдельному потоку. В каждом потоке - бесконечный цикл, в котором несколько проверок плюс изменение координаты, а для врагов еще поиск пути (пока что почти пустой). После изменения координаты - Sleep (creatureSpeed).
        С одним таким потоком (один пакмен бегает по карте) загрузка процессора - 30-40%. А с 5-ю еще вдобавок скорость перемещения существ падает (видимо к Sleep-у добавляется не такое уж и маленькое время рассчетов)

        В общем, вопрос: как сделать правильно?

      • Подскажите, как определить, какие СОМы есть на машине, т.к. в реестре они в разных системах сидят под разными ключами. Пользовался функцией QueryDosDevice, но, как оказалось, под 98/ME/XP она отрабатывает не так как надо, или вообще не отрабатывает. Может есть еще что-нибудь в этом роде?
        • Задача: из файла .bmp (см. вложение) выделить 12 подкартинок - HBITMAP-ов, используя функцию GetDIBits ().

          Проблема: функция отрабатывает без ошибок, но результат нулевой.

          Вот она (если кто осилит, буду премного благодарен, сам я уже готов сдаваться :-/):
        • Изучаю элементы управления общего пользования.

          Вопрос: как менять цвет текста в статус баре (в разных частях, но сразу во всех тоже пойдет)?
        • Ставлю глобальный хук на окно приложения (функция-фильтр в dll). Надо записывать события мыши и клавиатуры для пересылки по сети и воспроизведения на другой машине. Пока работаю с записью. Программа и dll компилятся, но не работают как надо. Помогите найти ошибку, буду очень благодарна.
        • Есть приложение в котором запускается дополнительный поток.
          И еще есть класс (синглтон), который используется как основным потоком, так и дополнительным потоком приложения. В синглтоне есть некая функция SendStopAppSoft(), которая вызывает еще что-то через OLE/COM, но это уже не суть.
          Когда я вызываю эту функцию в основном потоке, все отрабатывает нормально, а когда в дополнительном, ничего не работает. Хотя я прохожу дебаггером и значения все те же.
          P.S. Использую C++; VS2005; WinXP
        • Хочу в сообщение пользователю вставить данные из БД (DataModule1->IBDataSet1->FieldValues["NUM_PP"]).

          Выходит ошибка.

          Код:
          if(Application->MessageBox("При ответе \"ДА\" произойдет удаление записи. " +
              DataModule1->IBDataSet1->FieldValues["NUM_PP"].c_str()+"\n Продолжить?",
              "ВНИМАНИЕ! ", MB_YESNO + MB_ICONINFORMATION) == IDYES) {

          ОШИБКА:
          [C++ Error] ACU_Unit1.cpp(385): E2316 'c_str' is not a member of 'Variant'

          Как исправить?
        • Создать на основе TSрinEdet компонент, который позволяет вводить целые числа... Надо ещё сделать маску ввода, аналогично компоненту MaskEdet, как это сделать, не пойму.
      • При создании потока возникла такая проблема: мне необходимо, чтобы мой поток периодически останавливался и возобновлялся (интервал времени задается пользователем). Я пробовал создать таймер и управлять потоком оттуда, но мой поток, однажды запущенный, не хочет останавливаться (однако методы Suspend и Resume, привязанные к кнопкам, работают исправно).
        Пробовал ставить внутри метода Execute циклы для задержки, но компьютер подвисает. Подскажите пожалуйста метод, с помощью которого можно переодически "отсоиденять" поток от процессора так, чтобы система не тормозила.
        • Оговорюсь сразу, с VBA дел никогда не имела, поэтому прошу помощи как для совсем ничего не понимающего.

          Нужно в экселе (да и в Word потом) открыть диалог печати с уже проставленным количеством копий документа. Как передать?
          Макрос смогла записать только для немедленной посылки на печать. Хотелось бы сначала открыть диалог и решение оставить для пользователя.
      • Создал елемент Canvas на форме. Теперь мне нужно на нем нарисовать диаграмку. Но draw-функций в списке методов нет. Вопрос: как на Canvas'е нарисоваль еллипс?
      • Кто-нибудь знает, как реализовать выборку документов с использованием Отбора (т.е. по сути фильтра) на Visual Basic?
        Вот начало кода:

        Код:
        Public Sub Main()

        Dim Obj As New V81.COMConnector
        Dim Connection As Object

        Set Connection = Obj.Connect("Srvr=""192.168.0.168"";SQLSrvr=""192.168.0.168"";Ref=""test_db"";SQLDB=""test_db"";Usr=""user777"";Pwd=""777"";")
        MsgBox ("Connect!")

        Set Struct = Connection.NewObject("Структура")

        'Struct.Вставить("Почта",asd)


        MsgBox ("lol")


        End Sub

        Я не очень знаком с синтаксисом, и у меня не получается добавить в структуру КлючЗначение, т.е. выполнить Вставить, потому что не знаю, как это правильно записать.
  • Операционные системы
      • отсылаю на сервер запрос

        в ответ получаю
        Код:
        HTTP/1.1 200 OK
        Date: Mon, 23 Mar 2009 06:24:04 GMT
        Server: Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8b mod_bwlimited/1.4
        X-Powered-By: PHP/5.2.9
        Connection: close
        Content-Type: text/html

        Это я вижу в железке (т.е. что получил, то показал на другой сервер
        Код:
        Date:
        Mon, 30 Mar 2009 12:56:42 GMT
        Server: Apache/2.0.63 (FreeBSD) PHP/4.4.9 with Suhosin-Patch
        Last-Modified: Thu, 25 Dec 2008 11:51:43 GMT
        Etag: "831c-72d-a1d951c0"
        Accept-Ranges: bytes
        Content-Length: 1837
        Content-Type: text/html

        200 OK


        это я смотрю в фф, поэтому и порядок разный
        Кроме того - сервера разные.


        Больше всего меня интересует заголовок

        Connection: close
        кто закрывает соединение, потому как

        Код:
        <?php
        headers
        (HEX: ,"bla-bla");
        ?>
        выдает

        Date: Mon, 30 Mar 2009 13:08:26 GMT
        Server: Apache/2.0.63 (FreeBSD) PHP/4.4.9 with Suhosin-Patch
        X-Powered-By: PHP/4.4.9
        HEX: ,"bla-bla"
        Content-Length: 2
        Keep-Alive: timeout=15, max=100
        Connection: Keep-Alive
        Content-Type: text/html

        200 OK

        где это все настраивается, в частности keepalive?

  • Направления программирования
      • Мой очередной вопрос связан с отменой IRP_MJ_READ/WRITE. Допустим, что я хочу отменять запросы ввода-выводы на чтение/запись, если он не завершаются за разумное время (скажем 10 сек). Можно ли делать следующим образом? (я отталкиваюсь от известного кода У. Они)
        1. инициализировать событие cansel_event
        2. в DispatchReadWrite:
            --  сбрасывать это событие
            --  вызывать StartPacket для начала обработки IRP
            --  далее ожидать KeWaitForSingleObject по cansel_event с таймаутом 10 сек
            --  если ожидание заканчивается со статусом STATUS_TIMEOUT завершать запрос IRP со статусом STATUS_CANSELLED, а из DispatchReadWrite возвращать STATUS_SUCCESS
            -- если ожидание заканчивается со статусом STATUS_SUCCESS, то запрос уже был завершен в течение 10 сек, я ничего не делаю, а просто возвращаю STATUS_SUCCESS из DispatchReadWrite
        3. устанавливается событие при завершении запроса нормальным образом в функции DPC.
        4. Никаких IoCanselIrp и функций отмены я использовать тут не предполагаю

        Меня тут смущает 1 момент, получается моя DispatchReadWrite не вернет управление стороне, вызвавшей IoCallDriver (I/O Manager или вышестоящему драйверу) в течение довольно долго времени (пока запрос либо не будет завершен, либо не истечет таймаут). Обычно она возвращала управление после того, как StartIo пошлет запрос на выполнение операции оборудованию, с результатом STATUS_PENDING. Нормально ли это?

        У. Они предлагает следующую альтернативу данному подходу (стратегия Отмена "Чужих" IRP с ожиданием): в вышестоящем драйвере устанавливать функцию завершения для запроса, передавать этот запрос вниз, далее ожидать по событию с таймаутом, событие устанавливать в функции завершения, отменять запрос в случае окончания ожидания по таймауту.
        Я правильно понимаю, что эту функцию должен выполнять предоставленный мной драйвер-фильтр? И вообще может есть другие подходы к отмене запросов обращения к оборудованию по таймауту?
      • Есть драйвер модема XaVi X7005Q 2 USB на XP.
        Нужно либо переделать, либо разработать драйвер на VISTA. :-/
        Кто поможет?
      • Обьявляется сокет для прослушивания порта(любого).
        Первый вариант:
        Код:
        int error;
        char buff[6500];
          WSADATA wsaData;
          error=WSAStartup(MAKEWORD( 2, 0 ), &wsaData);
          if (error==SOCKET_ERROR)
             {
               Memo1->Lines->Add("произошла ошибка");
               WSACleanup();
             }
          else
              {
                Memo1->Lines->Add("Инициализация прошла");
              }
          sockaddr_in sock;
          sock.sin_family = AF_INET;
          sock.sin_port = htons(port);
          sock.sin_addr.s_addr = htonl(INADDR_ANY);
          int serv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
          if (serv == SOCKET_ERROR)
            {
              Memo1->Lines->Add("Ошибка в сокете");
              WSACleanup();
            }
          else
              Memo1->Lines->Add("Сокет ок");

          error = bind(serv, (sockaddr*)&sock,sizeof(sock));
          if (error == SOCKET_ERROR)
             Memo1->Lines->Add("Ошибка в bind");
          else
              {
                Memo1->Lines->Add("bind успешен");
                memset(buff,0,strlen(buff));
                int fromlen = sizeof(sock);
                int  rc = recvfrom(serv,buff,sizeof(buff),0,(sockaddr *)&sock,&fromlen);
                if (rc==SOCKET_ERROR)
                     Memo1->Lines->Add("ошибки");
                 else
                     Memo1->Lines->Add(buff);
              }
        Программа зависает до получения пакета, одного в данном случае(потом будет цикл, while ), как сделать чтоб этого не было?
        как бы надо использовать асинхронный сокет т.е.  WSAAsyncSelect()
        но вот беда параметр wMsg1 как описать в нем?
        второй  вариант:
        как бы есть функция обьявляю в хендл
        Код:
        public:
         ....
         void __fastcall WMUserN ( TMessage& Msg );
        protected:
        BEGIN_MESSAGE_MAP
          MESSAGE_HANDLER(WM_USER + 1, TMessage, WMUserN);
        END_MESSAGE_MAP(TForm);
        потом
        Код:
        void __fastcall WMUserN ( TMessage& Msg )
        {
          char buff[65000];
          int fromlen = sizeof(sockaddr_in);
          int lent=sizeof(buff);
          int rev_lent=0;
          sockaddr_in sock;
          sock.sin_family = AF_INET;
          sock.sin_port = htons(port);
          sock.sin_addr.s_addr = htonl(INADDR_ANY);
          int serv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
          if (serv != SOCKET_ERROR)
          {
          while (rev_lent < lent)
               {
                 WSAAsyncSelect(serv,Handle,sizeof(buff),FD_READ);
                 int rr= recvfrom(serv,buff,lent-rev_lent,0,(sockaddr *)&sock,&fromlen);
                 if (rr==SOCKET_ERROR)
                    ShowMessage("Ошибка");
                 else
                     {
                       Memo1->Lines->Add(buff);
                       rev_lent +=rr;
                     }

               }
          }
          else
             ShowMessage("все плохо");
        }
        И вот как это дело связать с сокетом? И код правильно ли я написал?
        Потом еще будет дорабатыватся до отправления сообщения.
      • По ходу работы пришлось разбираться с WinSocket, все вроде понятно, даже код работает. По ходу дела пользуюсь WSAAsyncSelect, на один сокет на разные события повесил разные сообщения, все это работает и тут увидел в MSDN, что
        It is not possible to specify different messages for different events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE events will be reported with message wMsg2:
        Код:
        rc = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);
        rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);
        Вопрос: где могут быть грабли и что с ними делать (отлаживаюсь на WinXP HE, работать должно под Win98)?
        Заранее благодарен за ответ.
        • Решил добавить к сайту примитивный опросник. Для начала хочу, чтоб все присланные варианты ответов записывались в файл. В страничке пхп, отвечающей за обрабатывание, чтение и запись результатов, сделал уже есть разбиение на варианты ответов (пока только 2 из 5).
          Проблема заключается в том, что мне никак не удается заставить ее нормально работать, а именно: принимать результат, складывать с имеющимся результатом в файле (файл - data.txt и хранится там 0) и выводить полученное число. Необходимо прочитать, сложить, удалить содержимое, и заново записать результат. Но вместо этого постоянно получаю чрезвычайно странную картину:
          "515
          0510"
          Сам пхп код:
          Код:
          <?php
          if(@$goo)
          {
              
          $text fopen("data.txt"'r') or die("Can't open file!");
              
          $data fread($textfilesize("data.txt"));
              if (
          $opinion == '5')
              {
                  
          $result $data 5;
                  echo 
          $data 5;
                  echo 
          "<br>";
                  echo 
          $data;
                  
          fclose($text);
                  
          $fh=fopen("data.txt",'a+');
                  
          $result $data 5;
                  
          fwrite($fh"$result");
                  
          fclose($fh);
                  die;
              }
              else;
              if (
          $opinion == '4')
              {
                  
          $result $data 4;
                  echo 
          $result;
                  echo 
          "<br>";
                  echo 
          $data;
                  
          fclose($text);
                  
          $fh=fopen("data.txt",'a+');
                  
          fwrite($fh"$result");
                  
          fclose($fh);
                  die;
              }
          }
          <
          ?>

          Форма:
          Код:
          <form action="http://spbpast.freetzi.com/voting/vote.php" method="post">
          <table>
              <td align=right>
                  <INPUT type="radio" name="opinion"  value="5">???????
                  <INPUT type="radio" name="opinion"  value="4">??????
                  <INPUT type="radio" name="opinion"  value="3">??????
                  <INPUT type="radio" name="opinion"  value="2">?????
                  <INPUT type="radio" name="opinion"  value="1">???????
              </td>
          </table>

          Заставить удалять я ее не смог (делал это командой unlink). 
          Я понимаю, что у меня тут однозначно имеется ошибка в коде. Но убив на это 4 дня, исправить ее я не смог. :(
  • Практические разделы
      • Каким образом можно поместить UPDATE в приведённой ниже хранимой процедуре в транзакцию?

        Код: (sql)
        CREATE FUNCTION do_something() RETURNS void AS $$
        BEGIN
            UPDATE table SET ... -- и так далее, UPDATE довольно навороченный
        END;
        $$ LANGUAGE plpgsql;

        Не работает следующий вариант:

        Код: (sql)
        CREATE
        FUNCTION do_something() RETURNS void AS $$
        BEGIN
        BEGIN;
            UPDATE table SET ... -- и так далее
        COMMIT;
        END;
        $$ LANGUAGE plpgsql;

        Как использовать транзакцию правильно?
      • Программа написана на FOXPRO, внешне схожа с программой "бест", интерфейс "DOS-овский", сама программа лежит на сервере 2003, клиенты подключаются к ней при помощи сетевого диска. Мы стали переподключать черес клиент служб терминалов, - программа перестала пускать больше одного пользователя - говорит, что временный файл занят. А почему тогда, подключаясь посредством сетевых дисков, программа пускает всех? Можно или нет как-то разрулить эту ситуацию? Простите, может, что непонятно написал, занимаюсь в основном железом, в общем, буду признателен за помощь.
      • Честно говоря, я плохо разбираюсь в Java, но мне действительно очень нужно разобраться с содержимым базы.
        Предположительно, там тестовые вопросы и варианты ответов, включая правильные.

        Это программа тестирования на Java. Я знаю, что она обращается к файлу.
        (посмотрел в "просмотре кода HTML" в IE). Нашел такую запись

        <param  name="FileName" value="../dir/dir/test.zip" />
        В зип лежит файл с расширением .atv. В текстовом редакторе открывется как куча символов.

        Нашел рядом файл .jar. Проверил декомпилятором классы в поисках каких нибудь ссылок на этот файл
        Нашел только static final int SND_FILENAME = 131072.
        На этом встал.

        Помогите кто чем может. Буду очень благодарен. Как открыть этот файл?
      • У меня проблема с компом. При включении, экран монитора остаётся тёмным, хотя всё подключено и системный блок работает. Не могу понять причину. Монитор подключал к другому системному блоку - рабатает, т.е. есть изображение. Вероятно, проблема с видеокартой. Поэтому необходимо провести диагностику.
        Хочу задать вопрос: можно ли провести диагностику системы, если на мониторе нет изображения?
        Может можно как-то решить данную проблему, при помощи программ или утилит?
      • Мат. плата MSI, процессор 2х-ядерный, тюнер AverTV505. Воспроизводит ТВ и записывает видео почему-то без звука. Подключал активные колонки к выходу тюнера - звука нет.  Раньше была материнка ASYS P5 PE VM - звук был. А на этой материнке нет! В биосе потыркался - не помогло, выставил биос по дефолту - тоже звука нет! Можно или нет решить мою проблему?
      • На работе около 10 компов соединены в локальную сеть. Компы не очень мощные. На всех стоит программа 1С. Нужен антивирус такой, чтобы сильно не нагружал компы, не мешал программе 1С.
        Если я, допустим, приобрету лицензию для 1 ПК, смогу ли я установить их на все компы, не будет ли вылетать лицензия, что ключ уже используется.?
      • 1. Я постоянно захожу на сайты, где даются ссылки на файлообменики с фильмами, музыкой, электронными книгами и т.п. и через несколько месяцев у меня начинает тормозить компьютер.

        Я так понял, это вирусы как-то проходят, но почему и какую теперь ставить защиту?

        У меня стоит NOD32 3.0.669.0, он постоянно обновляется, и он не показывает, что вирусы через Интернет странички пытаются пройти.

        2. Я помню, была раньше "шумиха" все ставили системы обнаружения вторжения (IDS), вот я поставил BlackICE (сейчас называется Internet Security System), но почему-то он мне выдавал кучу атак на мой компьютер, хотя настройки я выбирал или минимальные, или средние, и "шумиха" вокруг IDS прекратилась.

        Системы IDS не оправдали себя? 

        3. Вот я пользовался для сканирования собственного компьютера программой XSpaider российских разработчиков, и в интернете утверждалось, и в киоске продавец говорил, что XSpaider не обнаруживается системами обнаружения вторжений IDS.

        Вот у меня был случай. Два моих компьютера объединены кабелем, на одном я запускаю XSpaider и пытаюсь просканировать второй компьютер, на котором стоит IDS [BlackICE (сейчас называется Internet Security System)] и что же, IDS заблокировало сканирование и показало IP, откуда производилось сканирование.

        Значит, в интернете и продавец обманывали насчёт того, что XSpaider обходит IDS, или я неправельно настроил XSpaider?
  • Учимся программировать
      • Имеется структура. У нее 3 поля - ФИО, знак зодиака, дата рождения. Хочется сделать так, чтобы данные, введенные в поля, максимально соответствовали действительности, а не были банальным набором букв.  Вот то,  что удалось самостоятельно:

        Код:
        #include <iostream.h>
        #include <conio.h>
        #include <fstream.h>


        const str_len = 30;    //dlina txt_polya v strukture
        const amount_elem = 2; //Koli4estvo elementov v massive struktur


        struct znak    //nasha struktura
        {
        char FIO[str_len];
        char znak_zod[str_len];
        int data_rojd[3];
        };

        znak *arr = new znak[amount_elem];   //massiv struktur

        void vvod_elem();       //prototipi funkciy
        int vivod_elem();

        int main()
        {

        clrscr();

        vvod_elem();
        vivod_elem();


        return 1;
        }

        void vvod_elem()                     //funkciya vvoda elementov
        {
        cout<<"Vvedite informaciu o ludyah"<<endl;
        cout<<endl;
            for (int i=0; i<amount_elem; i++)   //tsikl vvoda elementov strukturi
        {
        cout<<"Vvedite FIO"<<endl;
        cin>>arr[i].FIO;                       //vvodim fio
        cout<<"Vvedite znak zodiaka"<<endl;



                cin>>arr[i].znak_zod;                     //vvodim znak zodiaka



        cout<<"Vvedite datu rojdeniya. Format dati: DD:MM:YYYY"<<endl;
        while (arr[i].data_rojd[0]<1   ||
               arr[i].data_rojd[0]>31   ||
               arr[i].data_rojd[1]<1    ||
               arr[i].data_rojd[1]>12   ||
               arr[i].data_rojd[2]<1850 ||
               arr[i].data_rojd[2]>2009) //[proverka pravilnosti vvoda dnya, mesyatsa i goda
        {
             for (int j=0; j<3; j++) cin>>arr[i].data_rojd[j];
             if (arr[i].data_rojd[0]<1 || arr[i].data_rojd[0]>31) {cout<<"Nevernoe 4islo! Povtorite vvod!"<<endl;};
             if (arr[i].data_rojd[1]<1 || arr[i].data_rojd[1]>12) {cout<<"Neverniy mesyats! Povtorite vvod!"<<endl;};
             if (arr[i].data_rojd[2]<1850 || arr[i].data_rojd[2]>2009) {cout<<"Neverniy god! Povtorite vvod!"<<endl;};
        }
        cout<<endl;
        }

        }

        int vivod_elem()  //procedura vivoda elementov massiva
        {
        if (arr[0].FIO=="0") cerr<<"Massiv struktur pust! Vvedite elementi massiva!"<<endl; getch(); return; //esli pole FIO v 0m elemente pustoe - viyti
        for (int i=0; i<amount_elem; i++)
        {
        cout<<"FIO: "<<arr[i].FIO;
        cout<<"Znak zodiaka: "<<arr[i].znak_zod;
        cout<<"Data rojdeniya: ";
        for(int j=0; j<3; j++) cout<<arr[i].data_rojd[j]<<" ";
        cout<<endl;
        };

        delete [] arr;


        return 1;
        }


        Задачу начал решать с конца - сделал проверку для даты. Изначально она заработала, но потом (после перезапуска си) отказалась. Может это связано с тем, что массив динамический?
        Пробовал сделать такую же проверку для знака зодиака, сравнивая поле со строчками - 0 реакции :( Направьте на путь истинный :)
      • Пишу программу на С для микроконтроллера.
        Одновременно выполняется несколько задач: прием-отправка данных медленному самодельному интерфейсу, прием-отправка данных по MODBUS, АЦП, несколько временно-зависимых задач. Задачи выполняются одновремено и они взаимосвязаны и число взаимосвязей увеличивается по мере написания программы.
        Возможно добавится новый функционал, а соотв. и взаимосвязи.
        Уже начинаю путаться, забывать что-откуда-куда.
        Как формализовать написание программы (в идеале - сколь угодно сложной), какими инструментами для этого пользоваться?
        Хочется построить программу стройно и красиво, чтобы наращивая функционал, структура не менялась, только добавлялись модули.

        Должны помочь старые-добрые блок схемы и графы состояний? Что-то у меня не получается описать задачу графами.

        Посоветуйте литературу по этому вопросу.
      • Поставлена задача: сформировать массив НАТУРАЛЬНЫХ чисел из m-строк и n-столбцов. Найти все числа матрицы, которые содержат цифру, введенную с клавы, и подсчитать их количество.


С уважением, команда Клуба.


В избранное