Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
387.doc
Скачиваний:
11
Добавлен:
30.04.2022
Размер:
3.51 Mб
Скачать

Контрольная работа № 5 обработка символов и строк

Цель работы: приобретение навыков обработки символов, строк, массивов символов.

Теоретические сведения

Переменная типа string – это массив переменных типа char, доступных в режиме «только чтение». Получить доступ к отдельным символам можно так

string myString = "Строка";

char myChar = myString[0];

Для получения массива, доступного для записи, пользуются методом ToCharArray()

string myString = "Строка";

char[] myChars = myString.ToCharArray();

// также можно использовать оператор foreach

foreach( char c in myString)

{

Console.WriteLine("{0}", c);

}

string - это ссылочный тип, и в результате присваивания создается ссылка на константную строку, хранимую в «куче».

С одной и той же строковой константой в «куче» может быть связано несколько переменных строкового типа. Но эти переменные не являются разными именами одного объекта.

Строковые константы в «куче» не изменяются, поэтому, когда одна из переменных получает новое значение, она связывается с новым константным объектом в «куче». Это означает, что семантика присваивания строк аналогична семантике значимого присваивания.

Операции сравнения строк сравнивают их значения, а не ссылки. Эти операции выполняются как над значимыми типами.

Бинарная операция "+" сцепляет две строки, приписывая вторую строку к хвосту первой.

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

Каждый символ строки имеет тип char, доступный только для чтения, но не для записи.

Пример, в котором над строками выполняются данные операции:

static void TestOpers()

{

//операции над строками

string s1 ="ABC", s2 ="CDE";

string s3 = s1+s2;

bool b1 = (s1==s2);

char ch1 = s1[0], ch2=s2[0];

Console.WriteLine("s1={0}, s2={1}, b1={2}," +

"ch1={3}, ch2={4}", s1,s2,b1,ch1,ch2);

s2 = s1;

b1 = (s1!=s2);

ch2 = s2[0];

Console.WriteLine("s1={0}, s2={1}, b1={2}," +

"ch1={3}, ch2={4}", s1,s2,b1,ch1,ch2);

//Неизменяемые значения

s1= "Zenon";

// s1[0]='L'; приведет к ошибке

}

Рис. 24. Операции со строками

В языке C# указатели допускаются в блоках, отмеченных как небезопасные. В таких блоках можно объявить переменную типа char*, но программа, такая же изящная, как в С++, не получится.

Рассмотрим базовый класс для символов. Тип char, как и другие типы C#, является классом. Этот класс наследует свойства и методы класса Object и имеет собственные методы.

Символьный класс Char, основанный на классе System.Char, использует 2 байта для кодирования символа (таблица Unicode).

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

static void TestChar()

{

char ch1='A', ch2 ='\x5A', ch3='\u0058';

char ch = new Char();

int code; string s;

ch = ch1;

//преобразование символьного и int типов

code = ch; ch1=(char) (code +1);

//преобразование символьного типа в строку

//s = ch; конечно, недопустимо

s = ch1.ToString()+ch2.ToString()+ch3.ToString();

Console.WriteLine("s= {0}, ch= {1}, code = {2}", s, ch, code);

}

Три символьные переменные инициализированы константами, значения которых заданы тремя разными способами. Переменная ch объявляется в объектном стиле, используя new и вызов конструктора класса.

Явные или неявные преобразования между классами Char и String отсутствуют, но есть метод ToString() для перевода символа в строку.

Преобразование целочисленных типов в тип char следует задать явно.

Функция TestChar() формирует строку s путем сцепления трех символов, преобразованных в строки. Значение s равно «BZX», при этом ch=А, а ее код - code = 65.

Примеры преобразования символа в его код и обратно:

static int SayCode(char sym)

{ return (sym); }

static char SaySym(object code)

{ return ((char)((int)code)); }

static void Main(string[] args)

{

char ch1 = 'A';

Console.WriteLine("ch1={0}, Unicode({1})={2}",

ch1, SaySym(SayCode(ch1)), SayCode(ch1));

}

В первой функции приведение к целому типу выполняется неявно.

Во второй - преобразование явное. Ее формальный параметр имеет тип object, за счет чего она вызывается с параметром, заданным любым целочисленным типом. Но позже придется выполнить явные преобразования.

