О кодировке символов




Скачать 202.59 Kb.
Дата 30.08.2016
Размер 202.59 Kb.
Обработка символьной информации

О кодировке символов


Первые компьютеры умели обрабатывать только числовую информацию. Теперь же большая их часть занята обработкой информации, представленной в виде текста. Чтобы это стало возможно, символы текста (буквы, цифры, знаки препинания и т.д.) стали кодировать при помощи чисел. Для этого создаётся таблица, в которой каждому символу алфавита, при помощи которого в компьютере записываются тексты, присваивается уникальный номер. Получается кодовая таблица. Число символов в этой таблице определяется количеством памяти, выделяемым для кодирования одного символа. Известно, что при помощи бит можно закодировать различных чисел (или символов, т.к. между ними при помощи таблицы задано взаимно однозначное соответствие). Традиционно один символ кодируется при помощи одного байта. Это значит, что размер кодовой таблицы равен 256 символам. При этом сами символы в этой таблице могут быть любыми, в любом порядке они могут следовать друг за другом, и даже их коды можно интерпретировать по-разному. Например, от 0 до 255 или от –128 до +127 включительно. Неизменно только одно: для восьмибитной кодировки количество этих символов, как и их кодов, может быть не больше 256. В дальнейшем будем считать, что коды символов заключены в пределах от 0 до 255.

Чтобы тексты, закодированные на одном компьютере, можно было прочитать на другом, на обоих компьютерах должна использоваться одна и та же кодовая таблица. Т.е. для кодовых таблиц нужна стандартизация. Одним из таких стандартов является ASCII — американский стандартный код для обмена информацией. Он использует 7 бит на кодирование одного символа, т.е. позволяет закодировать символов. В их число входят большие и малые буквы английского алфавита, цифры, знаки препинания, пробел, специальные и управляющие символы. Добавив к ASCII ещё один бит, получили расширенную таблицу ASCII. В ней коды с 128 до 255 включительно используются для кодирования какого-либо национального алфавита, например, русского. Все вместе 255 символов образуют кодовую страницу. Так сложилось, что даже для кодирования русских букв нет единого стандарта. В операционной системе MS-DOS в конце концов пришли к кодовой странице под названием cp866 (или OEM), в Windows применяется cp1251 (или ANSI). В этой кодировке сохраняется текст вашей1 программы, написанной на Delphi из BDS2006, если вы пользовались встроенным редактором Delphi. И при обработке текста программы компилятор Delphi будет пользоваться той же кодовой страницей. Если же вы создаёте программу на FreePascal в Windows, пользуясь IDE, то и при сохранении её текста, и при его обработке компилятором используется кодовая страница cp866. При выводе на экран консольных приложений Windows используется cp866, если приложение само не переключает кодовую страницу. Если вы пользуетесь компилятором командной строки, то и в Delphi, и в FreePascal вы можете задавать кодовую страницу файла с текстом программы при помощи опций.

В приложении 1 приведены таблицы кодировки для кодовых страниц cp866 и cp1251. Как уже указывалось, первые 128 символов с кодами от 0 до 127 для всех кодовых страниц совпадают. А дальше идут различия. Большая русская буква «А» в cp1251 имеет десятичный код 192, а в cp866 код 128. Но, несмотря на различия, во всех кодовых таблицах буква, которая в алфавите стоит раньше, имеет меньший код2. Проследите это по кодовым таблицам приложения 1. Обратите также внимание на то, что соседние в алфавите буквы не обязательно имеют соседние коды. Проверьте это, найдя коды букв «п» и «р» в cp866. А вот соседние цифры имеют соседние коды. Это коды от 48 до 57. Вспомните, что цифра — это тоже символ, только применяется он для записи чисел. Так же, как буква применяется для записи слов. Поэтому включению цифр в состав кодовых таблиц удивляться не стоит. И пробел — тоже символ. Поэтому у него есть код.

При нажатии клавиши Enter в текстовый файл в Windows записывается сразу 2 кода: 13 (возврат каретки) и 10 (переход на следующую строку). Первый из этих кодов заставляет курсор переходить в начало текущей строки, а второй опускает к началу следующей строки. Это надо иметь в виду при вводе информации из текстовых файлов. То же относится и к вводу с клавиатуры.

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

Символьный тип данных


