faqs.org.ru

 Главная > Программирование > Другие языки >

FAQ по BASIC

From: Gregory Zeldner <Gregory.Zeldner@f1967.n5020.z2.fidonet.org>
Date: Sat, 31 Aug 2002 23:05:00 +0400


                       BASIC FAQ
           Наиболее часто задаваемые вопросы
              в конференции RU.DOS.BASIC
------------------------------------------------------------
               (C) Gregory Zeldner 2001
               ~~~~~~~~~~~~~~~~~~~~~~~~
Все права на данный документ принадлежат автору. Приветству-
ется некоммерческое использование и распространение  в  сети
Fidonet.  Полный или частичный форвард в другие сети катего-
рически запрещается.

-------------------------------------------------------------

Q: Чем отличаются между собой QuickBASIC,  QBASIC и Microsoft
   BASIC Professional Development System (PDS)?
Q: Почему обсуждение Visial BASIC for DOS является оффтопиком?
Q: Существуют ли реализации языка BASIC других фирм?
Q: Какие существуют конференции со сходной тематикой?
Q: Почему никогда не следует использовать оператор GOTO?
Q: Что такое модульное программирование?
Q: Как ввести малую русскую букву "р" в среде QuickBASIC?
Q: Как подключить мышь?
Q: Как прочитать содержимое текущей директории?
Q: Как вернуть ERRORLEVEL - код завершения программы?
Q: Как передать управление большой внешней программе и  вернуться
   обратно?
Q: Как избежать пpинудительной пpокpутки экpана пpи выводе инфоp-
   мации на 24 и 25 стpоке?
Q: Как опpеделить, сколько стpок на экpане выставил пользователь
   до запуска пpогpаммы?
Q: Как перекодировать текст из кодировки DOS в WIN1251 или в KOI8R?

> Q: Чем отличаются между собой QuickBASIC,  QBASIC и  Microsoft
> BASIC Professional Development System (PDS)?

QuickBASIC.
     Создание Microsoft QuickBASIC (сокращенное обозначение - QB)
в середине 80-х годов произвело настоящую революцию в мире BASIC,
результатом  которой было то,  что впервые этот язык занял доста-
точно прочные позиции среди средств разработки серьезных приклад-
ных систем.В QuickBASIC в достаточно полной мере реализованы идеи
структурного и модульного программирования, возможности использо-
вания процедур и функций.
     Специфика технологии программирования в среде QB определяет-
ся наличием в ней двух трансляторов - интерпретатора и компилято-
ра.  Основу интегрированной среды, в которой выполняется основной
объем разработки и отладки программы, составляет Интеллектуальный
редактор и интерпретатор компилирующего типа (ИКТ). ИКТ - это но-
вый тип интерпретатора,  который производит предварительные "ком-
пиляцию и компоновку" программы в специальный псевдокод,  а затем
уже ее выполнение.  При завершении отладки программы пользователь
может  создать  исполняемый  EXE-модуль с помощью настоящего ком-
пилятора и компоновщика программ.

QBASIC.
     Начиная с версии MS-DOS  5.0,  вместо  устаревшего  GW-BASIC
фирма  Microsoft стала поставлять систему QBASIC,  которая предс-
тавляет собой усеченный вариант QuickBASIC без компилятора и  не-
которых возможностей модульного программирования.  QBASIC, конеч-
но,  может вполне использоваться для обучения и написания неболь-
ших программок,  но не для сколь-нибудь серьезной работы.  И дело
здесь не только в невозможности создавать исполняемые  модули.  В
версии  QBASIC  программа  может состоять только из одного модуля
(отсутствует операция LOAD) и следовательно  нельзя  загружать  и
использовать ранее созданные модули.  А на разработке по принципу
"напиши по новой всю программу от начала до конца" далеко, конеч-
но, не уедешь.


MICROSOFT BASIC PROFESSIONAL DEVELOPMENT SYSTEM (PDS)
     В 1989  году появилась Microsoft Basic Professional Develoр-
ment System (система для профессиональной разработки) версии 7.0,
а  на  следующий  год ее сменила версия 7.1.  Сегодня ее называют
Microsoft BASIC или просто PDS.  Это дальнейшее логическое разви-
тие QB 4.5 и в этом плане название QuickBASIC Extended (расширен-
ный) вполне оправдано.
     Краткая характеристика Basic PDS,  по сравнению  с  QB  4.5,