Статические методы и свойства класса Char представлены в табл. 7. Большинство статических методов перегружены. Они могут применяться как к отдельному символу, так и к строке, для которой указывается номер символа. Основную группу составляют методы Is, полезные при разборе строки. Примеры методов:

static void TestCharMethods()

{

Console.WriteLine("Статические методы класса char:");

char ch='a', ch1='1', lim =';', chc='\xA';

double d1, d2;

d1=char.GetNumericValue(ch); d2=char.GetNumericValue(ch1);

Console.WriteLine("Метод GetNumericValue:");

Console.WriteLine("sym 'a' - value {0}", d1);

Console.WriteLine("sym '1' - value {0}", d2);

System.Globalization.UnicodeCategory cat1, cat2;

cat1 =char.GetUnicodeCategory(ch1);

cat2 =char.GetUnicodeCategory(lim);

Console.WriteLine("Метод GetUnicodeCategory:");

Console.WriteLine("sym '1' - category {0}", cat1);

Console.WriteLine("sym ';' - category {0}", cat2);

Console.WriteLine("Метод IsControl:");

Console.WriteLine("sym '\xA' - IsControl - {0}", char.IsControl(chc));

Console.WriteLine("sym ';' - IsControl - {0}", char.IsControl(lim));

Таблица 7

Метод

Описание

GetNumericValue

Возвращает численное значение символа, если он является цифрой, и (-1) в противном случае

GetUnicodeCategory

Все символы разделены на категории. Метод возвращает Unicode категорию символа

IsControl

Возвращает true, если символ является управляющим

IsDigit

Возвращает true, если символ является десятичной цифрой

IsLetter

Возвращает true, если символ является буквой

IsLetterOrDigit

Возвращает true, если символ является буквой или цифрой

IsLower

Возвращает true, если символ задан в нижнем регистре

IsNumber

Возвращает true, если символ является числом (десятичной или шестнадцатиричной цифрой)

IsPunctuation

Возвращает true, если символ является знаком препинания

IsSeparator

Возвращает true, если символ является разделителем

IsSurrogate

Некоторые символы Unicode с кодом в интервале [0x1000, 0x10FFF] представляются двумя 16-битными "суррогатными" символами. Метод возвращает true, если символ является суррогатным

IsUpper

Возвращает true, если символ задан в верхнем регистре

IsWhiteSpace

Возвращает true, если символ является "белым пробелом". К белым пробелам, помимо пробела, относятся и другие символы, например, символ конца строки и символ перевода каретки

Parse

Преобразует строку в символ. Естественно, строка должна состоять из одного символа, иначе возникнет ошибка

ToLower

Приводит символ к нижнему регистру

ToUpper

Приводит символ к верхнему регистру

MaxValue, MinValue

Свойства, возвращающие символы с максимальным и минимальным кодом. Возвращаемые символы не имеют видимого образа

Console.WriteLine("Метод IsSeparator:");

Console.WriteLine("sym ' ' - IsSeparator - {0}", char.IsSeparator(' '));

Console.WriteLine("sym ';' - IsSeparator - {0}", char.IsSeparator(lim));

Console.WriteLine("Метод IsSurrogate:");

Console.WriteLine("sym '\u10FF' - IsSurrogate - {0}", char.IsSurrogate('\u10FF'));

Console.WriteLine("sym '\\' - IsSurrogate - {0}", char.IsSurrogate('\\'));

string str = "\U00010F00";

//Символы Unicode в интервале [0x10000,0x10FFF]

//представляются двумя 16-битными суррогатными символами

Console.WriteLine("str = {0}, str[0] = {1}", str, str[0]);

Console.WriteLine("str[0] IsSurrogate - {0}", сhar.IsSurrogate(str, 0));

Console.WriteLine("Метод IsWhiteSpace:");

str ="пробелы, пробелы!" + "\xD" + "\xA" + "Всюду пробелы!";

Console.WriteLine("sym '\xD ' - IsWhiteSpace - {0}", char.IsWhiteSpace('\xD')); Console.WriteLine("str: {0}", str);

Console.WriteLine("и ее пробелы - символ 8 {0},символ 17 {1}",

char.IsWhiteSpace(str,8), char.IsWhiteSpace(str,17));

Console.WriteLine("Метод Parse:");

str="A"; ch = char.Parse(str);

Console.WriteLine("str:{0} char: {1}",str, ch);

Console.WriteLine("Минимальное и максимальное значение:{0}, {1}", char.MinValue.ToString(), char.MaxValue.ToString());

Console.WriteLine("Их коды: {0}, {1}", SayCode(char.MinValue), SayCode(char.MaxValue)); }

