Интернет Университет информационных технологий Твой путь к знаниям
  Искать!
Курсы | Обучение | Школа | Магазин | Общение | Новости | Помощь

поддержка курса Программирование на языке С#: разработка консольных приложений
информация [+] Авторы: Е.В. Кудрина, М.В. Огнева, М.С. Портенко


 
 
 
Дополнительные материалы:
 
 
9. Лекция: Символы и строки
Страницы: 1 | 2 | 3 | 4 | » для печати и PDA
Если Вы заметили ошибку - сообщите нам или выделите ее и нажмите Ctrl+Enter
Лекция рассматривает символы и строки: типы данных char, string. Также рассмотрены изменяемые строки.

Обработка текстовой информации является одной из самых распространенных задач современного программировании. С# предоставляет для ее решения широкий набор средств: символы char, неизменяемые строки string, изменяемые строки StringBuider и регулярные выражения Regex. В данном разделе мы рассмотрим работу с символами, неизменяемыми и изменяемыми строками.

Символы char

Символьный тип char предназначен для хранения символа в кодировке Unicode. Символьный тип относится к встроенным типам данных С# и соответствует стандартному классу Сhar библиотеки .Net из пространства имен System. В этом классе определены статические методы, позволяющие задавать вид и категорию символа, а также преобразовывать символ в верхний или нижний регистр, в число. Рассмотрим основные методы:

Метод Описание
GetNumericValueВозвращает числовое значение символа, если он является цифрой, и -1 в противном случае.
GetUnicodeCategoryВозвращает категорию Unicode-символа. В Unicode символы разделены на категории, например цифры ( DecimalDigitNumber ), римские цифры ( 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Преобразует символ в верхний регистр

В следующем примере рассмотрим применение данных методов:

static void Main()
{
 try
 {
  char b = 'B', c = '\x64', d = '\uffff';
  Console.WriteLine("{0}, {1}, {2}", b, c, d);
  Console.WriteLine("{0}, {1}, {2}", char.ToLower(b), char.ToUpper(c), char.GetNumericValue(d));
  char a;
  do	//цикл выполнятеся до тех пор, пока не ввели символ e
  {
   Console.WriteLine("Введите символ: ");
   a = char.Parse(Console.ReadLine());
   Console.WriteLine("Введен символ {0}, его код  {1}, его категория {2}", a,       
                      (int)a, char.GetUnicodeCategory(a));
   if (char.IsLetter(a)) Console.WriteLine("Буква");
   if (char.IsUpper(a)) Console.WriteLine("Верхний регистр");
   if (char.IsLower(a)) Console.WriteLine("Нижний регистр");
   if (char.IsControl(a)) Console.WriteLine("Управляющий символ");
   if (char.IsNumber(a)) Console.WriteLine("Число");
   if (char.IsPunctuation(a)) Console.WriteLine("Разделитель");
  } while (a != 'e');
 }
 catch
 {
  Console.WriteLine("Возникло исключение");
 }
}

Используя символьный тип можно оргранизовать массив символов и работать с ним на основе базового класса Array:

static void Main()
{
 char[] a ={ 'm', 'a', 'Х',  'i', 'M', 'u', 'S' , '!', '!', '!' };
 char [] b="кол около колокола".ToCharArray(); //преобразование строки в массив символов
 PrintArray("Исходный массив а:", a);
 for (int x=0;x<a.Length; x++)
 if (char.IsLower(a[x])) a[x]=char.ToUpper(a[x]);
 PrintArray("Измененный массив а:", a);
 PrintArray("Исходный массив b:", b);
 Array.Reverse(b);
 PrintArray("Измененный массив b:", b);
}

static void PrintArray(string line, Array a)
{
 Console.WriteLine(line);
 foreach( object x in a) Console.Write(x);
 Console.WriteLine('\n');
}
Задание. Измените программу так, чтобы в ней подсчитывалось количество знаков пунктуации в массиве a.

Неизменяемые строки string

Тип string, предназначенный для работы со строками символов в кодировке Unicode, является встроенным типом С#. Ему соответствует базовый тип класса System.String библиотеки .Net. Каждый объект string - это неизменяемая последовательность символов Unicode, т.е. методы, предназначенные для изменения строк, возвращают измененные копии, исходные же строки остаются неизменными.

Создать строку можно несколькими способами:

  1. string s; 	// инициализация отложена
  2. string s=''кол около колокола''; 	//инициализация строковым литералом
  3. string s=@'Привет!'	//символ @ сообщает конструктору string, что строку 
    Сегодня хорошая погода!!! '' // нужно воспринимать буквально, даже если она занимает 
    //несколько строк
  4. string s=new string (' ', 20); 	//конструктор создает строку из 20 пробелов
  5. int x = 12344556;			//инициализировали целочисленную переменную
    string s = x.ToString();		//преобразовали ее к типу string
  6. char [] a={'a', 'b', 'c', 'd', 'e'};	//создали массив символов
    string v=new string (a);		// создание строки из массива символов
  7. char [] a={'a', 'b', 'c', 'd', 'e'};
    // создание строки из части массива символов, при этом:  0 
    string v=new string (a, 0, 2)	
    // показывает с какого символа, 2 - сколько символов 
    // использовать для инициализации

Класс string обладает богатым набором методов для сравнения строк, поиска в строке и других действий со строками. Рассмотрим эти методы.

Название Вид Описание
CompareСтатический методСравнение двух строк в лексикографическом (алфавитном) порядке. Разные реализации метода позволяют сравнивать строки с учетом или без учета регистра.
CompareToМетодСравнение текущего экземпляра строки с другой строкой.
ConcatСтатический методСлияние произвольного числа строк.
CopyСтатический методСоздание копии строки
EmptyСтатическое полеОткрытое статическое поле, представляющее пустую строку
FormatСтатический методФорматирование строки в соответствии с заданным форматом
IndexOf, IndexOfAny, LastIndexOf, LastIndexOfAnyЭкземплярные методыОпределение индексов первого и последнего вхождения заданной подстроки или любого символа из заданного набора в данную строку.
InsertЭкземплярный методВставка подстроки в заданную позицию
JoinСтатический методСлияние массива строк в единую строку. Между элементами массива вставляются разделители.
LengthСвойствоВозвращает длину строки
PadLeft, PadRigthЭкземплярные методыВыравнивают строки по левому или правому краю путем вставки нужного числа пробелов в начале или в конце строки.
RemoveЭкземплярный методУдаление подстроки из заданной позиции
ReplaceЭкземплярный методЗамена всех вхождений заданной подстроки или символа новыми подстрокой или символом.
SplitЭкземплярный методРазделяет строку на элементы, используя разные разделители. Результаты помещаются в массив строк.
StartWith, EndWithЭкземплярные методыВозвращают true или false в зависимости от того, начинается или заканчивается строка заданной подстрокой.
SubstringЭкземплярный методВыделение подстроки, начиная с заданной позиции
ToCharArrayЭкземплярный методПреобразует строку в массив символов
ToLower, ToUpperЭкземплярные методыПреобразование строки к нижнему или верхнему регистру
Trim, TrimStart, TrimEndЭкземплярные методыУдаление пробелов в начале и конце строки или только с одного ее конца.

Напоминаем, что вызов статических методов происходит через обращение к имени класса, например, String.Concat(str1, str2), в остальных случаях через обращение к экземплярам класса, например, str.ToLower(). На примере рассмотрим использование данных свойств и методов.

static void Main()
{
 string str1 ="Первая строка";
 string str2 = string.Copy(str1);
 string str3 = "Вторая строка";
 string str4 = "ВТОРАЯ строка";
 string strUp, strLow;
 int result, idx;
 Console.WriteLine("str1: " + str1);
 Console.WriteLine("Длина строки str1: " +str1.Length);
 
 // Создаем прописную и строчную версии строки str1.
 strLow = str1.ToLower();
 strUp = str1.ToUpper();
 Console.WriteLine("Строчная версия строки str1: " +strLow);
 Console.WriteLine("Прописная версия строки str1: " +strUp);
 Console.WriteLine();
 
 // Сравниваем строки,
 result = str1.CompareTo(str3);
 if (result == 0) Console.WriteLine("str1 и str3 равны.");
 else if (result < 0) Console.WriteLine("str1 меньше, чем str3");
 else Console.WriteLine("str1 больше, чем str3");
 Console.WriteLine();
 
 //сравниваем строки без учета регистра
 result = String.Compare(str3,str4,true);
 if (result == 0) Console.WriteLine("str3 и str4 равны без учета регистра.");
 else Console.WriteLine("str3 и str4 не равны без учета регистра.");
 Console.WriteLine();
 
 //сравниваем части строк
 result = String.Compare(str1, 4, str2, 4, 2);
 if (result == 0)  Console.WriteLine("часть str1 и str2 равны");
 else  Console.WriteLine("часть str1 и str2 не равны");
 Console.WriteLine();
 
 // Поиск строк.
 idx = str2.IndexOf("строка");
 Console.WriteLine("Индекс первого вхождения подстроки сторка: " + idx);
 idx = str2.LastIndexOf("о");
 Console.WriteLine("Индекс последнего вхождения символа о: " + idx);

 //конкатенация
 string str=String.Concat(str1, str2, str3, str4);
 Console.WriteLine(str);
 
 //удаление подстроки
 str=str.Remove(0,str1.Length);
 Console.WriteLine(str);
 
 //замена подстроки "строка" на пустую подстроку
 str=str.Replace("строка","");
 Console.WriteLine(str);
}

Очень важными методами обработки строк, являются методы разделения строки на элементы Split и слияние массива строк в единую строку Join.

static void Main()
{
 string poems = "тучки небесные вечные странники";
 char[] div = { ' '}; //создаем массив разделителей
 // Разбиваем строку на части,
 string[] parts = poems.Split(div);
 Console.WriteLine("Результат разбиения строки на части: ");
 for (int i = 0; i < parts.Length; i++)
 Console.WriteLine(parts[i]);
 // Теперь собираем эти части в одну строку, в качестве разделителя используем символ |
 string whole = String.Join(" | ", parts);
 Console.WriteLine("Результат сборки: ");
 Console.WriteLine(whole);
}
Задание. Измените программу так, чтобы слова в предложении записывались в обратном порядке.

В общем случае строка может содержать и другие разделители:

static void Main()
{
 string poems = "Тучки небесные, вечные странники...";
 char[] div = { ' ', ',', '.'}; //создаем массив разделителей
 // Разбиваем строку на части,
 string[] parts = poems.Split(div);
 Console.WriteLine("Результат разбиения строки на части: ");
 for (int i = 0; i < parts.Length; i++)
 Console.WriteLine(parts[i]);
 // Теперь собираем эти части в одну строку,
 string whole = String.Join(" | ", parts);
 Console.WriteLine("Результат сборки: ");
 Console.WriteLine(whole);
}
Задания.
  1. Объясните, почему в массиве строк parts появились пустые строки.
  2. Внесите изменения в программу так, чтобы пустых строк не было.

Рассмотрим другой пример - используя метод Split вводить двумерный массив можно не поэлементно, а построчно:

static void Main()
{
 try
 {
  int[][] MyArray;
  Console.Write("введите количество строк: ");
  int n = int.Parse(Console.ReadLine());
  MyArray = new int[n][];
  for (int i = 0; i < MyArray.Length; i++)
  {
   string line = Console.ReadLine();
   string[] mas = line.Split(' ');
   MyArray[i] = new int[mas.Length];
   for (int j = 0; j < MyArray[i].Length; j++)
   {
    MyArray[i][j] = int.Parse(mas[j]);
   }
  }
  PrintArray("исходный массив:", MyArray);
  for (int i = 0; i < MyArray.Length; i++) Array.Sort(MyArray[i]);
  PrintArray("итоговый массив", MyArray);
 }
 catch 
 {
  Console.WriteLine("возникло исключение");
 }
}
 
static void PrintArray(string a, int[][] mas)
{
 Console.WriteLine(a);
 for (int i = 0; i < mas.Length; i++)
 {
  foreach (int x in mas[i]) Console.Write("{0} ", x);
  Console.WriteLine();
 }
}

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

static void Main()
{
 try
 {
  int[][] MyArray;
  Console.Write("введите количество строк: ");
  string line= Console.ReadLine()
  int n = int.Parse(line.Trim());
  MyArray = new int[n][];
  for (int i = 0; i < MyArray.Length; i++)
  {
   line = Console.ReadLine();
   line=line.Trim();	//удалаяем пробелы в начале и конце строки 
   //удаляем линшие пробелы внутри строки 
   n = line.IndexOf("  ");
   while (n > 0)
   {
    line = line.Remove(n, 1);
    n = line.IndexOf("  ");
   }          
   string[] mas = line.Split(' ');
   MyArray[i] = new int[mas.Length];
   for (int j = 0; j < MyArray[i].Length; j++)
   {
    MyArray[i][j] = int.Parse(mas[j]);
   }
  }
  PrintArray("исходный массив:", MyArray);
  for (int i = 0; i < MyArray.Length; i++) Array.Sort(MyArray[i]);
  PrintArray("итоговый массив", MyArray);
 }
 catch 
 {
  Console.WriteLine("возникло исключение");
 }
}
 
static void PrintArray(string a, int[][] mas)
{
 Console.WriteLine(a);
 for (int i = 0; i < mas.Length; i++)
 {
  foreach (int x in mas[i]) Console.Write("{0} ", x);
  Console.WriteLine();
 }
}
Задание. Объясните, можно ли удалить внутри строки лишние пробелы, используя метод Replace. Например, следующим способом str.Replace(" ", " "), где мы пытаемся заменить подстроку состоящую из двух, на подстроку из одиного пробела.

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

string a="";
 for (int i = 1; i <= 100; i++) a +="!";
 Console.WriteLine(a);

В этом случае в памяти компьютера будет сформировано 100 различных строк вида:

!
!!
!!!
…
!!!...!!

И только последняя строка будет храниться в переменной а. Ссылки на все остальные строчки будут потеряны, но эти строки будут храниться в памяти компьютера и засорять память. Бороться с таким засорением придется сборщику мусора, что будет сказываться на производительности программы. Поэтому если нужно изменять строку, то лучше пользоваться классом StringBuilder.

Дальше »
Страницы: 1 | 2 | 3 | 4 | » для печати и PDA
 
 

Внимание! Если Вы увидите ошибку на нашем сайте, выделите её и нажмите Ctrl+Enter.
Нужна помощь?
• Забыли пароль? Вам сюда...
• Есть вопрос? Спрашивайте!
Вы можете:
• Изменить персональные данные
• Изменить параметры подписки
Интернет-магазин:
• Ваши заказы здесь
• Ваш личный счет
Курсы | Учебные программы | Учебники | Вопросы и Ответы | Форум | Новости | Помощь

Телефон: +7 (499) 253-9312, 253-9313, факс: +7 (499) 253-9310, email: info@intuit.ru
© INTUIT.ru::Интернет-Университет Информационных Технологий - дистанционное образование, 2003-2011
Проект Издательства "Открытые Системы".
Партнеры: РМ Телеком, KRAFTWAY COMPUTERS.
Rambler's Top100