заключается  в  следующем:  он  позволяет  создавать более мощные
программные комплексы и расширить круг решаемых задач за счет ис-
пользования  дополнительных возможностей процессора и оперативной
памяти, новых средств разработки программ, встроенной системы уп-
равления большими базами данных,  а также повышения эффективности
программного кода (объем  памяти,  быстродействие).  Кроме  новых
возможностей,  в PDS исправлены ряд ошибок QB,  в частности,  нет
проблем с вводом прописной русской буквы "р".  Большинство приме-
ров программ  в  данном FAQ ориентированы в первую очередь на ис-
пользование PDS.

> Q: Почему обсуждение Visial BASIC for DOS является оффтопиком?

A: VBDOS является не более чем утяжеленной версией PDS. Абсолютно
все возможности VBDOS (за исключением средств  визуального  прог-
раммирования) имеются и в PDS. А для программиста, имеющего навык
работы с предыдущими версиями BASIC фирмы Microsoft средства  ви-
зуального  программирования  явяются совершенно чужеродными,  так
как фактически требуют изучить новый язык, не нужный при програм-
мировании в текстовом режиме DOS. Именно новый, поскольку объект-
ные конструкции Visual интерфейса мало  похожи  на  "человеческий
язык",  столь милый сердцу приверженцев BASIC, а более напоминают
"инопланетные" конструкции C или Pascal.  Так что любителям визу-
ального  программирования  в  этой  эхе делать нечего - их ждут в
RU.VISIAL.BASIC.

>  Q: Существуют ли реализации языка BASIC других фирм?

A: Разумеется, фирма Microsoft не является единственным разработ-
чиком систем BASIC. Существуют также версии GFA, True, Power, Z и
некоторые другие,  но они не получили столь широкое распростране-
ние - отношение объема продаж языков BASIC фирмы Microsoft к реа-
лизациям BASIC остальных фирм составляет 12:1.



>Q: Почему никогда не следует использовать оператор GOTO?

A: Оператор GOTO - старейший и неструктурированный оператор языка
BASIC.  Программу с обилием GOTO трудно читать,  отлаживать,  мо-
дифицировать, так как она не имеет четкой структуры.
     Использование в  программе  оператора GOTO свидетельствует о
том,  что программист не полностью овладел всем богатством управ-
ляющих структур языка QuickBASIC, или не знает их возможностей, а
кроме того,  не существует программных конструкций,  где действи-
тельно было бы необходимо применение оператора GOTO.
     Приведу примеры того,  как можно избежать применения GOTO  и
других устаревших  конструкций,  которые достались QuickBASIC "по
наследству" от GWBASIC.

     Как получить код нажатой клавиши:
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     m1: A$ = INKEY$: IF A$ = "" GOTO m1

     Эту конструкцию можно переписать,  используя цикл  DO...LOOP
WHILE:

     DO: A$= INKEY$: LOOP WHILE A$ = ""

     Как выйти из цикла по условию:
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     FOR i = 1 TO 1000
     ...
        IF Flag% = TRUE THEN GOTO m999
     ...
     NEXT i
        .
        .
        .
     m999:

     В этом  случае можно воспользоваться альтернативным выходом
из цикла FOR...NEXT - EXIT FOR:

     FOR i = 1 TO 1000
     ...
        IF Flag% = TRUE THEN EXIT FOR
     ...
     NEXT i
        .
        .
        .

     Точно также можно выйти и из цикла DO...LOOP:

     DO
     ...
        IF Flag% = TRUE THEN EXIT DO
     ...
     LOOP
        .
        .
        .

     Предвижу вопрос:  а если нужно выйти из середины конструкции
WHILE...WEND  -  ведь  оператор EXIT WHILE не предусмотрен (также
как и EXIT SELECT)?  Казалось,  бы - ведь в таких  случаях  можно
просто написать:

     WHILE A$ <> "Конец"
     ...
        IF Flag = FALSE THEN GOTO m998
     ...

     WEND
        .
        .
        .
     m998:

     Я считаю,  что и в этом случае применение оператора GOTO из-
