Как пользоваться консольными программами

С такой задачей довольно часто приходится иметь дело начинающим программистам. И нередко она вызывает серьёзные затруднения, несмотря на то, что принцип её решения предельно прост.

Основная проблема чаще всего кроется в ещё недостаточном понимании структуры как консольных таки оконных программ.

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

  1. Ввод данных;
  2. Выполнение тех или иных действий;
  3. Вывод результатов на экран консоли.

В оконной программе первая и третья части объединены в оконном интерфейсе, а вторая часть выполняется при возникновении определённого события (например, нажатие кнопки).

Для наглядности рассмотрим следующий простой пример.

Есть консольная программ, которая перемножает два числа введённые пользователем и выводит результат умножения. Ниже приведён её код на Pascal и C++.

Delphi/Pascal
a , b , c : real ;
int _tmain ( int argc , _TCHAR * argv [ ] ) <
double a , b , c ;
// 1я часть. Ввод данных
// 2я часть. Собственно алгоритма программы
// 3я часть. Вывод результата

Subnautica КОНСОЛЬНЫЕ КОМАНДЫ

Необходимо переделать эту консольную программу в оконную.

Реализацию оконной версии выполним в Delphi и C++ Builder.

Так как программа принимает на вход два числа и возвращает результат в виде одного числа, в окне должны быть два компонента исходных чисел (допустим, поля для ввода Edit) и один компонент для вывода результата (допустим, метка Label).

Для того чтобы дать программе команду выполнить вычисления можно задействовать обычную кнопку. При нажатии на неё оба исходных числа будут перемножены, а результат выведен в Label.

Внешний вид окна показан на скриншоте ниже.

Для большей наглядности можно добавить два дополнительных компонента Label, которые будут служить подписями для компонентов Edit.Однако в силу того, что при перестановке множителей произведение не изменяется, наличие или отсутствие этих компонентов, а также их взаимное расположение на работу пользователя с программой никак не повлияют.

Теперь необходимо обработать событие нажатия на кнопку.

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

Источник: streletzcoder.ru

Консольное приложение на ассемблере

RSS

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

Крутые команды консоли windows которые вы должны знать

Большое количество системных утилит, входящих в состав операционной системы, используют исключительно текстовый интерфейс и рассчитаны на использование аргументов командной строки.

Как вы знаете, большинство упомянутых системных утилит мигрировали к нам из ранних версий операционной системы Windows, куда они, в свою очередь, заимствовались как из той же MSDOS (фактически предка Windows), так и из сторонних операционных систем. Соответственно, в старых ОС, до определенного времени, интерфейс взаимодействия с пользователем (командная строка) ограничивался текстовым режимом, по этой причине и разрабатывались утилиты исключительно под него.

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

  • возможность (для взаимодействия) использовать стандартные потоки ввода-вывода (будут описаны ниже).
  • наличие потоков позволяет использовать консольные утилиты в сценариях (скриптах), где выходные потоки одних утилит могут перенаправляться во входные потоки других.
  • оптимизация приложения по скорости выполнения (скорости вывода информации) и потреблению системных ресурсов.
  • удобство программирования, обусловленное простотой и небольшим набором функций обслуживания консоли.

Помимо класса консольных утилит, в практике разработчика часто возникают задачи, в которых разворачивать оконный графический интерфейс соразмерно напрасной трате своего и процессорного времени. В подобного рода задачах вполне достаточным условием является использование текстового (для вывода диагностических сообщений) или вовсе неинтерактивного (вывод данных в файл) режимов. Действительно, зачем пытаться изображать графический интерфейс там, где он явно излишен или вовсе не обязателен, не проще ли в таких задачах от него отказаться вовсе? Поэтому, сегодня мы акцентируем внимание на особенностях языка Ассемблера (FASM) при написании консольного приложения на ассемблере под Windows, и темой данной статьи будет создание серии простейших консольных приложений, демонстрирующих основные алгоритмы взаимодействия с консолью. Разработанные шаблоны (в примерах) могут быть в дальнейшем использованы в качестве базовых в различного рода проектах.
Итак, в словосочетании консольное приложение на ассемблере присутствует ключевое слово «консоль», на которое стоит обратить особое внимание, поскольку именно оно даст нам понимание основных принципов работы. Скорее всего, люди уже знакомые с компьютером в общем и операционными системами в частности, знают что это такое, хотя могут понимать это в широком, так сказать, смысле этого слова: механизм для ввода информации с клавиатуры и вывода ее на экран. Поэтому, не лишним будет дать серию расширенных определений:

Читайте также:
Программа для скриншотов отзывы

Текстовый пользовательский интерфейс (Text user interface, TUI / Character-Mode User Interface, CUI) — разновидность интерфейса, использующая для ввода-вывода/представления информации текстовый режим (или его эмуляцию) работы видеоадаптера и набор буквенно-цифровых символов и символов псевдографики.