Рис. 25. Операции со строками

Кроме статических методов, у класса Char есть и динамические. Большинство из них - это методы родительского класса Object, унаследованные и переопределенные в классе Char.

Метод CompareTo() проводит сравнение символов. Он отличается от метода Equal() тем, что для несовпадающих символов выдает «расстояние» между символами в соответствии с их упорядоченностью в кодировке Unicode.

static void testCompareChars()

{

char ch1, ch2;

int dif;

Console.WriteLine("Метод CompareTo");

ch1='A'; ch2= 'Z';

dif = ch1.CompareTo(ch2);

Console.WriteLine("Расстояние между символами {0}, {1} = {2}", ch1, ch2, dif);

ch1='а'; ch2= 'А';

dif = ch1.CompareTo(ch2);

Console.WriteLine("Расстояние между символами {0}, {1} = {2}", ch1, ch2, dif);

ch1='Я'; ch2= 'А';

dif = ch1.CompareTo(ch2);

Console.WriteLine("Расстояние между символами {0}, {1} = {2}", ch1, ch2, dif);

ch1='A'; ch2= 'A';

dif = ch1.CompareTo(ch2);

Console.WriteLine("Расстояние между символами {0}, {1} = {2}", ch1, ch2, dif);

ch1='А'; ch2= 'A';

dif = ch1.CompareTo(ch2);

Console.WriteLine("Расстояние между символами {0}, {1} = {2}", ch1, ch2, dif);

ch1='Ё'; ch2= 'А';

dif = ch1.CompareTo(ch2);

Console.WriteLine("Расстояние между символами {0}, {1} = {2}", ch1, ch2, dif);

}

Рис. 26. Операции с символами

Строчные буквы в кодировке непосредственно следуют за прописными буквами. Расстояние между алфавитами в кодировке довольно большое - русская буква А на 975 символов правее в кодировке, чем соответствующая буква в латинском алфавите.

Класс Char[] – массив символов, является наследником не только класса Object, но и класса Array, и, следовательно, обладает всеми методами родительских классов.

Например, метод Cop()y дает возможность выделять и заменять подстроку в строке. Методы IndexOf(), LastIndexOf() позволяют определить индексы первого и последнего вхождения в строку некоторого символа. Их нельзя использовать для операции нахождения индекса вхождения подстроки в строку. При необходимости можно написать такую функцию:

int IndexOfStr( char[]s1, char[] s2)

{

//возвращает индекс первого вхождения подстроки s2 в строку s1

int i =0, j=0, n=s1.Length-s2.Length;

bool found = false;

while( (i<=n) && !found)

{

j = Array.IndexOf(s1,s2[0],i);

if (j <= n)

{

found=true; int k = 0;

while ((k < s2.Length)&& found)

{

found =char.Equals(s1[k+j],s2[k]); k++;

}

}

i=j+1;

}

if(found) return(j); else return(-1);

}

Метод IndexOf() класса Array ищет начало совпадения строк, после чего проверяется совпадение остальных символов.

Строки происходят от базового класса – System.String.

Он обеспечивает множество методов, выполняющих черновую работу, табл. 8.

Метод Format(), как и большинство методов, является перегруженным и может вызываться с разным числом параметров. Первый необязательный параметр метода задает провайдера, определяющего национальные особенности, которые используются в процессе форматирования. Это должен быть объект, реализующий интерфейс System.IFormatProvider. Если этот параметр не задан, то используется культура, заданная по умолчанию.

Примеры:

public static string Format(string, object);

public static string Format(IFormatProvider, string, params object[]);

Параметр типа string задает форматируемую строку. Заданная строка содержит 1 или несколько форматов, они распознаются за счет окружающих формат фигурных скобок. Число форматов, вставленных в строку, определяет и число объектов, передаваемых при вызове метода.

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

Таблица 8

Член класса

Назначение

Length

Свойство возвращает длину строки

Empty

Возвращается пустая строка. Свойство со статусом readonly

Concat()

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

Compare()

Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. При этом можно учитывать или не учитывать регистр, особенности национального форматирования дат, чисел

CompareOrdinal()

Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. Сравниваются коды символов

CompareTo()

Сравнивает 2 строки

Copy()

Статический метод создает новую копию существующей строки