лишним. Конечно,  чтобы обойти это ограничение приходится идти на
хитрость - обрамлять конструкцию бесконечным циклом DO...LOOP  и
выходить с  помощью  EXIT  DO  - даже в этом случае,  это гораздо
удобнее, нагляднее, и я бы сказал красивее:

     DO
        WHILE A$ <> "Конец"
        ...
           IF Flag = FALSE THEN EXIT DO
        ...
        WEND
        EXIT DO
     LOOP
        .
        .
        .

     Также можно организовать и "EXIT SELECT":

     DO
        INPUT Kod
        SELECT CASE KOD
           CASE IS = ...
           ...
           CASE IS = 0: EXIT DO
           ...
           CASE ELSE ...
           ...
        END SELECT
     LOOP

     Как избежать синдрома "ёжика в тумане"
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     При организации  ветвления бесконечные операторы GOTO мешают
понять логику программы:

     30 INPUT A
        IF A > 100 THEN PRINT "Это много": GOTO 30
        IF A = 100 THEN GOTO 300
        PRINT A/100: GOTO 30
     ...

     300 ...

     Вместо этого можно использовать или блочную форму оператора
IF...THEN...ELSE в окружении цикла DO...LOOP WHILE:

     DO
        INPUT A
        IF A < 100 THEN
           PRINT A / 100
        ELSEIF A > 100 THEN
           PRINT "слишком много"
        END IF
     LOOP WHILE A <> 100
        .
        .
        .

     ...или конструкцию  SELECT...CASE  в  окружении цикла DO ...
LOOP

     DO
        INPUT A
        SELECT CASE A
           CASE IS < 100: PRINT A / 100
           CASE IS > 100: PRINT "слишком много"
           CASE IS = 100: EXIT DO
        END SELECT
     LOOP
        .
        .
        .
     Как правильно "разветвиться"
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     При организации  ветвления  вместо  устаревшей   управляющей
конструкции ON...GOSUB используйте более современную кон-струкцию
SELECT...END SELECT:

     m0: INPUT A
        ON A GOSUB m1, m2, m3, m3, m4, m4, m4
        GOTO m5
        m1:
          ...
        X = y * z
          ...
        RETURN
        m2:
          ...
        RETURN
        m3:
          ...
        RETURN
        m4:
          ...
        RETURN
        m5: ...

    Не правда ли,  с первого раза трудно понять, что это фрагмент
программы делает. Приходится проговаривать про себя: "Если значе-
ние A равно единице,  то ... перейти на метку... метку m1, вычис-
лить  значение  X  ...  вернуться  на  следующий  оператор пос-ле
ON...GOSUB ... это переход на метку m5 ... метка m5 - это продол-
жение выполнения программы..."

     Посмотрите, насколько  удобнее использование конструкции SE-
LECT...END SELECT:

     INPUT A
     SELECT CASE A
        CASE IS = 1:
        ...
        X = y * z
        ...
        CASE IS = 2
        ...
        CASE IS = 3, 4
        ...
        CASE 5 TO 7
        ...
     END SELECT

     "Если значение A равно единице,  вычислить значение X и  по-
кинуть SELECT...END SELECT".


>Q: Что такое модульное программирование?

     При разработке  собственной программы у каждого программиста
через некоторое время появляется большой набор собственных  заго-
товок, неординарных решений и т.  д., которые он хотел бы исполь-
зовать во всех своих творениях.
     QuickBASIC предоставляет такую возможность,  позволяя разра-
батывать программы по модульному принципу.  Модуль - это  отдель-
ная, полностью независимая от других, часть Вашей программы. Каж-
дая программа на QuickBASIC может состоять из одного или несколь-
ких модулей.
     Каждый модуль имеет главную часть.  В главной  части  модуля
описываются процедуры  и  функции  модуля  (операторами DECLARE),
функции DEF FN, константы (оператор CONST).
     В сpеде  для создания пpоцедуp и функций испольуется команда
"Edit - New Sub" и "Edit - New Function". Пpосмотp текущих пpоце-
дуp и функций вызывается по клавише F2.
     Один из модулей называется главным. Он содержит так называе-
мую точку входа,  с которой начинается  выполнение  программы.  В
каждой программе может быть только один главный модуль.

MAIN.BAS
    +- SUB One
    +- FUNCTION Two

     К главному модулю можно подключить один или несколько  вспо-
могательных (дополнительных)  модулей.  В чем же преимущество мо-
дульного программирования?

MAIN.BAS
    +- SUB one
    +- FUNCTION two
ADD-ON.BAS
    +- SUB three
    +- SUB forth
    +- FINCTION six

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

OTHER.BAS
    +- SUB one
    +- FUNCTION two
