Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

Приложение 1. Вывод русского текста в DOS-окно

Известно, что DOS- и Windows-коды букв русского алфавита различаются. Это обстоятельство надо учитывать при работе с консольприложениями FPS и CVF, поскольку присутствующие в программе символьные данные, если, конечно, исходные тексты набирались в программе, работающей под Windows, например в DS, имеют Windowsкоды, а вывод текста, например, оператором

print *, 'Сообщение на русском языке'

выполняется в DOS-окно.

Так как в Фортране (FPS и CVF) при выводе в DOS-окно не выполняется автоматического преобразования русского Windows-текста в DOS-текст, то об этом должен позаботиться сам пользователь.

Также необходимость преобразований возникает при вводе оператором READ русского текста с клавиатуры или из DOS-файла: введенный текст имеет DOS-кодировку и для дальнейшей работы необходимо его преобразовать в Windows-текст.

Рассмотрим предпосылки создания программы, выполняющей преобразование DOS-текста в Windows-текст и обратное преобразование.

Пусть в файле work1.txt дана строка, содержащая символы как русского, так и латинского алфавитов.

Состав файла work1.txt.

Пример символьной строки. An example of a symbol string.

Заметим, что каждый символ данной, да и любой, строки имеет код - целое положительное число от 1 до 255. Существует также и null-символ, код которого равен нулю.

Задача 1. Найти сумму кодов всех символов строки файла work1.txt, за вычетом пробелов. Вывести также код каждого символа строки.

Используем при решении встроенную функцию IACHAR(c), которая возвращает значение стандартного целого типа, равное коду символа c. Тип параметра c - CHARACTER(1). Длину строки без концевых пробелов найдем функцией LEN_TRIM; i-й символ строки string - это string(i:i).

program symbol_codes

! sco - искомая сумма кодов символов

integer(4) :: i, ico, sco

character(120) :: string

 

character(1) :: ch

 

open(10, file = 'work1.txt')

! Подсоединяем файл к устройству В/В

read(10, '(a)') string

! Ввод строки (одной записи) файла

do i = 1, len_trim(string)

! LEN_TRIM(string) - возвращает длину

412

 

Приложение 1. Вывод русского текста в DOS-окно

ch = string(i:i); ico = iachar(ch)

! строки без концевых пробелов

if(ch /= ' ') sco = sco + ico

! Сумма кодов, не включая коды пробелов

print *, 'Code of symbol ', ch, ' = ', ico

read *

! Ожидаем нажатия Enter

end do

print *, 'Сумма кодов символов строки без кодов пробелов sco = ', sco end program symbol_codes

Просматривая выводимые данные, мы обнаружим, что пробел имеет код 32, а точка - 46. Буквы английского алфавита имеют код в диапазоне от IACHAR('A') = 65 до IACHAR('z') = 122. Буквы русского алфавита в случае DOS-кодовой страницы 866 имеют код в диапазоне от IACHAR('A')

=

= 128 до IACHAR('я') = 239. То есть прописные буквы алфавита имеют меньший код, чем соответствующие им строчные буквы.

Из сопоставления минимального (128) и максимального кодов (239) букв следует, что в этом диапазоне кодов находятся не только коды русских букв, но и коды иных символов. Коды русских букв в DOS-кодовой странице 866 изменяются в диапазонах:

128-159 - коды прописных букв от А до Я;

160-175 - коды строчных букв от а до п;

224-239 - коды строчных букв от р до я.

Можно, применив встроенную функцию CHAR(i), выполнить и обратное преобразование: код символа - символ.

Задача 2. Вывести все буквы русского алфавита.

program russian_letters

 

integer(4) :: i

 

character(1) :: ch

 

do i = 128, 128 + 31

! Вывод прописных букв

print '(a, i3, a, a)', 'Capital latter with code ', i, ' - ', char(i)

read *

! Ожидаем нажатия Enter

end do

 

do i = 160, 160 + 15

! Вывод первых 16 строчных букв

print '(a, i3, a, a)', 'Small letter with code ', i, ' - ', char(i)

read *

! Ожидаем нажатия Enter

end do

 

do i = 224, 239

! Вывод следующих 16 строчных букв

print '(a, i3, a, a)', 'Small letter with code ', i, ' - ', char(i)

read *

! Ожидаем нажатия Enter

end do

 

end program russian_letters

 

Сохраним после ввода с клавиатуры строку текста в файле, использовав, например, такую программу:

413

О. В. Бартеньев. Современный ФОРТРАН

program string_to_file

 

character(120) string

 

open(10, file = 'work1.txt')

! Подсоединяем файл к устройству В/В

read '(a)', string

! Введем: Пример DOS-строки текста.

write(10, '(a)') string

! Вывод DOS-строки в файл work1.txt

end program string_to_file

 

Откроем файл work1.txt, например, в DS или в стандартной Windowsпрограмме NotePad (блокнот). Тогда введенная в DOS-режиме строка файла work1.txt предстанет в виде нечитаемого набора символов:

ЏаЁ¬Ґа DOS-бва®ЄЁ ⥪бв .

Задача 3. Преобразовать строку из DOS-представления в Windowsпредставление.