что является базой для:

Консоль (интерфейс командной строки) — текстовый интерфейс управления консольным приложением , ввод-вывод в рамках которого может осуществляться через стандартные потоки: ввод ( stdin ), вывод ( stdout ), ошибка ( stderr ), а так же прямыми чтением/записью из буферов ввода-вывода. По умолчанию к потоку ввода «подключена» клавиатура (мышь), а к потоку вывода — экран (монитора). В частном случае может быть представлена в виде бесконечной бумажной ленты, прокручивающейся в обе стороны.

что, в свою очередь, формирует понятие:

Консольное приложение (character-mode applications) Windows — класс приложений, использующих для взаимодействия с системой/пользователем объекты консоли: текстовый интерфейс и стандартные потоки ввода-вывода. Считается что консольные приложения управляются консолями .

Консольное приложение операционной системы Windows обеспечивает взаимодействие с пользователем через так называемое окно консоли . Примером подобных консольных приложений могут являться: окно командной строки (cmd), файловые менеджеры (например, Far Commander), и ряд типовых системных консольных утилит:

консоль cmd

Различия оконного и консольного приложений

Консольные приложения являются одним из типов исполняемых образов (приложений) Windows, наряду с типовыми оконными (GUI), библиотеками (DLL), драйверами (native) и некоторыми другими. По сути это полноценные приложениями, имеющие ряд специфических отличий:

  • Значение поля Subsystem заголовка результирующего PE-файла равно 3 ( IMAGE_SUBSYSTEM_WINDOWS_CUI ). На основании значения данного поля, загрузчик образов при подготовке приложения к выполнению производит свойственную консольным приложениям последовательность загрузки.
  • При запуске консольного приложения, загрузчик образов пытается наследовать консоль от процесса-родителя (приложение, из-под которого был произведен запуск):
  • Создается новая консоль, если родительский процесс не имеет консоли.
  • Консоль наследуется, если процесс-родитель тоже является консольным приложением (окно командной строки и прочее).

Следует ли из всего вышеперечисленного, что все функциональные методы консольного приложения «заключены» внутри набора текстовых функций и им лишь и ограничиваются? Отнюдь, основная идея заключается в том, что отличие оконного приложения от консольного чисто условное, поскольку консольное приложение сохраняет возможность вызывать GUI-функции (то есть функции, работающие уже с графическими примитивами) программного интерфейса Win32, все зависит лишь от набора подключаемых библиотек. Да, в простейшем случае текстовый интерфейс использует интерфейс командной строки, тем не менее многие приложения могут создавать более дружественный пользователю интерфейс при помощи интерактивных элементов, тем самым приближаясь по удобству к полноценному оконному (графическому).

Ограничение консольных приложений «текстовым» режимом в операционной системы Windows чисто условное, поскольку им доступны все базовые элементы управления, используемые и в графическом интерфейсе: кнопки, списки, меню, переключатели, флажки, полосы прокрутки и тому подобное.

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

Начиная с Windows 7, на системном уровне функционал консоли был вынесен из диспетчера csrss.exe и оформлен в качестве самостоятельных исполняемых образов:

  • conhost.exe – обработчик консольных окон режима пользователя (обеспечивает весь функционал работы с консолью);
  • condrv.sys – драйвер режима ядра, обеспечивающий взаимодействие conhost и консольных приложений;

Объекты консольного приложения

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

  • [единственный] входной буфер — область данных (события/сигналы/данные) для ввода (передачи на консоль);
  • [несколько] экранный выходной буфер — область данных (символы/атрибуты) для вывода (отображения на экране);
  • Окно консоли — область экрана, отображающая часть выходного буфера;
  • Текущая позиция курсора — маркера вывода, обозначающий текущую позицию вывода;
Читайте также:
Где взять программу coreldraw

Стандартные потоки (дескрипторы консоли)

На программном уровне для ввода/вывода информации консольные приложения используют три основных стандартных устройства ввода-вывода:

Наименование Назначение
Стандартный ввод ( stdin ) Поток данных, идущих в программу.
Стандартный вывод ( stdout ) Поток данных, идущих из программы.
Стандартная ошибка ( stderr ) Поток сообщений об ошибках, идущих из программы.

Для кода любого консольного приложения стандартные потоки доступны через дескрипторы и используют последние для того, чтобы обратиться к стандартному вводу (буферу ввода данных) и стандартному выводу (экранным буферам) собственной консоли. Хотя этими потоками консольное приложение не ограничено, никто не запрещает ему открывать любые файлы, использовать сетевые соединения и совершать иные действия, доступные в выполняющей их среде.