ADD-ON.BAS
    +- SUB three
    +- SUB forth
    +- FINCTION six

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

>Q: Как ввести малую русскую букву "р" в среде QuickBASIC?

A: К сожалению,  стандартными средствами (INPUT, INPUT$, LINE IN-
PUT,  INKEY$)  невозможно  ввести  символ с кодом 224 - это малая
русская буква "р" в альтернативной кодировке.  Это связано с  не-
корректным опросом клавиатуры, который выполняет BASIC. Есть нес-
колько вариантов решения.

     1. Использовать драйвер русских букв с изменяемой раскладкой
клавиатуры,  который  бы  подставлял  английскую букву "p" вместо
русской "р",  например KEYRUS. Однако, если вы вводите таким спо-
собом,  скажем  фамилии,  то их невозможно будет отсортировать по
алфавиту;
     2. Другим вариантом является использование "примочек" к  фи-
дошному редактору  сообщений GoldED,  например GEDSTART.COM.  Эта
программа подменяет при вводе текста не только "H", но и "р". Не-
достатки такого подхода те же, что и описанные выше.
     3. Отказаться  от  стандартных операторов BASIC и опрашивать
клавиатуру самостоятельно, используя прерывание BIOS 16h, функция
0. Для  использования прерываний необходимо загрузить среду с па-
раметром "/L".

=== cut CHAR.BAS ===

'$INCLUDE: 'interupt.bi'
DECLARE SUB Char (c$)

' Define the type needed for Interrupt
TYPE RegType
     ax    AS INTEGER
     bx    AS INTEGER
     cx    AS INTEGER
     dx    AS INTEGER
     bp    AS INTEGER
     si    AS INTEGER
     di    AS INTEGER
     flags AS INTEGER
END TYPE

DIM SHARED Inreg AS RegType
DIM SHARED Outreg AS RegType

     ' Вызов процедуры CHAR, печать всех вводимых символов
     ' ESC - конец работы программы
     DO
        CALL Char(a$): PRINT a$;
        IF a$ = CHR$(27) THEN EXIT DO
     LOOP
     END
     SUB Char (c$)
     ' *****************************************************
     ' Данная процедура корректно обрабатывает ввод всех
     ' символов  ASCII, включая малую русскую букву "р"
     ' используя прерывание BIOS 16h, функция 0.
     ' Вызов: CALL Char (variable$)
     ' Аналог:
     ' DO: variable$ = INKEY$: LOOP WHILE variable$ = ""
     ' *****************************************************

     n = &H16: ' прерывание 16h
     inreg.ax = 0: ' функция 0
     CALL Interrupt(n, inreg, outreg)
     nah = outreg.ax \ 256: nal = outreg.ax MOD 256
     c$ = CHR$(nal): IF nal = 0 THEN c$ = c$ + CHR$(nah)
     END SUB

=== end CHAR.BAS ===

     4. Пропатчить саму среду QuickBASIC и все необходимые для
компиляции библиотеки:

=== cut QB45.CRK ===

 Russian "p" for QuickBasic 4.5
(c) Igor Knizhny (2:5020/1343.20)

File QB.EXE
qb.exe
00024A75: 3C 0A
00024A76: E0 E4
00024A78: 14 04
00024A7A: F0 E0

File BRUN45.EXE
brun45.exe
00007C97: 3C 0A
00007C98: E0 E4
00007C9A: 14 04
00007C9C: F0 E0


File BCOM45.LIB
bcom45.lib
0001C83C: 3C 0A
0001C83D: E0 E4
0001C83F: 14 04
0001C841: F0 E0

=== end QB45.CRK ===

     5. Перейти  на следующую версию языка - Microsoft BASIC Pro-
fessional Development System, где эта ошибка, наконец, исправле-
на.

>Q: Как подключить мышь?

A: Процедура MOUSE, использующая прерывание INT 33H позволяет уп-
равлять мышью из программы на языке BASIC. Для использования пре-
рываний необходимо загрузить среду с параметром "/L".

=== cut MOUSE.BAS ===

'*****************************************
'
'MOUSETST.BAS - интерфейс с драйвером мыши
'
'*****************************************

DEFINT A-Z

DECLARE SUB MOUSE (m1%, m2%, m3%, m4%)

' Define the type needed for Interrupt

TYPE RegType
     ax    AS INTEGER
     bx    AS INTEGER
     cx    AS INTEGER
     dx    AS INTEGER
     bp    AS INTEGER
     si    AS INTEGER
     di    AS INTEGER
     flags AS INTEGER
