Текстовый ввод-вывод

Прямой ввод-вывод: Часть II

Разбить на страницы
Показывать лекцию целиком

3.1. Очистка экрана

Очистку всего экрана можно осуществить с помощью специальной команды или с помощью escape - последовательности Esc[2J. Рассмотрим эти способы поподробнее.

3.1.1. Реализация на ассемблере

1-ый метод: использование функции 6 прерывания 10H

Функция 6 прерывания 10H очищает определённую прямоугольную область экрана. Число строк, на которое надо сдвинуть экран, заносится в регистр AL. Если установлено значение 0, то экран очищается. Строка для верхнего левого угла очищаемой области заносится в регистр CH, столбец для левого верхнего угла - в регистр CL, а значения для правой нижней строки и столбца - в регистры DH и DL соответственно. Атрибут, которым должен чиститься экран, записывается в регистр BH. Он подробно описан в таблице 3.1.

Примечание: нумерация позиций экрана начинается с точки (0, 0) в верхнем левом углу экрана!

Числовое значение атрибутов символов (цвет и фон)
Числ. Значение Цветовой атрибут Символ или фон?
0 Чёрный Символ
1 Синий Символ
2 Зелёный Символ
3 Циан (голубой) Символ
4 Красный Символ
5 Пурпурный Символ
6 Коричневый Символ
7 Светло-серый Символ
8 Тёмно-серый Символ
9 Светло-синий Символ
10 Светло-зелёный Символ
11 Светло-голубой Символ
12 Светло-красный Символ
13 Светло-пурпурный Символ
14 Жёлтый Символ
15 Белый Символ
0 Чёрный Фон
16 Синий Фон
32 Зелёный Фон
48 Циан (голубой) Фон
64 Красный Фон
80 Пурпурный Фон
96 Коричневый Фон
112 Светло-серый Фон
128 Мигание Символ
Примечание: Атрибут = Символ+Фон (+ Мигание)

Пример 3.1

; --- Очистка экрана между координатами 0, 0 и 24, 79,
; --- нормальное заполнение символов.

	MOV AH, 6	; используемая функция.
	MOV AL, 0	; очищается весь диапазон
	MOV BH, 007H	; белые символы на чёрном фоне
	MOV CH, 0	; левый верхний
	MOV CL, 0	; угол
	MOV DH, 24	; правый нижний
	MOV DL, 79	; угол
	INT 10H

2-й метод: использование функции 9 прерывания 10H

Функция 9 прерывания 10H выводит символ и атрибут столько раз, сколько указано в CX. Значение 2000 чистит весь экран, если курсор установлен в позицию 0, 0. AL должен содержать символ пробела (код 020H), BL - байт атрибутов, а BH - номер страницы дисплея.

Пример 3.2.

; --- установка курсора в левый верхний угол экрана
	MOV AH, 2	; номер функции
	MOV BH, 0	; номер экранной страницы
	MOV DX, 0	; обнуляем координату позиции курсора
	INT 10H
; --- вывод символа 'пробел' 2000 раз
	MOV AH, 9 	; номер функции
	MOV CX, 2000	; число повторений вывода
	MOV AL, 020H	; символ пробела
	MOV BL, 7	; атрибут 'белый по чёрному'
	INT 10H

Дополнительную информацию смотрите [Абель, Джордейн]

3.1.2. Реализация на языке Си

Реализация очистки экрана средствами языка Си возможна только посредством использования escape-последовательности:

Пример 3.3.

…
puts( "\x1B[2J" );
…

3.1.3. Реализация на Бейсике

В бейсике для очистки экрана применяется оператор CLS

ОПЕРАТОР CLS
СИНТАКСИС: CLS
НАЗНАЧЕНИЕ: Данный оператор очищает текущий экран вывода программы Basic и переносит экранную позицию вывода (курсор) в координаты (0, 0).
Оператор не принимает и не возвращает никаких значений.

3.1.4. Реализация в Command Shell

Очистку экрана в MS-DOS Command Shell можно осуществить следующим способом:

  • команда CLS, очищающая экран дисплея и устанавливающая курсор в левый верхний угол. Её синтаксис:
    CLS
  • Дополнительную информацию смотри [Финогентов II]

    3.1.5. Реализация в языках Перл, Питон и Пролог

    Реализация очистки экрана средствами языков Перл, Питон и Турбо Пролог не предусмотрена.

    3.2. Управление курсором

    Помимо цвета выводимых символов, гораздо чаще Вам придётся изменять положение курсора на экране дисплея. При этом может потребоваться:

  • Абсолютное позиционирование курсора;
  • Относительное позиционирование (относительно текущей позиции);
  • Запоминание или чтение позиции курсора.
  • Этим операциям мы научимся в этом разделе.

    3.2.1. Абсолютное позиционирование курсора

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

    Для курсора могут быть установлены абсолютные координаты или координаты относительно текущей позиции. Абсолютные координаты могут меняться в пределах 25 (изредка 50) строк и 80 (иногда 40) столбцов. В языках высокого уровня обычно отсчитывают координаты экрана, начиная с единицы. Таким образом, позиция левого верхнего угла - 1, 1. В ассемблере отсчёт всегда начинается с нуля и позиция левого верхнего угла - 0, 0.

    Рассмотрим функции абсолютного позиционирования курсора, реализованные на разных языках.

    3.2.1.1. Реализация на ассемблере

    1-ый метод.

    Функция 2 прерывания 10H устанавливает курсор, относящийся к указанной странице видео памяти.

    ФУНКЦИЯ 2 ПРЕРЫВАНИЯ 10H
    Входные значения:
  • AH = 2 - номер функции
  • BH - номер видеостраницы (обычно 0):
  • DH - строка дисплея. Отсчёт строк начинается с 0;
  • DL - столбец дисплея. Отсчёт столбцов начинается с 0;
  • Пример установки графического курсора в центре экрана:

    Пример 3.4.

    ; --- установка курсора в строку 12, столбец 39.
    	MOV AH, 2	; номер функции
    	MOV BH, 0	; номер страницы
    	MOV DH, 12
    	MOV DL, 39
    	INT 10H

    Подробнее смотри [Абель, Джордейн]

    2-ой метод.

    Второй метод позиционирования курсора состоит в применении escape-последовательностей драйвера ANSI.SYS. В этом случае можно пользоваться функцией 9 прерывания 21H, выводя escape-последовательность как обычную строку.

    Пример 3.5.

    ; --- установка курсора в строку 12, столбец 39.
    
    ; --- в сегменте данных
    DOS_CENTER	DB 	27,'[12;39H$'	; строка позиции курсора
    ; --- в сегменте кода
    	MOV AH, 9	; номер функции вывода строки.
    	LEA DX, DOS_CENTER	; загрузка адреса строки
    	INT 21H

    Подробнее см. [MS_DOS 6.0, Финогентов I]

    3.2.1.2. Реализация в языках Си

    Не смотря на то, что на языке Си есть свои функции управления позицией курсора, предпочтительней использовать средства, предоставляемые драйвером ANSI.SYS (примеры см. ниже).

    Пример 3.6.

    1.	Реализация в Turbo C/C++
    
    const char POS_CENTER[] = "\x1b[12;39H";
    …
    puts( POS_CENTER);
    
    2.	Реализация в SPHINX C--
    
    WRITESTR( "\x1b[13;39H" );

    Подробнее см. [Бочков, Финогентов I]

    Другие функции задания абсолютной позиции курсора в Си:

    Функции Turbo C++

    ФУНКЦИЯ GOTOXY
    ОПИСАНА В: <conio.h> (содержит прототип функции)
    СИНТАКСИС:
    void gotoxy( x, y );
    int x;
    int y:
    НАЗНАЧЕНИЕ: Позиционирует курсор в текстовом окне.
    ОПИСАНИЕ: gotoxy перемещает курсор в текстовом окне в указанную позицию. Если координаты указаны неверно, вызов данной функции игнорируется. Например, это произойдёт при вызове gotoxy(80,30) когда окно имеет размеры 40 столбцов на 25 строк.
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет.
    ПЕРЕНОСИМОСТЬ: Работает только на системах, совместимых с IBM PC. Аналогичная функция есть в Turbo Pascal.

    Функции SPHINX C--

    ФУНКЦИЯ GOTOXY
    СИНТАКСИС:
    void GOTOXY ()
    AL = xloc; BL = yloc;
    НАЗНАЧЕНИЕ: Устанавливает текстовый курсор в позицию, заданную xloc и yloc. Отсчёт позиций начинается с нуля.
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: AX, BX и DX не определены.
    ФУНКЦИЯ GOTOXYZ
    СИНТАКСИС:
    void GOTOXYZ ()
    AL = xloc; BL = yloc; CL = page;
    НАЗНАЧЕНИЕ: Устанавливает текстовый курсор в позицию, заданную xloc и yloc для указанной "page" видео страницы дисплея. Отсчёт значений начинается с нуля.
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: AX,BX,CX и DX не определены.

    3.2.1.3. Реализация в Бейсике

    Бейсик нумерует строки от 1 до 25, а столбцы - от 1 до 80. Абсолютная позиция строки задаётся оператором LOCATE.

    ОПЕРАТОР LOCATE
    Синтаксис: LOCATE строка, столбец

    где

  • строка - переменная или целая константа, указывающая на положение строки вывода;
  • столбец - переменная или целая константа, указывающая на положение столбца вывода.
  • Назначение: Абсолютное позиционирование строки.

    Пример 3.7.

    REM Переместить курсор в центр экрана
    LOCATE 12, 40

    Подробнее см. [Джордейн]

    3.2.1.4. Реализация в Perl и Python

    Абсолютное позиционирование в Perl и Python не реализовано.

    3.2.1.5. Реализация в языке Turbo Prolog

    Абсолютное позиционирование в Turbo Prolog осуществляется с помощью специальной функции (см. примеры ниже).

    ФУНКЦИЯ: CURSOR
    СИНТАКСИС: cursor(Row, Column), где Row - целая переменная, устанавливающая или считывающая значение позиции строки выводимых символов, Column - целая переменная, устанавливающая или считывающая значение столбца на экране, куда выводится символ;
    НАЗНАЧЕНИЕ: Устанавливает или считывает позицию курсора в окне;
    ОПИСАНИЕ: Шаблон: (i,i) Перемещает курсор в указанную позицию ( Row,Column ) относительно начальной позиции (0,0) в активном окне. Шаблон: (o,o), связывает Row и Column с текущей позицией курсора. Никогда не даёт неудачного завершения;
    ШАБЛОНЫ: (i,i) (o,o) ;
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Никогда не даёт неудачного завершения;
    ОШИБКИ: * 1001 Недопустимые значения позиции курсора.

    Пример 3.8.

    /* Реализация абсолютного позиционирования курсора средствами спец. функции Турбо Prolog. */
    
    … cursor(12, 39), …

    3.2.2. Относительное позиционирование курсора

    Функции относительного позиционирования курсора выполняются только через escape-последовательности. Они выводятся на экран на ассемблере с помощью функции 9 прерывания 21H. В таблице 2.1 приводится вид escape-последовательностей для разных операций. Такие последовательности интерпретируются оболочкой как команды управления дисплеем, а не вывод символов строки.

    Возможны следующие направления перемещения курсора:

  • вверх на число строк: esc[числоA ;
  • вниз на число строк: esc[числоB ;
  • вправо на число позиций: esc[числоC ;
  • влево на число позиций: esc[числоD ;
  • включение автоматического перевода курсора на следующую строку: esc[=7h;
  • выключение автоматического перевода курсора на следующую строку: esc[=7l;
  • Кроме того, для управления курсором часто используются следующие "пробельные" метасимволы (см. таблицу 2.2).

    Подробнее см. [MS-DOS 6.0, Финогентов 1]

    3.2.2.1. Реализация на Ассемблере

    Для управления относительным перемещением курсора на языке ассемблера необходимо:

  • задать константу, содержащую эту управляющую последовательность (с последним знаком: "$" );
  • в нужном месте выполнить функцию 9 прерывания 21H.
  • См. пример 3.5.

    3.2.2.2. Реализация на языке Си

    Вывод escape - последовательностей осуществляется с использованием функции puts (потоковая функция).

    Тексты примеров с использованием escape - последовательностей приведены выше (см. пример 3.3. и др.)

    Для переноса вывода в начало новой строки в языке C-- есть функция WRITELN:

    ФУНКЦИЯ WRITELN
    СИНТАКСИС: WRITELN() ;
    НАЗНАЧЕНИЕ: Перемещает курсор в начало следующей строки;
    ВХОДНЫЕ ПАРАМЕТРЫ: нет;
    ФУНКЦИЯ ВОЗВРАЩАЕТ: * AX = 0xE0A;

    * BX = 7;

    3.2.2.3. Реализация на Бейсике

    В реализации функций относительного позиционирования курсора на Бейсике возможны следующий вариант:

    ФУНКЦИЯ TAB
    СИНТАКСИС: TAB( число ), где число - целая константа или переменная, определяющая отступ (в знаках) от позиции начала строки вывода.
    НАЗНАЧЕНИЕ: Функция сдвигает текстовый курсор в указанную позицию вывода на строке.
    ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ: нет.

    3.2.2.4. Реализация в Perl и Python

    В языках Perl и Python относительное позиционирование курсора возможно с помощью "пробельных" управляющих символов.

    Пример 3.9.

    # Реализация на Perl
    # отступ на семь позиций влево с использованием горизонтальной позиции табуляции
    
    print "\n\tТекст";

    Пример 3.10.

    # Реализация на Python примера 3.09.
    # отступ на семь позиций влево с использованием горизонтальной позиции табуляции
    
    print "\n\tТекст";

    3.2.2.5. Реализация в Turbo Prolog

    В языке Turbo Prolog относительное позиционирование курсора возможно с помощью "пробельных" управляющих символов.

    Пример 3.11.

    /* Реализация на Prolog примера 03.009. */
    /* отступ с использованием горизонтальной позиции табуляции */
    
    … nl, write( "\tТекст" ), …

    3.2.3. Запоминание позиции курсора

    Иногда возникают ситуации, когда надо прервать вывод текста, перевести курсор в другую позицию, вывести или ввести параметры программы, а затем продолжить вывод текста со "старого" места.

    Реализацию этой последовательности действий можно осуществить следующим образом:

  • Чтением абсолютной позиции курсора;
  • Запоминанием последней позиции курсора в неконтролируемый программистом буфер, и затем повторной "вставкой на экран" запомненной позиции курсора.
  • Последнюю реализацию можно осуществить с помощью следующих escape последовательностей:

  • Esc[s - сохранение текущей позиции курсора;
  • Esc[u - восстановление сохранённых в буфере координат курсора.
  • Подробнее см. [MS-DOS 6.0, Финогентов I]

    Реализация чтения координат курсора на Ассемблере

    Функция 3 прерывания 10H возвращает строку курсора в DH, а столбец - в DL. На входе надо поместить в BH номер страницы.

    ФУНКЦИЯ 3 ПРЕРЫВАНИЯ 10H
    НАЗНАЧЕНИЕ: Определяет и сохраняет текущую позицию курсора на экране дисплея.
    ПАРАМЕТРЫ: AH = 3 - номер функции;

    BH - номер экранной страницы дисплея;

    ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ: * DH - текущая строка курсора;

    * DL - текущий столбец курсора.

    Пример 3.12.

    ; --- В сегменте данных
    CUR_ROW	DB	? ; текущая строка курсора
    CUR_COL	DB	? ; текущий столбец курсора
    ; --- в сегменте кода
    ; --- определение позиции курсора
    	MOV AH, 3	; номер функции
    	MOV BH, 0	; номер экранной страницы
    	INT 10H
    ; --- Строка - столбец DH - DL
    	MOV CUR_ROW, DH
    	MOV CUR_COL, DL

    Смотрите также [Абель, Джордейн]

    Реализация чтения координат в Turbo C++

    ФУНКЦИЯ WHEREX
    ОПИСАНА В: <conio.h> (содержит прототип)
    СИНТАКСИС: int wherex( void );
    НАЗНАЧЕНИЕ: Возвращает горизонтальную позицию курсора в окне.
    ОПИСАНИЕ: wherex возвращает координату X текущей позиции курсора (внутри текущего текстового окна).
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: целое число от 1 до 80.
    ПЕРЕНОСИМОСТЬ: Действительна только для IBM PC и совместимых с ним компьютерах. Аналогичная функция существует в Turbo Pascal.

    ФУНКЦИЯ WHEREY
    ОПИСАНА В: <conio.h> (содержит прототип)
    СИНТАКСИС: int wherey( void);
    НАЗНАЧЕНИЕ: Возвращает вертикальную позицию курсора в окне.
    ОПИСАНИЕ: wherey возвращает координату Y текущей позиции курсора (внутри текущего текстового окна).
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: wherey возвращает целое число от 1 до 25, иногда до 43 или 50.
    ПЕРЕНОСИМОСТЬ: Действительна только для IBM PC и совместимых с ним компьютерах. Аналогичная функция существует в Turbo Pascal.

    Реализация чтения координат курсора на C--

    ФУНКЦИЯ GETXY
    СИНТАКСИС: word GETXY ()
    НАЗНАЧЕНИЕ: Читает позицию курсора на нулевой странице дисплея.
    ПАРАМЕТРЫ ФУНКЦИИ: нет
    ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ:
  • BH = 0
  • AH = DH = позиция строки курсора;
  • AL = DL = позиция столбца курсора;
  • CH = начальная строка курсора;
  • CL = последняя строка курсора.
  • Реализация чтения координат в Turbo Prolog

    Функция cursor языка Турбо Пролог 2.0 позволяет как записывать, так и считывать текущее значение курсора (см. пример).

    Пример 3.13.

    /* ex03013.pro */
    /* Реализация абсолютного позиционирования курсора средствами спец. функции Турбо Prolog. */
    
    domains
    	Row, Col = integer
    
    clauses
    … cursor( Row, Col ), …

    3.3. Резюме

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

    Манипулирование положением курсора часто требует установки драйвера: ANSI.SYS в операционной системе. В новейших операционных системах он установлен по-умолчанию, однако в операционных системах, созданных до 2001 года, этот драйвер может быть не установлен. Для его установки пропишите следующую строку в файле:

    CONFIG.SYS:
    DEVICEHIGH=C:\WINDOWS\Commands\ANSI.SYS
    
    CONFIG.NT
    DEVICEHIGH=%SystemRoot%\System32\ANSI.SYS

    Примечание: Файл C:\CONFIG.SYS используется в операционных системах Windows 9x/ME, а файл %SystemRoot%\System32\CONFIG.NT - в операционных системах Windows 2000/XP/Vista/7.

    Подробнее см. [MS-DOS 6.0, Финогентов I]

    Страницы:

    3.1. Очистка экрана

    Очистку всего экрана можно осуществить с помощью специальной команды или с помощью escape - последовательности Esc[2J. Рассмотрим эти способы поподробнее.

    3.1.1. Реализация на ассемблере

    1-ый метод: использование функции 6 прерывания 10H

    Функция 6 прерывания 10H очищает определённую прямоугольную область экрана. Число строк, на которое надо сдвинуть экран, заносится в регистр AL. Если установлено значение 0, то экран очищается. Строка для верхнего левого угла очищаемой области заносится в регистр CH, столбец для левого верхнего угла - в регистр CL, а значения для правой нижней строки и столбца - в регистры DH и DL соответственно. Атрибут, которым должен чиститься экран, записывается в регистр BH. Он подробно описан в таблице 3.1.

    Примечание: нумерация позиций экрана начинается с точки (0, 0) в верхнем левом углу экрана!

    Числовое значение атрибутов символов (цвет и фон)
    Числ. Значение Цветовой атрибут Символ или фон?
    0 Чёрный Символ
    1 Синий Символ
    2 Зелёный Символ
    3 Циан (голубой) Символ
    4 Красный Символ
    5 Пурпурный Символ
    6 Коричневый Символ
    7 Светло-серый Символ
    8 Тёмно-серый Символ
    9 Светло-синий Символ
    10 Светло-зелёный Символ
    11 Светло-голубой Символ
    12 Светло-красный Символ
    13 Светло-пурпурный Символ
    14 Жёлтый Символ
    15 Белый Символ
    0 Чёрный Фон
    16 Синий Фон
    32 Зелёный Фон
    48 Циан (голубой) Фон
    64 Красный Фон
    80 Пурпурный Фон
    96 Коричневый Фон
    112 Светло-серый Фон
    128 Мигание Символ
    Примечание: Атрибут = Символ+Фон (+ Мигание)

    Пример 3.1

    ; --- Очистка экрана между координатами 0, 0 и 24, 79,
    ; --- нормальное заполнение символов.
    
    	MOV AH, 6	; используемая функция.
    	MOV AL, 0	; очищается весь диапазон
    	MOV BH, 007H	; белые символы на чёрном фоне
    	MOV CH, 0	; левый верхний
    	MOV CL, 0	; угол
    	MOV DH, 24	; правый нижний
    	MOV DL, 79	; угол
    	INT 10H

    2-й метод: использование функции 9 прерывания 10H

    Функция 9 прерывания 10H выводит символ и атрибут столько раз, сколько указано в CX. Значение 2000 чистит весь экран, если курсор установлен в позицию 0, 0. AL должен содержать символ пробела (код 020H), BL - байт атрибутов, а BH - номер страницы дисплея.

    Пример 3.2.

    ; --- установка курсора в левый верхний угол экрана
    	MOV AH, 2	; номер функции
    	MOV BH, 0	; номер экранной страницы
    	MOV DX, 0	; обнуляем координату позиции курсора
    	INT 10H
    ; --- вывод символа 'пробел' 2000 раз
    	MOV AH, 9 	; номер функции
    	MOV CX, 2000	; число повторений вывода
    	MOV AL, 020H	; символ пробела
    	MOV BL, 7	; атрибут 'белый по чёрному'
    	INT 10H

    Дополнительную информацию смотрите [Абель, Джордейн]

    3.1.2. Реализация на языке Си

    Реализация очистки экрана средствами языка Си возможна только посредством использования escape-последовательности:

    Пример 3.3.

    …
    puts( "\x1B[2J" );
    …

    3.1.3. Реализация на Бейсике

    В бейсике для очистки экрана применяется оператор CLS

    ОПЕРАТОР CLS
    СИНТАКСИС: CLS
    НАЗНАЧЕНИЕ: Данный оператор очищает текущий экран вывода программы Basic и переносит экранную позицию вывода (курсор) в координаты (0, 0).
    Оператор не принимает и не возвращает никаких значений.

    3.1.4. Реализация в Command Shell

    Очистку экрана в MS-DOS Command Shell можно осуществить следующим способом:

  • команда CLS, очищающая экран дисплея и устанавливающая курсор в левый верхний угол. Её синтаксис:
    CLS
  • Дополнительную информацию смотри [Финогентов II]

    3.1.5. Реализация в языках Перл, Питон и Пролог

    Реализация очистки экрана средствами языков Перл, Питон и Турбо Пролог не предусмотрена.

    3.2. Управление курсором

    Помимо цвета выводимых символов, гораздо чаще Вам придётся изменять положение курсора на экране дисплея. При этом может потребоваться:

  • Абсолютное позиционирование курсора;
  • Относительное позиционирование (относительно текущей позиции);
  • Запоминание или чтение позиции курсора.
  • Этим операциям мы научимся в этом разделе.

    3.2.1. Абсолютное позиционирование курсора

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

    Для курсора могут быть установлены абсолютные координаты или координаты относительно текущей позиции. Абсолютные координаты могут меняться в пределах 25 (изредка 50) строк и 80 (иногда 40) столбцов. В языках высокого уровня обычно отсчитывают координаты экрана, начиная с единицы. Таким образом, позиция левого верхнего угла - 1, 1. В ассемблере отсчёт всегда начинается с нуля и позиция левого верхнего угла - 0, 0.

    Рассмотрим функции абсолютного позиционирования курсора, реализованные на разных языках.

    3.2.1.1. Реализация на ассемблере

    1-ый метод.

    Функция 2 прерывания 10H устанавливает курсор, относящийся к указанной странице видео памяти.

    ФУНКЦИЯ 2 ПРЕРЫВАНИЯ 10H
    Входные значения:
  • AH = 2 - номер функции
  • BH - номер видеостраницы (обычно 0):
  • DH - строка дисплея. Отсчёт строк начинается с 0;
  • DL - столбец дисплея. Отсчёт столбцов начинается с 0;
  • Пример установки графического курсора в центре экрана:

    Пример 3.4.

    ; --- установка курсора в строку 12, столбец 39.
    	MOV AH, 2	; номер функции
    	MOV BH, 0	; номер страницы
    	MOV DH, 12
    	MOV DL, 39
    	INT 10H

    Подробнее смотри [Абель, Джордейн]

    2-ой метод.

    Второй метод позиционирования курсора состоит в применении escape-последовательностей драйвера ANSI.SYS. В этом случае можно пользоваться функцией 9 прерывания 21H, выводя escape-последовательность как обычную строку.

    Пример 3.5.

    ; --- установка курсора в строку 12, столбец 39.
    
    ; --- в сегменте данных
    DOS_CENTER	DB 	27,'[12;39H$'	; строка позиции курсора
    ; --- в сегменте кода
    	MOV AH, 9	; номер функции вывода строки.
    	LEA DX, DOS_CENTER	; загрузка адреса строки
    	INT 21H

    Подробнее см. [MS_DOS 6.0, Финогентов I]

    3.2.1.2. Реализация в языках Си

    Не смотря на то, что на языке Си есть свои функции управления позицией курсора, предпочтительней использовать средства, предоставляемые драйвером ANSI.SYS (примеры см. ниже).

    Пример 3.6.

    1.	Реализация в Turbo C/C++
    
    const char POS_CENTER[] = "\x1b[12;39H";
    …
    puts( POS_CENTER);
    
    2.	Реализация в SPHINX C--
    
    WRITESTR( "\x1b[13;39H" );

    Подробнее см. [Бочков, Финогентов I]

    Другие функции задания абсолютной позиции курсора в Си:

    Функции Turbo C++

    ФУНКЦИЯ GOTOXY
    ОПИСАНА В: <conio.h> (содержит прототип функции)
    СИНТАКСИС:
    void gotoxy( x, y );
    int x;
    int y:
    НАЗНАЧЕНИЕ: Позиционирует курсор в текстовом окне.
    ОПИСАНИЕ: gotoxy перемещает курсор в текстовом окне в указанную позицию. Если координаты указаны неверно, вызов данной функции игнорируется. Например, это произойдёт при вызове gotoxy(80,30) когда окно имеет размеры 40 столбцов на 25 строк.
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет.
    ПЕРЕНОСИМОСТЬ: Работает только на системах, совместимых с IBM PC. Аналогичная функция есть в Turbo Pascal.

    Функции SPHINX C--

    ФУНКЦИЯ GOTOXY
    СИНТАКСИС:
    void GOTOXY ()
    AL = xloc; BL = yloc;
    НАЗНАЧЕНИЕ: Устанавливает текстовый курсор в позицию, заданную xloc и yloc. Отсчёт позиций начинается с нуля.
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: AX, BX и DX не определены.
    ФУНКЦИЯ GOTOXYZ
    СИНТАКСИС:
    void GOTOXYZ ()
    AL = xloc; BL = yloc; CL = page;
    НАЗНАЧЕНИЕ: Устанавливает текстовый курсор в позицию, заданную xloc и yloc для указанной "page" видео страницы дисплея. Отсчёт значений начинается с нуля.
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: AX,BX,CX и DX не определены.

    3.2.1.3. Реализация в Бейсике

    Бейсик нумерует строки от 1 до 25, а столбцы - от 1 до 80. Абсолютная позиция строки задаётся оператором LOCATE.

    ОПЕРАТОР LOCATE
    Синтаксис: LOCATE строка, столбец

    где

  • строка - переменная или целая константа, указывающая на положение строки вывода;
  • столбец - переменная или целая константа, указывающая на положение столбца вывода.
  • Назначение: Абсолютное позиционирование строки.

    Пример 3.7.

    REM Переместить курсор в центр экрана
    LOCATE 12, 40

    Подробнее см. [Джордейн]

    3.2.1.4. Реализация в Perl и Python

    Абсолютное позиционирование в Perl и Python не реализовано.

    3.2.1.5. Реализация в языке Turbo Prolog

    Абсолютное позиционирование в Turbo Prolog осуществляется с помощью специальной функции (см. примеры ниже).

    ФУНКЦИЯ: CURSOR
    СИНТАКСИС: cursor(Row, Column), где Row - целая переменная, устанавливающая или считывающая значение позиции строки выводимых символов, Column - целая переменная, устанавливающая или считывающая значение столбца на экране, куда выводится символ;
    НАЗНАЧЕНИЕ: Устанавливает или считывает позицию курсора в окне;
    ОПИСАНИЕ: Шаблон: (i,i) Перемещает курсор в указанную позицию ( Row,Column ) относительно начальной позиции (0,0) в активном окне. Шаблон: (o,o), связывает Row и Column с текущей позицией курсора. Никогда не даёт неудачного завершения;
    ШАБЛОНЫ: (i,i) (o,o) ;
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Никогда не даёт неудачного завершения;
    ОШИБКИ: * 1001 Недопустимые значения позиции курсора.

    Пример 3.8.

    /* Реализация абсолютного позиционирования курсора средствами спец. функции Турбо Prolog. */
    
    … cursor(12, 39), …

    3.2.2. Относительное позиционирование курсора

    Функции относительного позиционирования курсора выполняются только через escape-последовательности. Они выводятся на экран на ассемблере с помощью функции 9 прерывания 21H. В таблице 2.1 приводится вид escape-последовательностей для разных операций. Такие последовательности интерпретируются оболочкой как команды управления дисплеем, а не вывод символов строки.

    Возможны следующие направления перемещения курсора:

  • вверх на число строк: esc[числоA ;
  • вниз на число строк: esc[числоB ;
  • вправо на число позиций: esc[числоC ;
  • влево на число позиций: esc[числоD ;
  • включение автоматического перевода курсора на следующую строку: esc[=7h;
  • выключение автоматического перевода курсора на следующую строку: esc[=7l;
  • Кроме того, для управления курсором часто используются следующие "пробельные" метасимволы (см. таблицу 2.2).

    Подробнее см. [MS-DOS 6.0, Финогентов 1]

    3.2.2.1. Реализация на Ассемблере

    Для управления относительным перемещением курсора на языке ассемблера необходимо:

  • задать константу, содержащую эту управляющую последовательность (с последним знаком: "$" );
  • в нужном месте выполнить функцию 9 прерывания 21H.
  • См. пример 3.5.

    3.2.2.2. Реализация на языке Си

    Вывод escape - последовательностей осуществляется с использованием функции puts (потоковая функция).

    Тексты примеров с использованием escape - последовательностей приведены выше (см. пример 3.3. и др.)

    Для переноса вывода в начало новой строки в языке C-- есть функция WRITELN:

    ФУНКЦИЯ WRITELN
    СИНТАКСИС: WRITELN() ;
    НАЗНАЧЕНИЕ: Перемещает курсор в начало следующей строки;
    ВХОДНЫЕ ПАРАМЕТРЫ: нет;
    ФУНКЦИЯ ВОЗВРАЩАЕТ: * AX = 0xE0A;

    * BX = 7;

    3.2.2.3. Реализация на Бейсике

    В реализации функций относительного позиционирования курсора на Бейсике возможны следующий вариант:

    ФУНКЦИЯ TAB
    СИНТАКСИС: TAB( число ), где число - целая константа или переменная, определяющая отступ (в знаках) от позиции начала строки вывода.
    НАЗНАЧЕНИЕ: Функция сдвигает текстовый курсор в указанную позицию вывода на строке.
    ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ: нет.

    3.2.2.4. Реализация в Perl и Python

    В языках Perl и Python относительное позиционирование курсора возможно с помощью "пробельных" управляющих символов.

    Пример 3.9.

    # Реализация на Perl
    # отступ на семь позиций влево с использованием горизонтальной позиции табуляции
    
    print "\n\tТекст";

    Пример 3.10.

    # Реализация на Python примера 3.09.
    # отступ на семь позиций влево с использованием горизонтальной позиции табуляции
    
    print "\n\tТекст";

    3.2.2.5. Реализация в Turbo Prolog

    В языке Turbo Prolog относительное позиционирование курсора возможно с помощью "пробельных" управляющих символов.

    Пример 3.11.

    /* Реализация на Prolog примера 03.009. */
    /* отступ с использованием горизонтальной позиции табуляции */
    
    … nl, write( "\tТекст" ), …

    3.2.3. Запоминание позиции курсора

    Иногда возникают ситуации, когда надо прервать вывод текста, перевести курсор в другую позицию, вывести или ввести параметры программы, а затем продолжить вывод текста со "старого" места.

    Реализацию этой последовательности действий можно осуществить следующим образом:

  • Чтением абсолютной позиции курсора;
  • Запоминанием последней позиции курсора в неконтролируемый программистом буфер, и затем повторной "вставкой на экран" запомненной позиции курсора.
  • Последнюю реализацию можно осуществить с помощью следующих escape последовательностей:

  • Esc[s - сохранение текущей позиции курсора;
  • Esc[u - восстановление сохранённых в буфере координат курсора.
  • Подробнее см. [MS-DOS 6.0, Финогентов I]

    Реализация чтения координат курсора на Ассемблере

    Функция 3 прерывания 10H возвращает строку курсора в DH, а столбец - в DL. На входе надо поместить в BH номер страницы.

    ФУНКЦИЯ 3 ПРЕРЫВАНИЯ 10H
    НАЗНАЧЕНИЕ: Определяет и сохраняет текущую позицию курсора на экране дисплея.
    ПАРАМЕТРЫ: AH = 3 - номер функции;

    BH - номер экранной страницы дисплея;

    ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ: * DH - текущая строка курсора;

    * DL - текущий столбец курсора.

    Пример 3.12.

    ; --- В сегменте данных
    CUR_ROW	DB	? ; текущая строка курсора
    CUR_COL	DB	? ; текущий столбец курсора
    ; --- в сегменте кода
    ; --- определение позиции курсора
    	MOV AH, 3	; номер функции
    	MOV BH, 0	; номер экранной страницы
    	INT 10H
    ; --- Строка - столбец DH - DL
    	MOV CUR_ROW, DH
    	MOV CUR_COL, DL

    Смотрите также [Абель, Джордейн]

    Реализация чтения координат в Turbo C++

    ФУНКЦИЯ WHEREX
    ОПИСАНА В: <conio.h> (содержит прототип)
    СИНТАКСИС: int wherex( void );
    НАЗНАЧЕНИЕ: Возвращает горизонтальную позицию курсора в окне.
    ОПИСАНИЕ: wherex возвращает координату X текущей позиции курсора (внутри текущего текстового окна).
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: целое число от 1 до 80.
    ПЕРЕНОСИМОСТЬ: Действительна только для IBM PC и совместимых с ним компьютерах. Аналогичная функция существует в Turbo Pascal.

    ФУНКЦИЯ WHEREY
    ОПИСАНА В: <conio.h> (содержит прототип)
    СИНТАКСИС: int wherey( void);
    НАЗНАЧЕНИЕ: Возвращает вертикальную позицию курсора в окне.
    ОПИСАНИЕ: wherey возвращает координату Y текущей позиции курсора (внутри текущего текстового окна).
    ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: wherey возвращает целое число от 1 до 25, иногда до 43 или 50.
    ПЕРЕНОСИМОСТЬ: Действительна только для IBM PC и совместимых с ним компьютерах. Аналогичная функция существует в Turbo Pascal.

    Реализация чтения координат курсора на C--

    ФУНКЦИЯ GETXY
    СИНТАКСИС: word GETXY ()
    НАЗНАЧЕНИЕ: Читает позицию курсора на нулевой странице дисплея.
    ПАРАМЕТРЫ ФУНКЦИИ: нет
    ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ:
  • BH = 0
  • AH = DH = позиция строки курсора;
  • AL = DL = позиция столбца курсора;
  • CH = начальная строка курсора;
  • CL = последняя строка курсора.
  • Реализация чтения координат в Turbo Prolog

    Функция cursor языка Турбо Пролог 2.0 позволяет как записывать, так и считывать текущее значение курсора (см. пример).

    Пример 3.13.

    /* ex03013.pro */
    /* Реализация абсолютного позиционирования курсора средствами спец. функции Турбо Prolog. */
    
    domains
    	Row, Col = integer
    
    clauses
    … cursor( Row, Col ), …

    3.3. Резюме

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

    Манипулирование положением курсора часто требует установки драйвера: ANSI.SYS в операционной системе. В новейших операционных системах он установлен по-умолчанию, однако в операционных системах, созданных до 2001 года, этот драйвер может быть не установлен. Для его установки пропишите следующую строку в файле:

    CONFIG.SYS:
    DEVICEHIGH=C:\WINDOWS\Commands\ANSI.SYS
    
    CONFIG.NT
    DEVICEHIGH=%SystemRoot%\System32\ANSI.SYS

    Примечание: Файл C:\CONFIG.SYS используется в операционных системах Windows 9x/ME, а файл %SystemRoot%\System32\CONFIG.NT - в операционных системах Windows 2000/XP/Vista/7.

    Подробнее см. [MS-DOS 6.0, Финогентов I]

    Вернуться к учебному плану