Format()

Используется для форматирования строки с использованием других примитивов (числовых данных, других строк) и подстановочных выражений вида {0}

Insert()

Вставляет строку внутрь существующей

PadLft()

PadRight()

Методы позволяют заполнить строку указанными символами

Remove()

Replace()

Методы создают копию строки с внесенными изменениями (удаленными или замененными символами)

ToUpper() ToLower()

Методы дают копии строки, в которой все символы станут строчными или прописными

Trim()

TrimStart()

TrimEnd()

Убирает пробелы с двух сторон строки,

с начала строки и в конце строки

Split()

Выделяет подстроки, ограниченные 1 или несколькими заданными символами, а затем переносит эти подстроки в массив string

Intern(),

IsIntern()

Отыскивается и возвращается ссылка на строку, если таковая уже хранится во внутреннем пуле данных. Если же строки нет, то первый из методов добавляет строку во внутренний пул, второй - возвращает null. Методы применяются обычно тогда, когда строка создается с использованием построителя строк - класса StringBuilder

Join

Конкатенация массива строк в единую строку. При конкатенации между элементами массива вставляются разделители. Операция, заданная методом Join, является обратной к операции, заданной методом Split.

Объекты класса String объявляются с явной или отложенной инициализацией, с явным или неявным вызовом конструктора класса.

Чаще всего, при объявлении строковой переменной конструктор явно не вызывается, а инициализация задается строковой константой. Но у класса String много конструкторов, позволяющих строить строку из:

- символа, повторенного заданное число раз;

- массива символов char[];

- части массива символов.

Примеры объявления строк:

public void TestDeclStrings()

{

//конструкторы

string world = "Мир";

//string s1 = new string("s1");

//string s2 = new string();

string sssss = new string('s',5);

char[] yes = "Yes".ToCharArray();

string stryes = new string(yes);

string strye = new string(yes,0,2);

Console.WriteLine("world = {0}; sssss={1}; stryes={2};"+" strye= {3}", world, sssss, stryes, strye);

}

Объект world создан без явного вызова конструктора, а объекты sssss, stryes, strye созданы разными конструкторами.

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

При использовании операций == и != происходит сравнение значений строковых объектов, а не адресов этих объектов в оперативной памяти.

Операция сложения + в С# перегружена так, что при применении к строкам она вызывает метод Concat().

Пример использования членов класса System.String:

System.String strObj = "Это 1-я строка";

string s="Тест";

if (s == strObj)

Console.WriteLine("Одинаковые строки");

else

Console.WriteLine("Разные строки");

string newString = s+strObj;

Console.WriteLine("s + strObj = {0}", newString);

for (int i=0; i<s.Length; i++)

Console.WriteLine("{0}-й символ {1} ", i, s[i]);

Рис. 27. Сравнение строк

Ни один из методов класса String не меняет значения существующих объектов.

Аналогично, при работе со строкой как с массивом, разрешено только чтение отдельных символов, но не их замена.

//Неизменяемые значения

s1= "можно"; ch1 = s1[0];

// s1[0]='L'; ошибка

C# предлагает напрямую, без создания лишних копий, изменять строки. Это средство – класс StringBuilder, определенный в пространстве System.Text.

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

using System;

using System.Text; // здесь описан класс StringBuilder

namespace ConsoleApplication3

{

class Class1

{

static void Main(string[] args)

{

StringBuilder myBuf = new StringBuilder("Я - буфер");

myBuf.Append(" и меня можно увеличить...");

Console.WriteLine(myBuf);

} }

}

Рис. 28. Строка StringBuilder

В классе StringBuilder можно выполнять непосредственно со строками и другие операции, например, удалять или заменять символы. После обработки такой строки часто бывает удобно содержимое объекта StringBuilder перевести в обычную строку типа string.

using System;

using System.Text; // здесь описан класс StringBuilder

namespace ConsoleApplication3

{

class Class1

{

static void Main(string[] args)

{

StringBuilder myBuf = new StringBuilder("Я - буфер");

myBuf.Append(" и меня можно увеличить...");

Console.WriteLine(myBuf);

myBuf.Append(" и еще увеличить");

Console.WriteLine(myBuf);

string finalString = myBuf.ToString().ToUpper(); //в верх. регистр

Console.WriteLine(finalString);

}

} }

Рис. 29. Пример работы со строкой типа StringBuilder

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]