END TYPE

DIM SHARED Inreg AS RegType
DIM SHARED Outreg AS RegType

SCREEN 12

'включить курсор мыши
G1% = 1: CALL MOUSE(G1%, G2%, G3%, G4%)

' Пpочитать кооpдинаты кypсоpа и статyс кнопок
DO
   G1% = 3: CALL MOUSE(G1%, G2%, G3%, G4%)
   LOCATE 1, 1: PRINT "Кооpдинаты мыши : X ="; G3%; " Y ="; G4%; " "
   LOCATE 3, 1
   SELECT CASE G2%
      CASE IS = 1: PRINT "Нажата левая кнопка  "
      CASE IS = 2: PRINT "Нажата пpавая кнопка "
      CASE IS = 4: PRINT "Нажата сpедняя кнопка"
      CASE ELSE:   PRINT "Кнопки не нажаты     "
   END SELECT
   IF INKEY$ <> "" THEN EXIT DO
LOOP

'Погасить курсор мыши
G1% = 2: CALL MOUSE(G1%, G2%, G3%, G4%)

SCREEN 0

SUB MOUSE (m1, m2, m3, m4)
' *****************************************************
' Эта пpоцедypа обеспечивает интеpфейс с дpайвеpом мыши
' m1, m2, m3, m4 - паpаметpы, пеpедаваемые в дpайвеp мыши
' и возвpащаемые оттyда. Они соответствyют pегистpам
' пpоцессоpа AX, BX, CX, DX
' *****************************************************
n = &H33:       ' пpеpывание 33h
Inreg.ax = m1   ' входные pегистpы
Inreg.bx = m2
Inreg.cx = m3
Inreg.dx = m4
CALL Interrupt(n, Inreg, Outreg)
m1 = Outreg.ax  ' выходные pегистpы
m2 = Outreg.bx
m3 = Outreg.cx
m4 = Outreg.dx

END SUB

=== end MOUSE.BAS ===

>Q: Как прочитать содержимое текущей директории?

    В PDS  используется функция DIR$.  При первом запуске функции
передается маска для поиска файлов и возвращается первое имя фай-
ла по  заданной маске.  При следующих запусках возвращаются имена
остальных файлов:

=== cut LIST.BAS ===

'***********************************************************
'
'LIST.BAS - программа чтения содержимого текущей директории
'
'***********************************************************

DEFINT A-Z
REDIM FileName$(1)

'определяем маску для поиска файлов
maska$ = "*.*"

count = 1: CLS

'первый файл
FileName$(1) = DIR$(maska$)

IF FileName$(1) <> "" THEN
   'cледующий файл
   DO
     FindNext$ = DIR$
     IF FindNext$ <> "" THEN
        count = count + 1
        REDIM PRESERVE FileName$(count)
        FileName$(count) = FindNext$
      ELSE
        EXIT DO
      END IF
   LOOP
ELSE
   PRINT "В текущей директории нет файлов": END
END IF

'вывод результатов
PRINT "Всего найдено файлов:"; count
PRINT
FOR i = 1 TO count
   PRINT FileName$(i)
NEXT i

'ждем нажатия любой клавиши
DO: LOOP WHILE INKEY$ = ""

END

=== end LIST.BAS ===

   Часто при программировании возникает задача проверки существо-
вания того или иного файла.  Для этого также  можно  использовать
функцию DIR$:

IF DIR$(filename$)<> "" THEN
   PRINT "Файл существует"
ELSE
   PRINT "Файл не существует"
END IF

Q: Как вернуть ERRORLEVEL - код завершения программы?

   В PDS операторы окончания программы (END,  SYSTEM, STOP) имеют
необязательный  параметр - код завершения.  Это должно быть целое
число в интервале от 0 до 255.  ERRORLEVEL используется в команд-
ных файлах DOS для организации ветвления.

=== cut ERROR.BAS ===

IF OK THEN
   END 0
ELSE
   END 64
END IF

=== end ERROR.BAS ===

>Q: Как передать управление большой внешней программе и  вернуться
>   обратно?

     Оператор SHELL  позволяет  передать управления внешней прог-
рамме,  а после ее завершения вернуться в основную программу. Од-
нако при этом память,  занимаемая основной программой не освобож-
дается и может возникнуть ситуация когда ее  станет  недостаточно
для внешней программы.
    Оператор CHAIN освобождает память,  занимаемую основной прог-