Для хранения одиночных символов в языке Паскаль используется тип данных Char. Константы типа Char записываются в апострофах. Например: 'f', 'А', '9', '?', ' '. Последняя константа — пробел. Если символьной константой является сам символ апострофа, он удваивается: ''''. Можно также задать символьную константу, указав код символа после знака #. Например, запись #128 означает то же, что и 'А' в кодовой странице cp866. Переменная типа Char принимает значение символьных констант. Например,

Var ch : Char;

ch:= '.';



Многоточием в данном случае обозначен пропуск фрагмента программы.

Для определения кода символа применяют функцию Ord. Её аргументом является символ, а результатом — его код. Тип аргумента — char, результата — byte.

Var ch : Char;

Code1, Code2 : Byte;

Code1 := Ord('ю');



Ch:= 'ю';

Code2 := Ord(ch);

И Code1, и Code2 будут равны значению кода буквы «ю», т.е. 238 в cp866 или 254 в ср1251. Можете поэкспериментировать. Введите в Delphi

program Project1;

{$APPTYPE CONSOLE}

Var code : Byte;

Begin

code:=Ord('ю');



WriteLn(code);

End.


Вы увидите на экране число 254. Наберите тот же текст программы в FreePascal и получите 238. Причина — разная кодировка символов текста программы. Замените русскую букву английской, и результаты, выдаваемые Delphi и FreePascal, различаться не будут. Можете провести ещё один эксперимент. Замените теперь 'ю' на 'Ю', и вы увидите, что коды этих букв различны. Когда говорят о том, что в языке Паскаль большие и маленькие буквы не различаются, имеют в виду, что текст программы можно писать, не обращая внимания на регистр символов. За одним исключением: символьные и строковые3 константы всё же чувствительны к регистру.

Чтобы по коду символа получить сам символ, используйте функцию Chr. Её аргумент типа byte, а результат типа char. Например, в кодовой странице cp866 Chr(128) есть 'А', т.е. то же самое, что и #128. Однако, если code — переменная типа byte, то писать в тексте программы Chr(code) можно, а #code — нельзя. Легко понять, что Chr(Ord('ю'))есть 'ю', Ord(Chr(100)) есть 100.

Вводить и выводить переменные символьного типа можно так же, как и числовые, однако при вводе следует проявлять осторожность. Для примера напишем следующую программу.

Program InChar;

Var x, y : Integer;

ch : Char;

Begin

WriteLn('Введите 2 целых числа');



Read(x,y);

WriteLn('А теперь первую букву названия вашего города');

Read(ch);

Write('x=',x,' y=',y,' ch=',ch)

End.

После запуска её на выполнение получим странный, на первый взгляд, результат. Два числа программа спрашивает и ждёт нашего ввода, а вот букву ждать не хочет и после “ch=” вроде бы ничего не выводит. Попробуем узнать код символа, который программа выводит. С этой целью заменим предпоследнюю строку программы следующей:



Write('x=',x,' y=',y,' ch=',ch,' code=',Ord(ch))

Если при вводе двух целых чисел сразу же за последней цифрой второго вы нажали Enter, то результат на экране станет ещё хуже. Выведенные результаты окажутся частично затёртыми, зато с начала строки после одного пробела вы увидите “code=13” и курсор, мигающий сразу после цифры «3». Иногда только по положению курсора можно догадаться, то это всё-таки 13, а не какое-то более длинное число. Попробуем выяснить причину такого поведения программы.

При вводе Read рассматривает поступающие данные как последовательность символов. Допустим, по запросу двух чисел вы ввели

100200

Разумеется, вместо и вы нажали соответствующие клавиши. Read ожидает ввода двух целых чисел. Поэтому он читает и игнорирует все пробельные символы, пока не дойдёт до цифр. Потом читает все цифры, идущие подряд, и сразу после последней цифры останавливается, оставляя следующий за последней цифрой символ для следующего ввода. Последовательность цифр преобразуется в число. Так будут прочитаны все цифры и пробелы, а в буфере ввода останутся коды, сгенерированные при нажатии Enter. Как уже говорилось, это 13 и 10. Переменная ch и получит значение первого из них. При выводе, как и положено, с начала строки программа напишет

x=100 y=200 ch=

Теперь очередь дошла до вывода ch, равного #13. Но это управляющий символ, возвращающий курсор к началу строки. Поэтому с начала строки, затирая все попадающиеся на пути символы, будет написано: « code=13».

Если при вводе данных после последней цифры второго числа вы сделали пробел, а уже потом нажали Enter, то поведение программы будет иным. Разберитесь в этом сами.

Чтобы исправить программу, достаточно хотя бы только первый Read заменить на ReadLn. О различии между ними говорилось на занятии 1.

Для данных символьного типа определены операции сравнения. При этом фактически сравниваются коды символов. Меньшим считается символ с меньшим кодом.

'd' 'Б'

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

'0'

Строковый тип данных


Строкой считается любая последовательность символов. Строковые константы заключаются в апострофы так же, как и символьные переменные.

'машина', 'z12kL'

Если в строке нужно указать сам символ апострофа, то он удваивается, например:

'That''s string'

В записи строковой константы можно задавать символы их кодами:

#161#160#169#226

В кодовой странице cp866 это то же, что и 'байт'.

Можно смешивать два описанные способа задания строковых констант:

'Вставьте в принтер бумагу.'#10'Для продолжения нажмите любую клавишу'#10

Длиной строки называется количество символов этой строки.

Тип данных для работы со строками — string. В стандарте языка Паскаль длина строки ограничена 255 символами. Это ограничение остаётся и в TurboPascal. В FreePascal и Delphi этот тип данных называется ShortString. Т.е. переменная типа ShortString представляет собой строку длиной не более 255 символов. Наряду с этим в FreePascal и Delphi есть тип данных AnsiString, который позволяет хранить строку, длина которой ограничена только размерами оперативной памяти5. Если не изменять настройки по умолчанию в Delpi, а в FreePascal использовать режим совместимости с Delphi, то тип string будет эквивалентен AnsiString. Можно также после ключевого слова string в квадратных скобках задать максимальную длину строки. Она должна быть не больше 255. Например,

{$mode Delphi}

Var name : string[15];

Address : string;

Максимальная длина строки name будет ограничена 15 символами, а строки address размерами оперативной памяти. Хотя внутреннее представление этих строк в памяти компьютера будет разным, правила работы с ними будут одинаковыми.

И ShortString, и AnsiString программист может рассматривать как своего рода массив символов, в котором первый элемент является первым символом строки, второй — вторым и т.д.

{$mode delphi}

Program nnn;

Var s : string;

Begin


s:='малина';

Write(s,' - ');

s[1]:='к';

WriteLn(s)

End.

Так «малина» превращается в «калина». Однако, в отличие от обычных массивов, переменные типа string можно вводить и выводить при помощи Read/ReadLn и Write/WriteLn без использования операторов цикла.



При помощи операции «+» строки можно сцеплять друг с другом: s:=a+b. При этом к концу строки a будет приписано содержимое строки b безо всяких пробелов между ними. Это и станет содержимым строки s.

{$mode delphi}

Program concat;

Var a,b,s : string;

Begin

a:='сос';



b:='на';

s:=a+b;


WriteLn(a,'+',b,'=',s);

s:=b+a;


WriteLn(b,'+',a,'=',s);

End.


Выполнив эту программу, вы убедитесь, что для строк .

Особое значение имеет пустая строка. Это строка, в которой нет ни одного символа. Она обозначается двумя апострофами подряд, без пробела или любого другого символа между ними. Для неё и произвольной строки a справедливо следующее утверждение:

a+'' = ''+a = a

Для строк определена операция сравнения. Выполняется она так. Сравниваются первые символы строк. Если они различны, то та строка меньше, у которой первый символ меньше.

'арбуз'

Если первые символы совпадают, то сравнивают вторые, если и они равны, то третьи и т.д.

'арбуз'>'абажур', 'арбуз'>'арбалет'

Если все символы одной строки уже исчерпаны, а другой ещё нет, то более короткая строка меньше.

'арбуз'

Если все символы одной строки равны символам, стоящим на тех же позициях в другой строке, то эти строки равны.

'арбуз'='арбуз'

Для нахождения длины строки используют функцию Length. Её аргумент имеет тип string, а результат — Integer.

Var s : string;

Len, Len1 : integer;

Len:=length('table');



S:= '';

Len1:=length(s)

В этом примере значение переменной Len будет равно 5, а Len1 нулю, потому что s — пустая строка.

Проиллюстрируем работу со строками следующим примером.



Задача 1. Дана строка s. Получить новую строку s1, в которой все символы следуют в обратном порядке. Например, 'стол' — 'лотс'.

{$mode delphi}

Program revers;

Var s, s1 : string;

i, len : integer;

Begin


WriteLn('Введите строку');

ReadLn(s);


(* Определяем длину строки *)

len:=Length(s);


s1:=''; //В новой строке пока нет символов
(* Начиная с конца строки s, добавляем

в новую строку по одному символу *)

For i:=len DownTo 1 Do

s1:=s1+s[i];


WriteLn(s1)

End.


Приложение 1. Кодовые таблицы


Десятичный код символа

Символ

Примечание

0







1






2






3






4






5






6






7






8






9






10






11



Перевод строки

12






13



Возврат каретки

14






15






16






17






18






19






20






21

§




22






23






24






25






26






27






28






29






30






31






32



пробел

33

!




34






35

#




36

$




37

%




38

&




39






40

(




41

)




42

*




43

+




44

,




45

-




46

.




47

/




48

0

Цифра ноль

49

1




50

2




51

3




52

4




53

5




54

6




55

7




56

8




57

9




58

:




59

;




60





61

=




62

>




63

?




64

@




65

A




66

B




67

C




68

D




69

E




70

F




71

G




72

H




73

I




74

J




75

K




76

L




77

M




78

N




79

O




80

P




81

Q




82

R




83

S




84

T




85

U




86

V




87

W




88

X




89

Y




90

Z




91

[




92

\




93

]




94

^




95

_




96

`




97

a




98

b




99

c




100

d




101

e




102

f




103

g




104

h




105

i




106

j




107

k




108

l




109

m




110

n




111

o




112

p




113

q




114

r




115

s




116

t




117

u




118

v




119

w




120

x




121

y




122

z




123

{




124

|




125

}




126

~




127






Десятичный код символа

Символ

Примечание

cp866

cp1251

128


А

Ђ

129



Б

Ѓ

130



В

131



Г

ѓ

132



Д

133



Е

134



Ж

135



З

136



И

137



Й

138



К

Љ

139



Л

140



М

Њ

141



Н

Ќ

142



О

Ћ

143



П

Џ

144



Р

ђ

145



С

146



Т

147



У

148



Ф

149



Х

150



Ц

151



Ч

152



Ш

˜

153



Щ

154



Ъ

љ

155



Ы

156



Ь

њ

157



Э

ќ

158



Ю

ћ

159



Я

џ

160



а

 

161



б

Ў

162



в

ў

163



г

Ј

164



д

¤

165



е

Ґ

166



ж

¦

167



з

§

168



и

Ё

169



й

©

170



к

Є

171



л

«

172



м

¬

173



н

­

174



о

®

175



п

176


°

177



±

178



І

179



і

180



ґ

181



µ

182



183



·

184



ё

185



186



є

187



»

188



ј

189



Ѕ

190



ѕ

191



ї

192



А

193



Б

194



В

195



Г

196



Д

197



Е

198



Ж

199



З

200



И

201



Й

202



К

203



Л

204



М

205



Н

206



О

207



П

208



Р

209



С

210



Т

211



У

212



Ф

213



Х

214



Ц

215



Ч

216



Ш

217



Щ

218



Ъ

219



Ы

220



Ь

221



Э

222



Ю

223



Я

224



р

а

225



с

б

226



т

в

227



у

г

228



ф

д

229



х

е

230



ц

ж

231



ч

з

232



ш

и

233



щ

й

234



ъ

к

235



ы

л

236



ь

м

237



э

н

238



ю

о

239



я

п

240



Ё

р

241



ё

с

242



Є

т

243



є

у

244



ф

245


ї

х

246



Ў

ц

247



ў

ч

248



°

ш

249



щ

250



·

ъ

251



ы

252



ь

253



¤

э

254



ю

255



 

я


1 Будем считать, что у вас русская версия операционной системы и установлен русский язык системы в разделе «Язык системы и региональные стандарты» Панели управления, как это принято по умолчанию.

2 Это не выполняется только для букв «Ё» и «ё».

3 О строковых переменных и константах речь пойдёт далее

4 Кроме «Ё» и «ё»

5 «AnsiString, also called a long string, represents a dynamically allocated string whose maximum length is limited only by available memory», — как сказано в системе помощи Delphi. В документации по FreePascal: «Ansistrings are strings that have no length limit».


База данных защищена авторским правом ©infoeto.ru 2022
обратиться к администрации
Как написать курсовую работу | Как написать хороший реферат
    Главная страница