Стандартный поток — объект процесса консольного приложения, предназначающийся для организации обмена данными.

Традиционно, со стандартным вводом ассоциирована клавиатура, а со стандартным выводом/ошибкой ассоциирован монитор (экран), таким образом вывод печатных символов в STDOUT и STDERR приводит к появлению этих символов на устройстве вывода и к получению их пользователем. В дополнение, потоки могут быть переопределены (перенаправлены) и на другие логические устройства (файл, ввод/вывод другой программы и прочее). Поэтому определение консольного приложения может быть расширено:

Любая программа, получающая данные путём чтения STDIN и передающая данные путём записи в STDOUT , является консольной.

Тем не менее возникает резонный вопрос: обязательно ли наличие окна консоли у консольного приложения? Ведь, теоретически, консольные программы могут обходиться и без классического ввода (с клавиатуры) и вывода (в окно, на экран), поскольку объекты stdin и stdout могут быть связаны с файлами, потоками ввода/вывода других программ или иными объектами операционной системы? Тем не менее, стандартный сценарий использования консольного приложения в Windows подразумевает создание отдельного окна консоли.
В ходе запуска консольного приложения, система генерирует вышеперечисленные дескрипторы для вновь создаваемого процесса консоли. Процесс консольного приложения обычно использует функции GetStdHandle , CreateFile , CreateConsoleScreenBuffer для того, чтобы открыть один из вышеописанных дескрипторов. Функция GetStdHandle обеспечивает механизм получения кодом приложения дескрипторов стандартного ввода, стандартного вывода и стандартной ошибки, связываемых с процессом в момент создания. В случае необходимости имеется возможность переназначить стандартные дескрипторы через функцию SetStdHandle , изменяющую дескрипторы, связанные с STDIN , STDOUT или STDERR .
Стандартные дескрипторы родительского процесса всегда наследуются всеми создаваемыми дочерними процессами, поэтому вызовы функции GetStdHandle дочерними процессами возвращают переназначенный дескриптор. По этой причине, в зависимости от действий родительского процесса, дескриптор, возвращенный функцией GetStdHandle , может сослаться на что-либо, отличное от привычного нам консольного ввода-вывода. К примеру, родительский процесс может при помощи SetStdHandle изменить дескриптор какого-либо потока (например STDIN ) перед созданием дочернего процесса. Затем, когда созданный дочерний процесс у себя в коде вызовет функцию GetStdHandle , он получает дескриптор переназначенного канала. Этим обеспечивается механизм управления родительским процессом стандартными дескрипторами дочернего процесса.

К дескрипторам применяются права доступа. По умолчанию дескрипторы, возвращенные функцией GetStdHandle , имеют доступ GENERIC_READ | GENERIC_WRITE .

Буфер ввода

Каждое консольное приложение имеет буфер вводимых данных:

Входной буфер консоли (Input buffer) — очередь данных, каждая запись которой содержит информацию относительно входного события консоли (нажатие/отпускание клавиш, движение/нажатие/отпускание мыши и прочие).

В момент, когда окно консольного приложения имеет фокус клавиатуры (является активным), консоль оформляет каждое событие ввода (типа нажатия/отпускания клавиши, перемещение указателя мыши или щелчка кнопки мыши) в качестве данных, которые помещаются в буфер вводимых данных консоли. Что такое эти самые данные? Запись данных о вводе ― структура Windows, содержащая в себе информацию о деталях события: тип, источник (клавиатура, мышь, размеры окна, фокус, меню) и прочих. Структура имеет внутренний тип INPUT_RECORD и представляет собой следующее:

Источник: datadump.ru

Возможности консольных приложений для Windows

В настоящее время, когда у разработчиков программного обеспечения появляется всё больше возможностей для сознания приложений со сложным графическим интерфейсом, консольные приложения по-прежнему прочно удерживают свои позиции, даже в такой, казалось бы им среде, как современная операционная система Windows. Это объясняется в первую очередь простотой их исполнения и некоторыми специфическими особенностями консольных приложений, которые делают их в ряде случаев более подходящими для решения задачи, чем приложения с графическим интерфейсом. Один минус: выглядят такие приложения очень уныло и однообразно, как безликая серая масса букв и цифр на чёрном фоне окна консоли. Но не всё так безнадёжно, как может показаться на первый взгляд. В этой статье я попытаюсь дать несколько полезных рецептов расширения функциональности консольных приложений и придания их внешнему виду большей выразительности.

Читайте также:
Какие программы на МТС

И так: начнём с заголовка окна консоли. При запуске программы в заголовке окна отображается полное имя файла, с которого было запущено приложение. Вместо имени файла, в заголовке окна можно указать любой другой текст: название приложения, например. Это делается с помощью функции SetConsoleTitle.