Задача 4. Преобразовать строку из Windows-представления в DOSпредставление.

Решим прежде промежуточную задачу.

Задача 5. Вывести в файл work2.txt Windows-коды букв русского алфавита, принимая во внимание, что Windows-код русской буквы больше ее DOS-кода.

Воспользуемся для этого программой

program windows_codes

 

integer(2) :: i

 

open(11, file = 'work2.txt')

! Подсоединяем файл к устройству В/В

do i = 160, 255

 

write(11, '(i4, 2x, a1)') i, char(i)

! Вывод Windows-кодов и символов

end do

! в файл work2.txt

end program windows_codes

 

Проанализировав файл work2.txt, мы обнаружим, что коды русских букв в Windows-кодовой странице 1251 изменяются в таких диапазонах:

192-223 - коды прописных букв от А до Я;

224-255 - коды строчных букв от а до я.

Таким образом, чтобы преобразовать DOS-букву ru_letter русского алфавита в Windows-букву ru_letter русского алфавита потребуется выполнить для букв с DOS-кодами от 128 до 175 (буквы А - Я, а - п) оператор

ru_letter = CHAR(ru_letter + (192 - 128))

А для букв с DOS-кодами от 224 до 239 (буквы р - я) следует применить оператор

ru_letter = CHAR(ru_letter + (255 - 239))

Понятно, что обратное преобразование потребует уменьшение Windowsкода буквы до соответствующего ее DOS-кода.

414

Приложение 1. Вывод русского текста в DOS-окно

Оформим преобразования DOS - Windows и Windows - DOS в виде внешней символьной функции

string = RuDosWin(string, dos_win)

которую разместим в модуле TextTransfer. Функция RuDosWin такова, что если ее параметр dos_win равен .TRUE., то выполняется преобразование DOS - Windows, в противном случае (dos_win = .FALSE.) выполняется преобразование Windows - DOS.

Функция RuDosWin позволит выводить в консоль-проектах русские тексты в DOS-окно и читать оператором READ русские DOS-тексты в приложениях CVF и FPS.

module TextTransfer

! Длина строк - результирующих переменных символьных функций integer(4), parameter :: ncresults = 250

contains

!Функция преобразовывает текст DOS в текст Windows, если dos_win = .TRUE.,

!и преобразовывает текст Windows в текст DOS, если dos_win = .FASLE. function RuDosWin(string, dos_win) ! Длина строки string не должна превышать

character(ncresults) :: RuDosWin ! ncresults символов

!Параметры string и dos_win имеют вид связи IN

!и, следовательно, не должны изменяться в RuDosWin character(*), intent(in) :: string

logical(4), intent(in) :: dos_win

!dif - величина, на которую при преобразовании изменяется код буквы integer(2) :: i, dos_win_code, dif

RuDosWin = string

do i = 1, len_trim(RuDosWin)

!dos_win_code – DOSили Windows-код символа

dos_win_code = iachar(RuDosWin(i:i))

dif = 0

! dif больше нуля, если символ - русская буква

if(dos_win) then

! Если преобразование DOS - Windows

select case(dos_win_code)

! Найдем величину dif

case(128 : 175)

! DOS-русские буквы от А до Я и от а до п

dif = 64

! DOS-русские буквы от р до я

case(224 : 239)

dif = 16

 

end select

 

else

! Преобразование Windows - DOS

select case(dos_win_code)

! Windows-русские буквы от А до Я и от а до п

case(192 : 239)

dif = -64

! Windows-русские буквы от р до я

case(240 : 255)

dif = -16

 

end select

 

end if

 

! Выполняем преобразование символа, если он является буквой русского алфавита

415

О. В. Бартеньев. Современный ФОРТРАН

if(dif /= 0) RuDosWin(i:i) = char(dos_win_code + dif) end do

end function RuDosWin end module TextTransfer

Пример. Вывести в консоль-приложении заданный в программе русский текст (он имеет Windows-кодировку) в DOS-окно, а введенный с клавиатуры DOS-текст вывести в текстовой файл a.txt, выполнив предварительно преобразование DOS-Windows.

program text_go use TextTransfer

character(120) :: string

!Выводим на консоль DOS-текст Введите строку на русском языке,

!получаемый после преобразования Windows-DOS

!Встроенная функция TRIM выполняет отсечение концевых пробелов print *, trim(RuDosWin('Введите строку на русском языке', .false.))

read(*, '(a)') string

! Вводим с клавиатуры DOS-текст

! Введем: Текст на русском языке

print *, string

! Выводим строку на консоль без преобразований

! Результат: Текст на русском языке

open(10, file = 'a.txt')

 

write(10, '(a)') string

! Выводим строку в файл a.txt без преобразований

!Просмотрим файл a.txt в "Блокноте" (NotePad)

!Результат - нечитаемый текст: ’Ґбв - агббЄ®¬ п§лЄҐ

!Выводим строку в файл a.txt после преобразований write(10, '(a)') RuDosWin(string, .true.)

!Просмотрим файл a.txt в "Блокноте"

!Результат: Текст на русском языке

end program text_go

416