раммой и запускает внешнюю,  но при этом возникает вопрос - а как
же вернуться в основную  программу?  Конечно,  можно  решить  эту
проблему, запуская командный файл и организуя ветвление по ERROR-
LEVEL. Но есть способ лучше - полная передача управления програм-
ме-спутнику,  которая запускает внешнюю программу через SHELL,  а
затем передает управление основной программе:

   MAIN.BAS    - основная программа
   BIG.EXE     - внешняя программа
   QBSWAP.EXE  - решение проблемы :)


=== cut MAIN.BAS ===
   .
   .
   .
   CHAIN "QBSWAP"
   .
   .
   .
=== end MAIN.BAS ===

=== cut QBSWAP.BAS ===

   SHELL "BIG"
   CHAIN "MAIN"

=== end QBSWAP.BAS ===


>Q: Пpи  установке куpсоpа на 24 или 25 стpоку с помощью LOCATE и
>попытки что-либо напечатать с помощью PRINT пpоисходит  автомати-
>ческая пpокpутка экpана. Как этого избежать?

    Скpоллинг (пpокpутка)  экpана пpоисходит пpи пеpеводе куpсоpа
в стpоку,  котоpую BASIC считает уже не видимой на экpане пользо-
вателю.  Сpазу  после запуска пpогpаммы BASIC считает,  что такой
"уже невидимой стpокой" является стpока номеp 25.  есмотря на то,
что  эта строка присутствует на экране,  она считается служебной,
пpедназначенной для вывода инфоpмации опеpатоpом KEY ON.
    Если принудительная  пpокpутка  экpана  ломает  логику работы
программы, есть два пути решения:

    1. Не давать пpогpамме автоматически пеpевести куpсоp в стpо-
ку 25:

         LOCATE 24, 1, 1: PRINT "Line 24";
         DO WHILE INKEY$ = "": LOOP

    В pезультате на 24 строке появится надпись "Line 24", но бла-
годаpя точке с запятой в конце PRINT, куpсоp останется на этой же
строке.   еобходимо об этом всегда помнить при работе с 24  и  25
строкой.

    2. Можно  явно указать ,  что последняя стpока имеет номеp 25
(соответственно,  "пеpвая невидимая стpока" - 26). Это делается с
помощью оператора VIEW PRINT.

         VIEW PRINT 1 TO 25
         LOCATE 24, 1, 1: PRINT "Line 24"
         DO WHILE INKEY$ = "": LOOP

    Тепеpь оператор PRINT не вызвает прокрутку и без ";".  Однако
для вывода информации в строку 25 все равно придется использовать
способ 1.

>Q: Как избежать пpинудительной пpокpутки экpана пpи выводе инфоp-
>   мации на 24 и 25 стpоке?

    Slawa Michalev (2:5020/1308.70):
    Скpоллинг (пpокpутка)  экpана пpоисходит пpи пеpеводе куpсоpа
в стpоку,  котоpую BASIC считает уже не видимой на экpане пользо-
вателю.  Сpазу  после запуска пpогpаммы BASIC считает,  что такой
"уже невидимой стpокой" является стpока номеp 25. Несмотря на то,
что  эта строка присутствует на экране,  она считается служебной,
пpедназначенной для вывода инфоpмации опеpатоpом KEY ON.
    Если принудительная  пpокpутка  экpана  ломает логику работы
программы, есть два пути решения:

    1. Не давать пpогpамме  автоматически  пеpевести  куpсоp  в
стpоку 25:

LOCATE 24, 1, 1: PRINT "Line 24";
DO WHILE INKEY$ = "": LOOP

    В pезультате на 24 строке появится надпись "Line 24", но бла-
годаpя точке с запятой в конце PRINT, куpсоp останется на этой же
строке.  Необходимо об этом всегда помнить при работе с 24  и  25
строкой.

    2. Можно  явно указать ,  что последняя стpока имеет номеp 25
(соответственно,  "пеpвая невидимая стpока" - 26). Это делается с
помощью оператора VIEW PRINT.

VIEW PRINT 1 TO 25
LOCATE 24, 1, 1: PRINT "Line 24"
DO WHILE INKEY$ = "": LOOP

      Тепеpь оператор PRINT не вызвает прокрутку и без ";". Одна-
ко для вывода информации в строку 25 все равно  придется  исполь-
зовать способ 1.