::SetConsoleTitle(_T(«Пример программы на C++»));

Далее рассмотрим проблему с выводом на консоль текста кириллицы. Практически каждому программисту когда-нибудь приходилось с этим сталкиваться.

По сложившейся традиции, для вывода текста на консоль в большинстве примеров на C++ используются функции стандартной библиотеки, такие как printf или puts, которые работают с текстом в кодировке OEM, что соответствует кодовой странице 866 для русского языка. То же самое происходит при использовании потока вывода cout. Но проблема в том, что большинство текстовых редакторов для Windows работают с текстом в кодировке ANSI, что для русского языка соответствует кодовой странице 1251.

Как решить эту проблему? Проще всего использовать функции, которые записывают текст непосредственно в буфер консоли, а не в стандартный поток. Для этого нужно в программный код включить заголовочный файл CONIO.H и, вместо функций printf и puts, вызывать аналогичные функции _cprintf и _cputs.

Так они выглядят в коде на Visual C++:

_cputts(_T(«Всем привет от меня!rn»)); _tcprintf(_T(«%srn»), _T(«Благодарю за внимание.»));

Несложно написать и собственную процедуру вывода текста на консоль с использованием системной функции WriteConsole. Вот пример такой процедуры:

BOOL PrintText(LPCTSTR szText) < static HANDLE hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE); // DWORD dw(0); return ::WriteConsole(hConsole, szText, ::lstrlen(szText), >

А вот так она используется:

PrintText(_T(«Всем пока. rn»));

Как вы уже наверно заметили, для перевода строки необходимо указывать последовательность из двух символов: «rn», в отличие от стандартного потока, где указывается лишь один символ ‘n’. Но бывает и так, что нужно вывести текст именно через стандартный поток, чтобы его можно было перенаправить в текстовый файл или в другое консольное приложение. Для этого текст нужно перевести в другую кодировку с помощью функции CharToOem. Или использовать функцию WideCharToMultiByte с параметром CP_OEMCP, если ваш текст в кодировке UNICODE.

Размер буфера консоли по умолчанию равен 80х300, т.е. 300 строк по 80 символов каждая. Задать буферу консоли другой размер можно при помощи функции SetConsoleScreenBufferSize.

Атрибутами текста консоли являются: цвет символов и цвет заднего фона. Код атрибута соответствует числовому значению в диапазоне от 0x00 до 0x7F. Так выглядит таблица с числовыми значениями атрибутов текста в шестнадцатеричном коде:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F

Функция SetConsoleTextAttribute задаёт выводимому тексту указанный атрибут. Для задания всему окну консоли указанных атрибутов применяется функция FillConsoleOutputAttribute.

Позиционирование текста (т.е. установка курсора на позицию с заданными координатами) производится с помощью функции SetConsoleCursorPosition.

Полный код моего примера в Visual C++ 2005 выглядит так:

#include «stdafx.h» #include BOOL PrintText(LPCTSTR szText); BOOL SetConsoleAttrib(WORD wAttrib); BOOL SetCurrentPos(SHORT x, SHORT y); BOOL SetConsoleSize(SHORT x, SHORT y); int _tmain(int argc, _TCHAR* argv[]) < ::SetConsoleTitle(_T(«Пример программы на C++»)); // SetConsoleSize(160, 80); SetConsoleAttrib(0x6F); // _cputts(_T(«Всем привет от меня!rn»)); _tcprintf(_T(«%srn»), _T(«Благодарю за внимание.»)); // SetCurrentPos(25, 10); PrintText(_T(«Всем пока. rn»)); // _gettch(); // ожидание нажатия клавиши. return 0; >static HANDLE _ConsoleOut = ::GetStdHandle(STD_OUTPUT_HANDLE); BOOL SetConsoleAttrib(WORD wAttrib) < ::SetConsoleTextAttribute(_ConsoleOut, wAttrib); CONSOLE_SCREEN_BUFFER_INFO csbi = ; ::GetConsoleScreenBufferInfo(_ConsoleOut, DWORD dw(0); COORD cr = ; return ::FillConsoleOutputAttribute(_ConsoleOut, wAttrib, csbi.dwSize.X * csbi.dwSize.Y, cr, > BOOL PrintText(LPCTSTR szText) < DWORD dw(0); return ::WriteConsole(_ConsoleOut, szText, ::lstrlen(szText), >BOOL SetCurrentPos(SHORT x, SHORT y) < COORD pos = ; return ::SetConsoleCursorPosition(_ConsoleOut, pos); > BOOL SetConsoleSize(SHORT x, SHORT y) < COORD size = ; return ::SetConsoleScreenBufferSize(_ConsoleOut, size); >

Приведённый пример был создан в среде Visual C++ 2005 как проект Win32 Console Application.

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

Источник: codenet.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru