В предыдущей лекции мы говорили о символьном типе char и строках постоянной длины, задаваемых массивом символов. Основным типом при работе со строками является тип
Объекты String достаточно много конструкторов. Они позволяют сконструировать строку из:
char[] ;Некоторым конструкторам в качестве параметра инициализации можно передать строку, заданную типом 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 созданы разными конструкторами
Заметьте, не допускается явный вызов конструктора по умолчанию - конструктора без параметров. Нет также конструктора, которому в качестве аргумента можно передать обычную строковую константу. Соответствующие операторы в тексте закомментированы.
Над строками определены следующие операции:
= );== ) и ( != );+ );[] ).Начну с присваивания, имеющего важную особенность. Поскольку string - это ссылочный тип, то в результате присваивания создается ссылка на константную строку, хранимую в "куче". С одной и той же строковой константой в "куче" может быть связано несколько переменных строкового типа. Но эти переменные не являются псевдонимами - разными именами одного и того же объекта. Дело в том, что строковые константы в "куче" не изменяются (о неизменяемости строкового типа будем далее говорить подробно), поэтому когда одна из переменных получает новое значение, она связывается с новым константным объектом в "куче". Остальные переменные сохраняют свои связи. Для программиста это означает, что семантика присваивания строк аналогична семантике значимого присваивания.
В отличие от других ссылочных типов, операции, проверяющие эквивалентность, сравнивают значения строк, а не ссылки. Эти операции выполняются как над значимыми типами.
Бинарная операция " + " сцепляет две строки, приписывая вторую строку к хвосту первой.
Возможность взятия индекса при работе со строками отражает тот приятный факт, что строку можно рассматривать как массив и получать без труда каждый ее символ. Каждый символ строки имеет тип char, доступный только для чтения, но не для записи.
Вот пример, в котором над строками выполняются данные операции:
public 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';
}
Без констант не обойтись. В C# существуют два вида строковых констант:
@.В обычных константах некоторые символы интерпретируются особым образом. Связано это прежде всего с тем, что необходимо уметь задавать в строке непечатаемые символы, такие, как, например, символ табуляции. Возникает необходимость задавать символы их кодом - в виде escape-последовательностей. Для всех этих целей используется комбинация символов, начинающаяся символом " \ " - обратная косая черта. Так, пары символов: " \n ", " \t ", " \\ ", " \ "" задают соответственно символ перехода на новую строку, символ табуляции, сам символ обратной косой черты, символ кавычки, вставляемый в строку, но не сигнализирующий о ее окончании. Комбинация " \xNNNN " задает символ, определяемый шестнадцатеричным кодом NNNN. Хотя такое решение возникающих проблем совершенно естественно, иногда возникают неудобства: например, при задании констант, определяющих путь к файлу, приходится каждый раз удваивать символ обратной косой черты. Это одна из причин, по которой появились
В
//Два вида констант
s1= "\x50";
s2=@"\x50""";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1 = "c:\\c#book\\ch5\\chapter5.doc";
s2 = @"c:\c#book\ch5\chapter5.doc";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1= "\"A\"";
s2=@"""A""";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
Взгляните на результаты работы приведенных фрагментов кода, полученные при вызове процедур TestDeclStrings и TestOpers.
(рис 14.1) Объявления, константы и операции над объектами string
В языке C# существует понятие
К таким
//Неизменяемые значения s1= "Zenon"; ch1 = s1[0]; //s1[0]='L';
| Метод | Описание |
|---|---|
Empty |
Возвращается пустая строка. Свойство со статусом read only |
Compare |
Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. При этом можно учитывать или не учитывать регистр, особенности национального форматирования дат, чисел и т.д. |
CompareOrdinal |
Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. Сравниваются коды символов |
Concat |
Конкатенация строк. Метод перегружен, допускает сцепление произвольного числа строк |
Copy |
Создается копия строки |
| Выполняет форматирование в соответствии с заданными спецификациями |
|
Intern, IsIntern |
Отыскивается и возвращается ссылка на строку, если таковая уже хранится во внутреннем пуле данных. Если же строки нет, то первый из методов добавляет строку во внутренний пул, второй - возвращает null. Методы применяются обычно тогда, когда строка создается с использованием построителя строк - класса |
| Конкатенация массива строк в единую строку. При конкатенации между элементами массива вставляются разделители. Операция, заданная методом |
Console.WriteLine("s1={0}, s2={1}", s1,s2);
Здесь строка, задающая первый аргумент метода, помимо обычных символов, содержит
Давайте рассмотрим общий синтаксис как самого System.IFormatProvider. Если этот параметр не задан, то используется культура, заданная по умолчанию. Вот примеры двух реализаций этого метода:
public static string Format(string, object); public static string Format(IFormatProvider, string, params object[]);
Параметр типа string задает форматируемую строку. Заданная строка содержит один или несколько
Общий синтаксис, специфицирующий
{N [,M [:<коды_форматирования>]]}
Обязательный параметр N задает индекс объекта, заменяющего M, если он задан, определяет минимальную ширину поля, которое отводится строке, вставляемой вместо C ( Currency ) говорит о том, что параметр должен форматироваться как валюта с учетом национальных особенностей представления. Код P ( Percent ) задает форматирование в виде процентов с точностью до сотой доли.
Все становится ясным, когда появляются соответствующие примеры. Вот они:
public void TestFormat()
{
//метод Format
int x=77;
string s= string.Format("x={0}",x);
Console.WriteLine(s + "\tx={0}",x);
s= string.Format("Итого:{0,10} рублей",x);
Console.WriteLine(s);
s= string.Format("Итого:{0,6:######} рублей",x);
Console.WriteLine(s);
s= string.Format("Итого:{0:P} ",0.77);
Console.WriteLine(s);
s= string.Format("Итого:{0,4:C} ",77.77);
Console.WriteLine(s);
//Национальные особенности
System.Globalization.CultureInfo ci =
new System.Globalization.CultureInfo("en-US");
s= string.Format(ci,"Итого:{0,4:C} ",77.77);
Console.WriteLine(s);
}//TestFormat
Приведу некоторые комментарии к этой процедуре. Вначале демонстрируется, что и явный, и неявный вызовы CultureInfo, инициализированный так, чтобы он задавал особенности CultureInfo наследует интерфейс IFormatProvider. Российские национальные особенности форматирования установлены по умолчанию. При необходимости их можно установить таким же образом, как это сделано для США, задав соответственно константу " ru-RU ". Результаты работы метода показаны на рис. 14.2.
(рис 14.2) Результаты работы метода Format
Методы
Заданный строкой текст зачастую представляет собой совокупность структурированных элементов - абзацев, предложений, слов, скобочных выражений и т.д. При работе с таким текстом необходимо разделить его на элементы, пользуясь специальными разделителями элементов, - это могут быть пробелы, скобки, знаки препинания. Практически подобные задачи возникают постоянно при работе со структурированными текстами. Методы
public string[] Split(params char[])
На вход методу string, вызвавший метод, разделяется на подстроки, ограниченные этими разделителями. Из этих подстрок создается массив, возвращаемый в качестве результата метода. Другая реализация позволяет ограничить число элементов возвращаемого массива.
Синтаксис
public static string Join(string delimiters, string[] items )
В качестве результата метод возвращает строку, полученную конкатенацией элементов массива items, между которыми вставляется строка разделителей delimiters. Как правило, строка delimiters состоит из одного символа, который и разделяет в результирующей строке элементы массива items ; но в отдельных случаях ограничителем может быть строка из нескольких символов.
Рассмотрим примеры применения этих методов. В первом из них строка представляет сложноподчиненное предложение, которое разбивается на простые предложения. Во втором предложение разделяется на слова. Затем производится обратная сборка разобранного текста. Вот код соответствующей процедуры:
public void TestSplitAndJoin()
{
string txt = "А это пшеница, которая в темном чулане
хранится," +" в доме, который построил Джек!";
Console.WriteLine("txt={0}", txt);
Console.WriteLine("Разделение текста на простые предложения:");
string[] SimpleSentences, Words;
//размерность массивов SimpleSentences и Words
//устанавливается автоматически в соответствии с
//размерностью массива, возвращаемого методом Split
SimpleSentences = txt.Split(',');
for(int i=0;i< SimpleSentences.Length; i++)
Console.WriteLine("SimpleSentences[{0}]= {1}",
i, SimpleSentences[i]);
string txtjoin = string.Join(",",SimpleSentences);
Console.WriteLine("txtjoin={0}", txtjoin);
Words = txt.Split(',', ' ');
for(int i=0;i< Words.Length; i++)
Console.WriteLine("Words[{0}]= {1}",i, Words[i]);
txtjoin = string.Join(" ",Words);
Console.WriteLine("txtjoin={0}", txtjoin);
}//TestSplitAndJoin
Результаты выполнения этой процедуры показаны на рис. 14.3.
(рис 14.3) Разбор и сборка строки текстаОбратите внимание, что методы
Если при разборе предложения на слова использовать в качестве разделителя только пробел, то пустые слова не появятся, но запятая будет являться частью некоторых слов.
Как всегда, есть несколько способов справиться с проблемой. Один из них состоит в том, чтобы написать собственную реализацию этих функций, другой - в корректировке полученных результатов, третий - в использовании более мощного аппарата регулярных выражений, и о нем мы поговорим чуть позже.
Операции, разрешенные над строками в C#, разнообразны. Методы этого класса позволяют выполнять вставку, удаление, замену, поиск вхождения подстроки в строку. Object, частично их переопределяя. IComparable, , IConvertible, IEnumerable. Три из них уже рассматривались при описании классов-массивов.
Рассмотрим наиболее характерные методы при работе со строками.
Сводка методов, приведенная в таблице 14.2, дает достаточно полную картину широких возможностей, имеющихся при работе со строками в C#. Следует помнить, что Replace, Insert и другие методы представляют собой функции, возвращающие новую строку в качестве результата и не изменяющие строку, вызвавшую метод.
| Метод | Описание |
|---|---|
Insert |
Вставляет подстроку в заданную позицию |
Remove |
Удаляет подстроку в заданной позиции |
Replace |
Заменяет подстроку в заданной позиции на новую подстроку |
Substring |
Выделяет подстроку в заданной позиции |
IndexOf, IndexOfAny, LastIndexOf, LastIndexOfAny |
Определяются индексы первого и последнего вхождения заданной подстроки или любого символа из заданного набора |
StartsWith, EndsWith |
Возвращается true или false, в зависимости от того, начинается или заканчивается строка заданной подстрокой |
PadLeft, PadRight |
Выполняет набивку нужным числом пробелов в начале и в конце строки |
Trim, TrimStart, TrimEnd |
Обратные операции к методам Pad. Удаляются пробелы в начале и в конце строки, или только с одного ее конца |
ToCharArray |
Преобразование строки в массив символов |
System.Text. Рассмотрим класс
Объекты этого класса объявляются с явным вызовом конструктора класса. Поскольку специальных констант этого типа не существует, то вызов конструктора для инициализации объекта просто необходим. Конструктор класса перегружен, и наряду с конструктором без параметров, создающим пустую строку, имеется набор конструкторов, которым можно передать две группы параметров. Первая группа позволяет задать строку или подстроку, значением которой будет инициализироваться создаваемый объект класса
public StringBuilder (string str, int cap). Параметр str задает строку инициализации, cap - public StringBuilder (int curcap, int maxcap). Параметры curcap и maxcap задают начальную и максимальную public StringBuilder (string str, int start, int len, int cap). Параметры str, start, len задают строку инициализации, cap - Над строками этого класса определены практически те же операции с той же семантикой, что и над строками
= );== ) и ( != );[] ).Операция конкатенации ( + ) не определена над строками класса Append, дописывающий новую строку в хвост уже существующей.
Со строкой этого класса можно работать как с массивом, но, в отличие от
public void TestStringBuilder()
{
//Строки класса StringBuilder
//операции над строками
StringBuilder s1 =new StringBuilder("ABC"),
s2 =new StringBuilder("CDE");
StringBuilder s3 = new StringBuilder();
//s3= s1+s2;
s3= s1.Append(s2);
bool b1 = (s1==s3);
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);
StringBuilder s = new StringBuilder("Zenon");
s[0]='L';
Console.WriteLine(s);
}//TestStringBuilder
Этот пример демонстрирует возможность выполнения над строками класса Append. Появляется новая возможность - изменять отдельные символы строки. (Для того чтобы имя класса using System.Text, ссылающееся на соответствующее пространство имен.)
У класса
public StringBuilder Append (<объект>). К строке, вызвавшей метод, присоединяется строка, полученная из объекта, который передан методу в качестве параметра. Метод перегружен и может принимать на входе объекты всех простых типов, начиная от char и bool до string и long. Поскольку объекты всех этих типов имеют метод ToString, всегда есть возможность преобразовать объект в строку, которая и присоединяется к исходной строке. В качестве результата возвращается ссылка на объект, вызвавший метод. Поскольку возвращаемую ссылку ничему присваивать не нужно, то правильнее считать, что метод изменяет значение строки;public StringBuilder Insert (int location,<объект>). Метод вставляет строку, полученную из объекта, в позицию, указанную параметром location. Метод Append является частным случаем метода Insert ;public StringBuilder Remove (int start, int len). Метод удаляет подстроку длины len, начинающуюся с позиции start ;public StringBuilder Replace (string str1,string str2). Все вхождения подстроки str1 заменяются на строку str2 ;public StringBuilder AppendFormat (<строка форматов>, <объекты>). Метод является комбинацией Append. Строка За исключением метода Remove, все рассмотренные методы являются перегруженными. В их описании дана схема вызова метода, а не точный синтаксис перегруженных реализаций. Приведу примеры, чтобы продемонстрировать, как вызываются и как работают эти методы:
//Методы Insert, Append, AppendFormat
StringBuilder strbuild = new StringBuilder();
string str = "это это не ";
strbuild.Append(str); strbuild.Append(true);
strbuild.Insert(4,false); strbuild.Insert(0,"2*2=5 - ");
Console.WriteLine(strbuild);
string txt = "А это пшеница, которая в темном чулане
хранится," +" в доме, который построил Джек!";
StringBuilder txtbuild = new StringBuilder();
int num =1;
foreach(string sub in txt.Split(','))
{
txtbuild.AppendFormat(" {0}: {1} ", num++,sub);
}
str = txtbuild.ToString();
Console.WriteLine(str);
В этом фрагменте кода конструируются две строки. Первая из них создается из строк и булевых значений true и false. Для конструирования используются методы Insert и Append. Вторая строка конструируется в цикле с применением метода AppendFormat. Результатом этого конструирования является строка, в которой простые предложения исходного текста пронумерованы.
Обратите внимание, что сконструированная вторая строка передается в обычную строку ToString.
Обратите внимание, как выглядят результаты работы.
(рис 14.4) Операции и методы класса StringBuilder
Каждый экземпляр строки класса
У класса
Capacity - возвращает или устанавливает текущую емкость буфера;MaxCapacity - возвращает максимальную емкость буфера. Результат один и тот же для всех экземпляров класса;int EnsureCapacity (int capacity) - позволяет уменьшить емкость буфера. Метод пытается вначале установить емкость, заданную параметром capacity ; если это значение меньше размера хранимой строки, то емкость устанавливается такой, чтобы гарантировать размещение строки. Это число и возвращается в качестве результата работы метода.Приведу код, в котором проводятся различные эксперименты с емкостью буфера:
//Емкость буфера
int curvol1 = txtbuild.Capacity;
int curvol2 = strbuild.Capacity;
int maxvol1 = txtbuild.MaxCapacity;
int maxvol2 = strbuild.MaxCapacity;
Console.WriteLine("curvol1= {0}",curvol1);
Console.WriteLine("curvol2= {0}",curvol2);
Console.WriteLine("maxvol1= {0}",maxvol1);
Console.WriteLine("maxvol2= {0}",maxvol2);
int sure1 = txtbuild.EnsureCapacity(100);
int sure2 = strbuild.EnsureCapacity(100);
Console.WriteLine("sure1= {0}",sure1);
Console.WriteLine("sure2= {0}",sure2);
curvol2 = strbuild.Capacity;
Console.WriteLine("curvol2= {0}",curvol2);
//ошибка! попытка установить емкость меньше длины строки
//strbuild.Capacity = 25;
strbuild.Capacity = 256; //так можно!
curvol2 = strbuild.Capacity;
Console.WriteLine("curvol2= {0}",curvol2);
//увеличим строку - емкость увеличится
int len = txtbuild.Length;
txtbuild.Append(txtbuild.ToString());
curvol1 = txtbuild.Capacity;
Console.WriteLine("curvol1= {0}",curvol1);
//уменьшим строку
txtbuild.Remove(len, len);
curvol1 = txtbuild.Capacity;
Console.WriteLine("curvol1= {0}",curvol1);
В этом фрагменте кода анализируются и изменятся емкостные свойства буфера двух объектов. Демонстрируется, как меняется емкость при увеличении и уменьшении размера строки. Результаты работы этого фрагмента кода показаны на рис. 14.5.
(рис 14.5) Анализ емкостных свойств буфера
В предыдущей лекции мы говорили о символьном типе char и строках постоянной длины, задаваемых массивом символов. Основным типом при работе со строками является тип
Объекты String достаточно много конструкторов. Они позволяют сконструировать строку из:
char[] ;Некоторым конструкторам в качестве параметра инициализации можно передать строку, заданную типом 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 созданы разными конструкторами
Заметьте, не допускается явный вызов конструктора по умолчанию - конструктора без параметров. Нет также конструктора, которому в качестве аргумента можно передать обычную строковую константу. Соответствующие операторы в тексте закомментированы.
Над строками определены следующие операции:
= );== ) и ( != );+ );[] ).Начну с присваивания, имеющего важную особенность. Поскольку string - это ссылочный тип, то в результате присваивания создается ссылка на константную строку, хранимую в "куче". С одной и той же строковой константой в "куче" может быть связано несколько переменных строкового типа. Но эти переменные не являются псевдонимами - разными именами одного и того же объекта. Дело в том, что строковые константы в "куче" не изменяются (о неизменяемости строкового типа будем далее говорить подробно), поэтому когда одна из переменных получает новое значение, она связывается с новым константным объектом в "куче". Остальные переменные сохраняют свои связи. Для программиста это означает, что семантика присваивания строк аналогична семантике значимого присваивания.
В отличие от других ссылочных типов, операции, проверяющие эквивалентность, сравнивают значения строк, а не ссылки. Эти операции выполняются как над значимыми типами.
Бинарная операция " + " сцепляет две строки, приписывая вторую строку к хвосту первой.
Возможность взятия индекса при работе со строками отражает тот приятный факт, что строку можно рассматривать как массив и получать без труда каждый ее символ. Каждый символ строки имеет тип char, доступный только для чтения, но не для записи.
Вот пример, в котором над строками выполняются данные операции:
public 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';
}
Без констант не обойтись. В C# существуют два вида строковых констант:
@.В обычных константах некоторые символы интерпретируются особым образом. Связано это прежде всего с тем, что необходимо уметь задавать в строке непечатаемые символы, такие, как, например, символ табуляции. Возникает необходимость задавать символы их кодом - в виде escape-последовательностей. Для всех этих целей используется комбинация символов, начинающаяся символом " \ " - обратная косая черта. Так, пары символов: " \n ", " \t ", " \\ ", " \ "" задают соответственно символ перехода на новую строку, символ табуляции, сам символ обратной косой черты, символ кавычки, вставляемый в строку, но не сигнализирующий о ее окончании. Комбинация " \xNNNN " задает символ, определяемый шестнадцатеричным кодом NNNN. Хотя такое решение возникающих проблем совершенно естественно, иногда возникают неудобства: например, при задании констант, определяющих путь к файлу, приходится каждый раз удваивать символ обратной косой черты. Это одна из причин, по которой появились
В
//Два вида констант
s1= "\x50";
s2=@"\x50""";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1 = "c:\\c#book\\ch5\\chapter5.doc";
s2 = @"c:\c#book\ch5\chapter5.doc";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1= "\"A\"";
s2=@"""A""";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
Взгляните на результаты работы приведенных фрагментов кода, полученные при вызове процедур TestDeclStrings и TestOpers.
(рис 14.1) Объявления, константы и операции над объектами string
В языке C# существует понятие
К таким
//Неизменяемые значения s1= "Zenon"; ch1 = s1[0]; //s1[0]='L';
| Метод | Описание |
|---|---|
Empty |
Возвращается пустая строка. Свойство со статусом read only |
Compare |
Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. При этом можно учитывать или не учитывать регистр, особенности национального форматирования дат, чисел и т.д. |
CompareOrdinal |
Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. Сравниваются коды символов |
Concat |
Конкатенация строк. Метод перегружен, допускает сцепление произвольного числа строк |
Copy |
Создается копия строки |
| Выполняет форматирование в соответствии с заданными спецификациями |
|
Intern, IsIntern |
Отыскивается и возвращается ссылка на строку, если таковая уже хранится во внутреннем пуле данных. Если же строки нет, то первый из методов добавляет строку во внутренний пул, второй - возвращает null. Методы применяются обычно тогда, когда строка создается с использованием построителя строк - класса |
| Конкатенация массива строк в единую строку. При конкатенации между элементами массива вставляются разделители. Операция, заданная методом |
Console.WriteLine("s1={0}, s2={1}", s1,s2);
Здесь строка, задающая первый аргумент метода, помимо обычных символов, содержит
Давайте рассмотрим общий синтаксис как самого System.IFormatProvider. Если этот параметр не задан, то используется культура, заданная по умолчанию. Вот примеры двух реализаций этого метода:
public static string Format(string, object); public static string Format(IFormatProvider, string, params object[]);
Параметр типа string задает форматируемую строку. Заданная строка содержит один или несколько
Общий синтаксис, специфицирующий
{N [,M [:<коды_форматирования>]]}
Обязательный параметр N задает индекс объекта, заменяющего M, если он задан, определяет минимальную ширину поля, которое отводится строке, вставляемой вместо C ( Currency ) говорит о том, что параметр должен форматироваться как валюта с учетом национальных особенностей представления. Код P ( Percent ) задает форматирование в виде процентов с точностью до сотой доли.
Все становится ясным, когда появляются соответствующие примеры. Вот они:
public void TestFormat()
{
//метод Format
int x=77;
string s= string.Format("x={0}",x);
Console.WriteLine(s + "\tx={0}",x);
s= string.Format("Итого:{0,10} рублей",x);
Console.WriteLine(s);
s= string.Format("Итого:{0,6:######} рублей",x);
Console.WriteLine(s);
s= string.Format("Итого:{0:P} ",0.77);
Console.WriteLine(s);
s= string.Format("Итого:{0,4:C} ",77.77);
Console.WriteLine(s);
//Национальные особенности
System.Globalization.CultureInfo ci =
new System.Globalization.CultureInfo("en-US");
s= string.Format(ci,"Итого:{0,4:C} ",77.77);
Console.WriteLine(s);
}//TestFormat
Приведу некоторые комментарии к этой процедуре. Вначале демонстрируется, что и явный, и неявный вызовы CultureInfo, инициализированный так, чтобы он задавал особенности CultureInfo наследует интерфейс IFormatProvider. Российские национальные особенности форматирования установлены по умолчанию. При необходимости их можно установить таким же образом, как это сделано для США, задав соответственно константу " ru-RU ". Результаты работы метода показаны на рис. 14.2.
(рис 14.2) Результаты работы метода Format
Методы
Заданный строкой текст зачастую представляет собой совокупность структурированных элементов - абзацев, предложений, слов, скобочных выражений и т.д. При работе с таким текстом необходимо разделить его на элементы, пользуясь специальными разделителями элементов, - это могут быть пробелы, скобки, знаки препинания. Практически подобные задачи возникают постоянно при работе со структурированными текстами. Методы
public string[] Split(params char[])
На вход методу string, вызвавший метод, разделяется на подстроки, ограниченные этими разделителями. Из этих подстрок создается массив, возвращаемый в качестве результата метода. Другая реализация позволяет ограничить число элементов возвращаемого массива.
Синтаксис
public static string Join(string delimiters, string[] items )
В качестве результата метод возвращает строку, полученную конкатенацией элементов массива items, между которыми вставляется строка разделителей delimiters. Как правило, строка delimiters состоит из одного символа, который и разделяет в результирующей строке элементы массива items ; но в отдельных случаях ограничителем может быть строка из нескольких символов.
Рассмотрим примеры применения этих методов. В первом из них строка представляет сложноподчиненное предложение, которое разбивается на простые предложения. Во втором предложение разделяется на слова. Затем производится обратная сборка разобранного текста. Вот код соответствующей процедуры:
public void TestSplitAndJoin()
{
string txt = "А это пшеница, которая в темном чулане
хранится," +" в доме, который построил Джек!";
Console.WriteLine("txt={0}", txt);
Console.WriteLine("Разделение текста на простые предложения:");
string[] SimpleSentences, Words;
//размерность массивов SimpleSentences и Words
//устанавливается автоматически в соответствии с
//размерностью массива, возвращаемого методом Split
SimpleSentences = txt.Split(',');
for(int i=0;i< SimpleSentences.Length; i++)
Console.WriteLine("SimpleSentences[{0}]= {1}",
i, SimpleSentences[i]);
string txtjoin = string.Join(",",SimpleSentences);
Console.WriteLine("txtjoin={0}", txtjoin);
Words = txt.Split(',', ' ');
for(int i=0;i< Words.Length; i++)
Console.WriteLine("Words[{0}]= {1}",i, Words[i]);
txtjoin = string.Join(" ",Words);
Console.WriteLine("txtjoin={0}", txtjoin);
}//TestSplitAndJoin
Результаты выполнения этой процедуры показаны на рис. 14.3.
(рис 14.3) Разбор и сборка строки текстаОбратите внимание, что методы
Если при разборе предложения на слова использовать в качестве разделителя только пробел, то пустые слова не появятся, но запятая будет являться частью некоторых слов.
Как всегда, есть несколько способов справиться с проблемой. Один из них состоит в том, чтобы написать собственную реализацию этих функций, другой - в корректировке полученных результатов, третий - в использовании более мощного аппарата регулярных выражений, и о нем мы поговорим чуть позже.
Операции, разрешенные над строками в C#, разнообразны. Методы этого класса позволяют выполнять вставку, удаление, замену, поиск вхождения подстроки в строку. Object, частично их переопределяя. IComparable, , IConvertible, IEnumerable. Три из них уже рассматривались при описании классов-массивов.
Рассмотрим наиболее характерные методы при работе со строками.
Сводка методов, приведенная в таблице 14.2, дает достаточно полную картину широких возможностей, имеющихся при работе со строками в C#. Следует помнить, что Replace, Insert и другие методы представляют собой функции, возвращающие новую строку в качестве результата и не изменяющие строку, вызвавшую метод.
| Метод | Описание |
|---|---|
Insert |
Вставляет подстроку в заданную позицию |
Remove |
Удаляет подстроку в заданной позиции |
Replace |
Заменяет подстроку в заданной позиции на новую подстроку |
Substring |
Выделяет подстроку в заданной позиции |
IndexOf, IndexOfAny, LastIndexOf, LastIndexOfAny |
Определяются индексы первого и последнего вхождения заданной подстроки или любого символа из заданного набора |
StartsWith, EndsWith |
Возвращается true или false, в зависимости от того, начинается или заканчивается строка заданной подстрокой |
PadLeft, PadRight |
Выполняет набивку нужным числом пробелов в начале и в конце строки |
Trim, TrimStart, TrimEnd |
Обратные операции к методам Pad. Удаляются пробелы в начале и в конце строки, или только с одного ее конца |
ToCharArray |
Преобразование строки в массив символов |
System.Text. Рассмотрим класс
Объекты этого класса объявляются с явным вызовом конструктора класса. Поскольку специальных констант этого типа не существует, то вызов конструктора для инициализации объекта просто необходим. Конструктор класса перегружен, и наряду с конструктором без параметров, создающим пустую строку, имеется набор конструкторов, которым можно передать две группы параметров. Первая группа позволяет задать строку или подстроку, значением которой будет инициализироваться создаваемый объект класса
public StringBuilder (string str, int cap). Параметр str задает строку инициализации, cap - public StringBuilder (int curcap, int maxcap). Параметры curcap и maxcap задают начальную и максимальную public StringBuilder (string str, int start, int len, int cap). Параметры str, start, len задают строку инициализации, cap - Над строками этого класса определены практически те же операции с той же семантикой, что и над строками
= );== ) и ( != );[] ).Операция конкатенации ( + ) не определена над строками класса Append, дописывающий новую строку в хвост уже существующей.
Со строкой этого класса можно работать как с массивом, но, в отличие от
public void TestStringBuilder()
{
//Строки класса StringBuilder
//операции над строками
StringBuilder s1 =new StringBuilder("ABC"),
s2 =new StringBuilder("CDE");
StringBuilder s3 = new StringBuilder();
//s3= s1+s2;
s3= s1.Append(s2);
bool b1 = (s1==s3);
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);
StringBuilder s = new StringBuilder("Zenon");
s[0]='L';
Console.WriteLine(s);
}//TestStringBuilder
Этот пример демонстрирует возможность выполнения над строками класса Append. Появляется новая возможность - изменять отдельные символы строки. (Для того чтобы имя класса using System.Text, ссылающееся на соответствующее пространство имен.)
У класса
public StringBuilder Append (<объект>). К строке, вызвавшей метод, присоединяется строка, полученная из объекта, который передан методу в качестве параметра. Метод перегружен и может принимать на входе объекты всех простых типов, начиная от char и bool до string и long. Поскольку объекты всех этих типов имеют метод ToString, всегда есть возможность преобразовать объект в строку, которая и присоединяется к исходной строке. В качестве результата возвращается ссылка на объект, вызвавший метод. Поскольку возвращаемую ссылку ничему присваивать не нужно, то правильнее считать, что метод изменяет значение строки;public StringBuilder Insert (int location,<объект>). Метод вставляет строку, полученную из объекта, в позицию, указанную параметром location. Метод Append является частным случаем метода Insert ;public StringBuilder Remove (int start, int len). Метод удаляет подстроку длины len, начинающуюся с позиции start ;public StringBuilder Replace (string str1,string str2). Все вхождения подстроки str1 заменяются на строку str2 ;public StringBuilder AppendFormat (<строка форматов>, <объекты>). Метод является комбинацией Append. Строка За исключением метода Remove, все рассмотренные методы являются перегруженными. В их описании дана схема вызова метода, а не точный синтаксис перегруженных реализаций. Приведу примеры, чтобы продемонстрировать, как вызываются и как работают эти методы:
//Методы Insert, Append, AppendFormat
StringBuilder strbuild = new StringBuilder();
string str = "это это не ";
strbuild.Append(str); strbuild.Append(true);
strbuild.Insert(4,false); strbuild.Insert(0,"2*2=5 - ");
Console.WriteLine(strbuild);
string txt = "А это пшеница, которая в темном чулане
хранится," +" в доме, который построил Джек!";
StringBuilder txtbuild = new StringBuilder();
int num =1;
foreach(string sub in txt.Split(','))
{
txtbuild.AppendFormat(" {0}: {1} ", num++,sub);
}
str = txtbuild.ToString();
Console.WriteLine(str);
В этом фрагменте кода конструируются две строки. Первая из них создается из строк и булевых значений true и false. Для конструирования используются методы Insert и Append. Вторая строка конструируется в цикле с применением метода AppendFormat. Результатом этого конструирования является строка, в которой простые предложения исходного текста пронумерованы.
Обратите внимание, что сконструированная вторая строка передается в обычную строку ToString.
Обратите внимание, как выглядят результаты работы.
(рис 14.4) Операции и методы класса StringBuilder
Каждый экземпляр строки класса
У класса
Capacity - возвращает или устанавливает текущую емкость буфера;MaxCapacity - возвращает максимальную емкость буфера. Результат один и тот же для всех экземпляров класса;int EnsureCapacity (int capacity) - позволяет уменьшить емкость буфера. Метод пытается вначале установить емкость, заданную параметром capacity ; если это значение меньше размера хранимой строки, то емкость устанавливается такой, чтобы гарантировать размещение строки. Это число и возвращается в качестве результата работы метода.Приведу код, в котором проводятся различные эксперименты с емкостью буфера:
//Емкость буфера
int curvol1 = txtbuild.Capacity;
int curvol2 = strbuild.Capacity;
int maxvol1 = txtbuild.MaxCapacity;
int maxvol2 = strbuild.MaxCapacity;
Console.WriteLine("curvol1= {0}",curvol1);
Console.WriteLine("curvol2= {0}",curvol2);
Console.WriteLine("maxvol1= {0}",maxvol1);
Console.WriteLine("maxvol2= {0}",maxvol2);
int sure1 = txtbuild.EnsureCapacity(100);
int sure2 = strbuild.EnsureCapacity(100);
Console.WriteLine("sure1= {0}",sure1);
Console.WriteLine("sure2= {0}",sure2);
curvol2 = strbuild.Capacity;
Console.WriteLine("curvol2= {0}",curvol2);
//ошибка! попытка установить емкость меньше длины строки
//strbuild.Capacity = 25;
strbuild.Capacity = 256; //так можно!
curvol2 = strbuild.Capacity;
Console.WriteLine("curvol2= {0}",curvol2);
//увеличим строку - емкость увеличится
int len = txtbuild.Length;
txtbuild.Append(txtbuild.ToString());
curvol1 = txtbuild.Capacity;
Console.WriteLine("curvol1= {0}",curvol1);
//уменьшим строку
txtbuild.Remove(len, len);
curvol1 = txtbuild.Capacity;
Console.WriteLine("curvol1= {0}",curvol1);
В этом фрагменте кода анализируются и изменятся емкостные свойства буфера двух объектов. Демонстрируется, как меняется емкость при увеличении и уменьшении размера строки. Результаты работы этого фрагмента кода показаны на рис. 14.5.
(рис 14.5) Анализ емкостных свойств буфера
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.