>Q: Как опpеделить, сколько стpок на экpане выставил пользователь до
>   запуска пpогpаммы?

    Slawa Michalev (2:5020/1308.70):
    BASIC позволяет  определить три стандартных текстовых режима:
25, 43 и 50 стpок на экpане. С помощью функции MaxRow можно полу-
чить количество доступных программе строк:

DECLARE FUNCTION MaxRow% ()
PRINT "Пpогpамма запущена в pежиме"; MaxRow; "стpок на экpане."

FUNCTION maxRow%
 'запоминаем позицию курсора
  row% = CSRLIN: column% = POS(0)
 'включаем обработчик ошибок
  ON LOCAL ERROR GOTO ErrorHandler
 'пытаемся позиционировать курсор. 60 строк
 'возможны только в графическом режиме (SCREEN 12)
  FOR i% = 25 TO 60
    LOCATE i%
  NEXT i%
  maxRow% = 60

ExitMaxRow:
 'Восстанавливаем положение курсора и покидаем функцию
  LOCATE row%, column%
  EXIT FUNCTION

ErrorHandler:
 'упс :-)
  maxRow% = i% - 1
  RESUME ExitMaxRow
END FUNCTION


>Q: Как перекодировать текст из кодировки DOS в WIN1251 или в KOI8R?

    Anton Samsonov (2:5020/2123):
    Для этого  служит функция XLAT из приведенной ниже программы.
Чтобы таблицы перекодировок  не  были  испорчены  при  пересылке,
программа  DOS2ANS  представлена в виде self-extracted bas-source
code. Ее достаточно  сохранить в файл и запустить.

