Рекомендации по программированию СТРОКИ Цель работы: подробно изучить приемы работы со строками. Обработка текстовой информации является одной из самых распространенных задач в современном программировании, и С# предоставляет для ее решения широкий набор средств: отдельные символы, массивы символов, изменяемые и неизменяемые строки и регулярные выражения. Символы Символьный тип char предназначен для хранения символов в кодировке Unicode. Символьный тип относится к встроенным типам данных С# и соответствует стандартному классу Char библиотеки .NET из пространства имен System. В этом классе определены статические методы, позволяющие задать вид и категорию символа, а также преобразовать символ в верхний или нижний регистр и в число. Основные методы приведены в таблице 1. Таблица 1 –Основные методы класса System.Char Метод | Описание | GetNumericValue | Возвращает числовое значение символа, если он является цифрой, и -1 в противном случае | GetUnicodeCategory | Возвращает категорию Unicode-символа. Bce Unicode-символы разделены на категории, например, десятичные цифры (Decimal-DigitNumber), римские цифры (LetterNumber), разделители строк (LineSeparator), буквы в нижнем регистре (LowercaseLetter) и т. д. | IsControl | Возвращает true, если символ является управляющим | IsDigit | Возвращает true, если символ является десятичной цифрой | IsLetter | Возвращает true, если символ является буквой | IsLetterOrDigit | Возвращает true, если символ является буквой или цифрой | IsLower | Возвращает true, если символ задан в нижнем регистре | IsNumber | Возвращает true, если символ является числом (десятичным или шестнадцатеричным) | IsPunctuation | Возвращает true, если символ является знаком препинания | IsSeparator | Возвращает true, если символ является разделителем | IsUpper | Возвращает true, если символ записан в верхнем регистре | IsWhiteSpace | Возвращает true, если символ является пробельным (пробел, перевод строки и возврат каретки) | Parse | Преобразует строку в символ (строка должна состоять из одного символа) | ToLower | Преобразует символ в нижний регистр | ToUpper | Преобразует символ в верхний регистр | MaxValue, MinValue | Возвращают символы с максимальным и минимальным кодами (эти символы не имеют видимого представления) | В листинге 1 продемонстрировано использование этих методов. Листинг 1.Использование методов класса System.Char   Результат работы программы:  В операторе 1 описаны три символьных переменных. Они инициализируются символьными литералами в различных формах представления. Далее выполняются вывод и преобразование символов. В цикле 2 анализируется вводимый с клавиатуры символ. Можно вводить и управляющие символы, используя сочетание клавиши Ctrl с латинскими буквами. При вводе использован метод Parse, преобразующий строку, которая должна содержать единственный символ, в символ типа char. Поскольку вводится строка, ввод каждого символа следует завершать нажатием клавиши Enter. Цикл выполняется, пока пользователь не введет символ q. Вывод символа сопровождается его кодом в десятичном виде. Для вывода кода используется явное преобразование к целому типу. Явное преобразование из символов в строки и обратно в С# не существует, неявным же образом любой объект, в том числе и символ, может быть преобразован в строку2, например: string s = 'к' + 'о' + 'т'; // результат – строка "кот" При вводе и преобразовании могут возникать исключительные ситуации, например, если пользователь введет пустую строку. Для ≪мягкого≫ завершения программы предусмотрена обработка исключений. Массивы символов Массив символов, как и массив любого иного типа, построен на основе базового класса Array, некоторые свойства и методы которого были перечислены в таблице 1 пр.р. 5. Применение этих методов позволяет эффективно решать некоторые задачи. Простой пример приведен в листинге 2. Листинг 2.Работа с массивом символов  Результат работы программы:  Символьный массив можно инициализировать, либо непосредственно задавая его элементы (оператор 1), либо применяя метод ToCharArray класса string, который разбивает исходную строку на отдельные символы (оператор 2). Строки типа string Тип string, предназначенный для работы со строками символов в кодировке Unicode, является встроенным типом С#. Ему соответствует базовый класс System.String библиотеки .NET. Создать строку можно несколькими способами: string s; // инициализация отложена string t = "qqq"; // инициализация строковым литералом string u = new string(' ', 20); // конструктор создает строку из 20 пробелов char[] a = { '0', '0', '0' }; // массив для инициализации строки string v = new string(a); // создание из массива символов Для строк определены следующие операции: • присваивание (=); • проверка на равенство (==); • проверка на неравенство ( ! = ) ; • обращение по индексу ( [ ] ) ; • сцепление (конкатенация) строк ( + ) . Несмотря на то, что строки являются ссылочным типом данных, на равенство и неравенство проверяются не ссылки, а значения строк. Строки равны, если имеют одинаковое количество символов и совпадают посимвольно. Обращаться к отдельному элементу строки по индексу можно только для получения значения, но не для его изменения. Это связано с тем, что строки типа string относятся к так называемым неизменяемым типам данных.Методы, изменяющие содержимое строки, на самом деле создают новую копию строки. Неиспользуемые ≪старые≫ копии автоматически удаляются сборщиком мусора. В классе System.String предусмотрено множество методов, полей и свойств, позволяющих выполнять со строками практически любые действия. Основные элементы класса приведены в таблице 2. Таблица 2 – Основные элементы класса System.String Название | Вид | Описание | Compare | Статический метод | Сравнение двух строк в лексикографическом (алфавитном) порядке. Разные реализации метода позволяют сравнивать строки и подстроки с учетом и без учета регистра и особенностей национального представления дат и т. д. | CompareOrdinal | Статический метод | Сравнение двух строк по кодам символов. Разные реализации метода позволяют сравнивать строки и подстроки | CompareTo | Метод | Сравнение текущего экземпляра строки с другой строкой | Concat | Статический метод | Конкатенация строк. Метод допускает сцепление произвольного числа строк | Copy | Статический метод | Создание копии строки | Empty | Статическое поле | Пустая строка (только для чтения) | Format | Статический метод | Форматирование в соответствии с заданными спецификаторами формата | IndexOf, IndexOf Any, LastIndexOf, LastIndexOfAny | Методы | Определение индексов первого и последнего вхождения заданной подстроки или любого символа из заданного набора | Insert | Метод | Вставка подстроки в заданную позицию | Intern, IsIntern | Статические методы | Возвращает ссылку на строку, если такая уже существует. Если строки нет, Intern добавляет строку во внутренний null, IsIntern возвращает null | Join | Статический метод | Слияние массива строк в единую строку. Между элементами массива вставляются разделители | Length | Свойство | Длина строки (количество символов) | PadLeft, PadRight | Методы | Выравнивание строки по левому или правому краю путем вставки нужного числа пробелов в начале или в конце строки | Remove | Метод | Удаление подстроки из заданной позиции | Replace | Метод | Замена всех вхождений заданной подстроки или символа новыми подстрокой или символом | Продолжение таблицы 2 Название | Вид | Описание | Split | Метод | Разделяет строку на элементы, используя заданные разделители. Результаты помещаются в массив строк | StartsWith, EndsWith | Методы | Возвращает true или false в зависимости от того, начинается или заканчивается строка заданной подстрокой | Substring | Метод | Выделение подстроки, начиная с заданной позиции | ToCharArray | Метод | Преобразование строки в массив символов | ToLower, ToUpper | Методы | Преобразование символов строки к нижнему или верхнему регистру | Trim, TrimStart, TrimEnd | Методы | Удаление пробелов в начале и конце строки или только с одного ее конца (обратные по отношению к методам PadLeft и PadRight действия) | Пример применения методов приведен в листинге 3. Листинг 3.Работа со строками типа String  Результат работы программы:  В операторе 1 выполняются два последовательных вызова методов: метод Substring возвращает подстроку строки s, которая содержит символы исходной строки, начиння с третьего. Для этой подстроки вызывается метод Remove, удаляющий из нее два символа, начиная с 12-го. Результат работы метода присваивается переменной sub. Аргументом метода Split (оператор 2) является разделитель, в данном случае – символ пробела. Метод разделяет строку на отдельные слова, которые заносяться в массив строк mas. Статический метод Join (он вызывается через имя класса) объединяет элементы массива mas в одну строку, вставляя между каждой парой слов строку "!". Оператор 3 напоминает о том, как вводить строки с клавиатуры. Форматирование строк В операторе 4 из листинга 8 неявно применяется метод Format, который заменяет все вхождения параметров в фигурных скобках значениями соответствующих переменных из списка вывода. После номера параметра можно задать минимальную ширину поля вывода, а также указать спецификатор формата, который определяет форму представления выводимого значения. В общем виде параметр задается следующим образом: {n [,m[:спецификатор_формата]]} Здесь n – номер параметра. Параметры нумеруются с нуля, нулевой параметр заменяется значением первой переменной из списка вывода, первый параметр – второй переменной и т. д. Параметр m определяет минимальную ширину поля, которое отводится под выводимое значение. Если выводимому числу достаточно меньшего количества позиций, неиспользуемые позиции заполняются пробелами. Если числу требуется больше позиций, параметр игнорируется. Спецификатор формата, как явствует из его названия, определяет формат вывода значения. Например, спецификатор С (Currency) означает, что параметр должен форматироваться как валюта с учетом национальных особенностей представления, а спецификатор X (Hexadecimal) задает шестнадцатеричную форму представления выводимого значения. В операторе 5 используются так называемые пользовательские шаблоны форматирования. В них нет ничего сложного: после двоеточия задается вид выводимого значения посимвольно, причем на месте каждого символа может стоять либо #, либо 0. Если указан знак #, на этом месте будет выведена цифра числа, если она не равна нулю. Если указан 0, будет выведена любая цифра, в том числе и 0. В таблице 3 приведены примеры шаблонов и результатов вывода. Таблица 3 – Примеры применения пользовательских шаблонов форматирования Число | Шаблон | Вид | 1,243 | 00.00 | 01,24 | 1,243 | #.## | 1,24 | 0,1 | 00.00 | 00,10 | 0,1 | #.## | ,1 | Пользовательский шаблон может также содержать текст, который в общем случае заключается в апострофы. Строки типа StringBuilder Возможности, предоставляемые классом String, широки, однако требование неизменности его объектов может оказаться неудобным. В этом случае для работы со строками применяется класс StringBuilder, определенный в пространстве имен System.Text и позволяющий изменять значение своих экземпляров. При создании экземпляра обязательно использовать операцию new и конструктор, например: StringBuilder а = new StringBuilder( ); // 1 StringBuilder b = new StringBuilder( "qwerty" ); // 2 StringBuilder с = new StringBuilder( 100 ); // 3 StringBuilder d = new StringBuilder( "qwerty", 100 ); // 4 StringBuilder e = new StringBuilder( "qwerty", 1, 3, 100 ); // 5 В конструкторе класса указываются два вида параметров: инициализирующая строка или подстрока и объем памяти, отводимой под экземпляр (емкость буфера). Один или оба параметра могут отсутствовать, в этом случае используются их значения по умолчанию. Если применяется конструктор без параметров (оператор 1), создается пустая строка размера, заданного по умолчанию (16 байт). Другие виды конструкторов задают объем памяти, выделяемой строке, и/или ее начальное значение. Например, в операторе 5 объект инициализируется подстрокой длиной 3 символа, начиная с первого (подстрока "wer"). Основные элементы класса StringBuilder приведены в таблице 4. Таблица 4 – Основные элементы класса System.Text.StringBuilder Название | Вид | Описание | Append | Метод | Добавление в конец строки. Разные варианты метода позволяют добавлять в строку величины любых встроенных типов, массивы символов, строки и подстроки типа string | AppendFormat | Метод | Добавление форматированной строки в конец строки | Capacity | Свойство | Получение или установка емкости буфера. Если устанавливаемое значение меньше текущей длины строки или больше максимального, генерируется исключение ArgumentOutOfRangeException | Insert | Метод | Вставка подстроки в заданную позицию | Length | Свойство | Длина строки (количество символов) | MaxCapacity | Свойство | Максимальный размер буфера | Remove | Метод | Удаление подстроки из заданной позиции | Replace | Метод | Замена всех вхождений заданной подстроки или символа новой подстрокой или символом | ToString | Метод | Преобразование в строку типа string | Пример применения методов приведен в листинге 4. Листинг 4.Работа со строками типа StringBuilder   Результат работы программы:  Емкость буфера не соответствует количеству символов в строке и может увеличиваться в процессе работы программы как в результате прямых указаний программиста, так и вследствие выполнения методов изменения строки, если строка в результате превышает текущий размер буфера. Программист может уменшить размер буфера с помощью свойства Capacity, чтобы не занимать лишнюю память. Класс Random При отладке программ, использующих массивы, удобно иметь возможность генерировать исходные данные, заданные случайным образом. В библиотеке С# на этот случай есть класс Random, определенный в пространстве имен System. Для получения псевдослучайной последовательности чисел необходимо сначала создать экземпляр класса с помощью конструктора, например: Random a = new Random(); // 1 Random b = new Random(1); // 2 Есть два вида конструктора: конструктор без параметров (оператор 1) использует начальное значение генератора, вычисленное на основе текущего времени. В этом случае каждый раз создается уникальная последовательность. Конструктор с параметром типа int (оператор 2) задает начальное значение генератора, что обеспечивает возможность получения одинаковых последовательностей чисел. Для получения очередного значения серии пользуются методами, перечисленными в таблице 5. Таблица 5 –Основные методы класса System.Random Название | Описание | Next() | Возвращает целое положительное число во всем положительном диапазоне типа int | Next(max) | Возвращает целое положительное число в диапазоне [0, макс] | Next(min, max) | Возвращает целое положительное число в диапазоне [мин, макс] | NextBytes(buffer) | Возвращает массив чисел в диапазоне [0, 255] | NextDouble() | Возвращает вещественное положительное число в диапазоне [0, 1) | Пример применения методов приведен в листинге 5. Листинг 5.Работа с генератором псевдослучайных чисел   Результат работы программы:  Рекомендации по программированию При работе со строками необходимо учитывать, что в С# строка типа string является неизменяемым типом данных, то есть любая операция изменения строки на самом деле возвращает ее копию. Для изменения строк используется тип OnngBuilder. Прежде чем описывать в программе какое-либо действие со строками, полезно посмотреть, нет ли в списке элементов используемого класса подходящих методов и свойств. Для эффективного поиска и преобразования текста в соответствии с заданными шаблонами используются так называемые регулярные выражения. Индивидуальные задания: Вариант 1 Написать программу, которая считывает из текстового файла три предложения и выводит их в обратном порядке. Вариант 2 Написать программу, которая считывает текст из файла и выводит на экран только предложения, содержащие введенное с клавиатуры слово. Вариант 3 Написать программу, которая считывает текст из файла и выводит на экран только строки, содержащие двузначные числа. Вариант 4 Написать программу, которая считывает английский текст из файла и выводит на экран слова, начинающиеся с гласных букв. Вариант 5 Написать программу, которая считывает текст из файла и выводит его на экран, меняя местами каждые два соседних слова. Вариант 6 Написать программу, которая считывает текст из файла и выводит на экран только предложения, не содержащие запятых. Вариант 7 Написать программу, которая считывает текст из файла и определяет, сколько в нем слов, состоящих не более чем из четырех букв. Вариант 8 Написать программу, которая считывает текст из файла и выводит на экран только цитаты, то есть предложения, заключенные в кавычки. Вариант 9 Написать программу, которая считывает текст из файла и выводит на экран только предложения, состоящие из заданного количества слов. Вариант 10 Написать программу, которая считывает английский текст из файла и выводит на экран слова текста, начинающиеся и оканчивающиеся на гласные буквы. Вариант 11 Написать программу, которая считывает текст из файла и выводит на экран только строки, не содержащие двузначных чисел. Вариант 12 Написать программу, которая считывает текст из файла и выводит на экран только предложения, начинающиеся с тире, перед которым могут находиться только пробельные символы. Вариант 13 Написать программу, которая считывает английский текст из файла и выводит его на экран, заменив прописной каждую первую букву слов, начинающихся с гласной буквы. Вариант 14 Написать программу, которая считывает текст из файла и выводит его на экран, заменив цифры от 0 до 9 словами ≪ноль≫, ≪один≫, ≪девять≫, начиная каждое предложение с новой строки. Вариант 15 Написать программу, которая считывает текст из файла, находит самое длинное слово и определяет, сколько раз оно встретилось в тексте. Вариант 16 Написать программу, которая считывает текст из файла и выводит на экран сначала вопросительные, а затем восклицательные предложения. Вариант 17 Написать программу, которая считывает текст из файла и выводит его на экран, после каждого предложения добавляя, сколько раз встретилось в нем введенное с клавиатуры слово. Вариант 18 Написать программу, которая считывает текст из файла и выводит на экран все его предложения в обратном порядке. Вариант 19 Написать программу, которая считывает текст из файла и выводит на экран сначала предложения, начинающиеся с однобуквенных слов, а затем все остальные. Вариант 20 Написать программу, которая считывает текст из файла и выводит на экран предложения, содержащие максимальное количество знаков пунктуации. |