- •Введение
- •Контрольная работа № 1 разработка приложений в microsoft visual studio 2008
- •Теоретические сведения Интерфейс Microsoft Visual Studio 2008
- •Создание консольного приложения
- •Построение xml-отчета по выполненному проекту
- •Создание приложения Windows Forms
- •Контрольные вопросы
- •Содержание и порядок выполнения работы
- •Контрольная работа № 2
- •Теоретические сведения Структура программы. Переменные и выражения
- •Литеральные константы
- •Операции и их старшинство
- •Операторы c#
- •If(выражение1) if(выражение2) if(выражение3) ...
- •Контрольные вопросы
- •Содержание и порядок выполнения работы
- •Примеры решения задач
- •Контрольная работа № 3 техника работы с массивами. Процедуры и функции
- •Теоретические сведения
- •Базовый класс для массивов
- •Процедуры и функции
- •Синтаксис методов
- •Формальные и фактические аргументы
- •Соответствие формальных и фактических аргументов
- •Функции с побочным эффектом
- •Функция Main()
- •Контрольные вопросы
- •Содержание и порядок выполнения работы
- •Примеры решения задач
- •Контрольная работа № 4 перечисления и структуры
- •Теоретические сведения
- •Базовый класс перечислений - System.Enum
- •Структуры
- •Контрольные вопросы
- •Содержание и порядок выполнения работы
- •Пример решения задачи
- •Контрольная работа № 5 обработка символов и строк
- •Теоретические сведения
- •Контрольные вопросы
- •Содержание и порядок выполнения работы
- •Примеры решения задачи
- •Контрольная работа № 6 проектирование классов. Составление программ с использованием ооп
- •Теоретические сведения
- •Контрольные вопросы
- •Содержание и порядок выполнения работы
- •Пример решения задачи
- •Заключение
- •Библиографический список
- •Оглавление
- •394026 Воронеж, Московский просп., 14
Контрольная работа № 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