'>>> Page 1 of DOS2ANS.BAS begins here. TYPE:BINAA TLEN:1875
DEFINT A-Z:DIM SHARED K,S,B&,Z&:V1 'Created by PostIt! 7.1
SUB V1:OPEN "O",1,"DOS2ANS.BAS",4^6:Z&=1875:?STRING$(50,177);
U"%ijkn%syEf(R)2/%ijhq%fwjE%kzsh%ynts(E'qf#yEMG2;0Cx)A2QEMG;0CLi4
U"BC.QEBx)A2Ef%xExy%wnsl.QEBi24BCE%fxEx%ywns%lN2/%2/ht%sxyE)='qf%
U"yEbE%XEEE%EEEE%EEEE%EEEE%EEEE%EEEEdELY'Vzw$tlZ[q'LEwvqttZ[&Hd^E
U"yi'swYW'q'y%2/2/%htsxIyEG;)0CU]%[[Eb%EVEE%EEEE%EEEE%EEEE%EEEE%E
U"EEL%][[E#EREoYze[tlY&o[Vwq&ofhEy'qswY'2qyoEMR]$a&o2/h%tsxyLEG;0
U"&CVWZ%VEbE%WEEE%EEEE%EEEE%EEEE%EEEE%EELV%WZVE%REfs%xn2/%htsxIyE
U"G;)0Cpt%n]Eb%EXEE%EEEE%EEEE%EEEE%EEEE%EEEL2Y]W]#EREy$'sE'kp%t&e
U"oEw&u]'Y%Po_wt&xEM]gRpw[%N2/2%/inr%Exmf%wjiE)0'qf%yMVE#ytE=&'qf
U"y%NEfx%Exyw%nslELLaopqzw_djEZw%kq'z'&q2/2I/LQOMU\]TLEVO[MTfO\)W
U"T_2#/LET3ZzwEbqdE(r'z\$2wzwEuf['[pEwZ^r's&dSxE[t>yZ[EnqE'[tyYd[
U"H'%Eq2wstE4M&tE%zzjT%rnrj%NQ2/RLE&tty'['6YdtEWZw%q<'zdEQ%'rzewE
U"pdH[eEwkv%t&>t&dEjM&o(WYw%t'YQEGA\GEw7EGYG%NS2/I2/0'%qfyMMG;0C%
U"U][[%NEbELGOPQhRSTiMUVWXMYZ[\M]^_$MabcdMefghMijklMmnopMqrstNjuv
U"whxyz%u&'(YuZ[\]u^_$aubcde?fghGI2/0'%qfyMMG;0C%VWZV%NEbEsG9:;Z<
U"=>wu?#ABuCDEFuGHIJuKLMNuOPQRuSTUVuWXYZu[\]^u1_$aubcdeufghiujklm
U"unopqurstu?vwxGI2/0'%qfyMMG;0C%ptn]%NEbEsGZ[pu$]^,uosbcudefguhi
U"klumn_au\wtvuxrquuYj:;uP#=>trOSBuCDEFuGHIKuLMN?uA<WTuVXRQ?U9JG%
U"2/2/#2/L^WYw%tfYEwZl('zePv'qo<&wh2%/2/i#nrE81w4BQCEBw4&BEfx%Exy
U"w%nsl2C/8w4&BEbE&'qfyLMG;0&CVWZ#VQEG2;0CU%][[QmEGHiua[^ksE[j^oe
U"EdwuZak^?dxeEu:^bj?acYF#GQEB1w4BN%2/uw%nsyEIGw4B2D;CE)8B_E#G$EB
U"1w4B2%/uwn#syE81w4B$IEG27M0A02MC4ABLEF4AJ4E27M0=64&3G2/#2/L^PtY
U"tyi'swY<\t[EuZ[Y'by\E[qtyZ[JoEwvjE's&$'xE[Mopzwc_dEZkw%q'5z'qEe
U"qEsYr\r\g%S2/LD\oEqQ^'st%_2/LLEG;0JCxA2%EEEE5Y'sEN[opz>w_dEWZw%
U"qW'z'qpEwZ^r's&'br'E[qtyZ[&o2/LLEG;0JCi4B&CEEE5Y'sEN_tzt5q'xEN[
U"opz>w_dEWZw%qW'z'q%2/LEJBxA2%EEEE#EEEWZZ^'s6&dxEi[tyZK[EszThE(t
U"iYty'qswY'2qyw2I/L\opEqd^3'st_%2/LEJBi4B&CEEE#EEE_Vtv\zle[o[[ER
U"E[qtyZ[^EqE&kt'p^i'sw%$'xE[Mopzw$_tEZkw%q'5z'q2#/LEcl\&y_GwhEqi
U"'vqYPobotf[Ey'Vzw$tlZ[q'gEwv%tt&j&?&d^EWZw%qW'z'qdSETZ_zwE'c&'E
U"Yqoq&'XE&\z'gQ2/RLE(tiYty'qswY'2qyoE$&tE[iYtp\tt[Zh%S2/k%zshy%n
U"tsE&'qfyIEMG;D0CxAA2QEG2;0Ci24BCQCEBxA&2Efx%Exyw%nslQCEBi4)BCEf
U"%xExy%wnsl%N2/2%/Ein.rE8u)>B2/%EinrCEBh7)0AEf%xExy%wnsl%EOEV%2/
U"Ei#nrE8Ly01;J4u>B%2/Ei#nrE8Lh763%2/2/CEBi4)BCEbCEBxA&22/2%/Ekt.
U"wE8u)>BEb%EVEy%tEqj.sMBx)A2N2#/EEBLh70A%EbEr%niIMJBxA2.QE8u)>BQ
U"E%VN2/.EE8yM01;41u>BE%bEns%xywM)0'qfIyMG;D0CxA&2NQEJBh70&AN2/%E
U"EnkCE8y021;4u)>BEy%mjs2%/EEE%rniICMBi4)BCQEJ8u>B%QEVN%EbEr%niIM
U")0'qfIyMG;D0Ci4)BCNQCE8y021;4u)>BQE%VN2/#EEE8Lh763#EbE8Lh763%EP
U"EV%2/EE%jsiE%nk2/#Esj'.yE8u)>B2/#2/E'%qfyE.bE8h27632%/2/j%siEk%
U"zshy%nts2%/2/
END SUB
CLOSE:IF S=80AND B&=Z&THEN?" :) Ok!"ELSE?" :( Bad!
SUB U(A$):FOR A=1TO LEN(A$):C=ASC(MID$(A$,A))-37:IF C<0THEN C=91+C*32
IF K<4THEN K=C+243ELSE?#1,CHR$(C+(K MOD 3)*86);:K=K\3:B&=B&+1
S=(S+C)AND 255:NEXT:LOCATE,1:?STRING$(B&*50\Z&,219);:END SUB
'>>> Page 1 of DOS2ANS.BAS ends here. Last page. TCHK:80

Вернуться в раздел "Другие языки" - Обсудить эту статью на Форуме
Главная - Поиск по сайту - О проекте - Форум - Обратная связь

© faqs.org.ru