Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky

.pdf
Скачиваний:
36
Добавлен:
22.03.2016
Размер:
2 Мб
Скачать
☆

Строка форматирования "строка форматирования" включает неизменяемые символы и конструкции, называемые полями подстановок. Структура поля подстановки "поля подстановок" : {N[,W][:S[R]]}, где N – номер аргумента; W -

ширина поля; S - спецификатор формата; R – спецификатор точности.

Квадратные скобки в поля подстановки не входят и обозначают необязательность ограниченного ими фрагмента (элемента) поля. В поле подстановки разрешено опускать все элементы кроме фигурных скобок и номера аргумента. Именно поэтому все остальные элементы поля подстановки мы ограничили квадратными скобками. Воспользуемся этим правилом, чтобы привести

первый пример.

int num = 23, den = 6;

string result, // ссылка на строку, с результатом

form = "Числитель: {0}, знаменатель: {1}, дробь: {0}/{1}=={2}"; result = string.Format(form, num, den, num / den); Console.WriteLine(result);

В примере определены две ссылки

result и form на объекты типа

string.

Значение строки, связанной со ссылкой

form, определено инициализирующей

строковой константой. В ней пять полей подстановок. Номера в полях указывают,

символьные представления значений каких (по счету, начиная с 0) аргументов будут подставлены вместо соответствующих полей. В обращении к методу Format()

первый аргумент – строка form, затем num – аргумент, с номером 0, den – аргумент,

которому соответствует номер 1, num/den – выражение, значение которого воспринимается как аргумент с номером 2. В результате выполнения подстановок метод Format() возвращает строку, ссылка на которую присвоена переменной result.

Выводя эту строку на консоль, получим:

Числитель: 23, знаменатель: 6, дробь: 23/6==3

(Обратите внимание на округление результата целочисленного деления.)

В приведённом примере поля подстановок "поля подстановок" содержали только номера аргументов. Разберём назначение других элементов, которые в поле

подстановки необязательны. Запятая и следующее за ним число (W - ширина поля)

в поле подстановки определяет количество позиций, выделяемых для изображения подставляемого значения. Если эти элементы (запятая и число) опущены, то число позиций определяется изображением выводимого значения, то есть ширина поля выбирается минимально достаточной для изображения значения. Если ширина поля указана, и она превышает длину помещаемого в поле значения, то при положительной длине поля W значение выравнивается по правой границе. Если перед шириной поля W стоит минус, то выравнивание выполняется по левой границе поля.

Спецификатор формата S задаёт вид изображаемого значения. Для разных типов данных этот спецификатор выбирается по-разному. Следующая за ним цифра

– спецификатор точности R – влияет на формируемое значение, и это влияние зависит от спецификатора формата.

Спецификаторы формата S и точности R

Таблица 8.1.

Спецификатор S

Название формата

Роль спецификатора

С или с

Валютный

точности R

Количество десятичных

D или d

Целочисленный

разрядов

Минимальное число

E или e

Экспоненциальный

цифр

Число разрядов после

F или f

С фиксированной точкой

точки

Число разрядов после

N или n

Число с разделителем

точки

Число знаков после

P или p

триад

точки

Значение в процентах

Число знаков после

G или g

(%)

 

Короткий из E или F

точки

X или x

Шестнадцатеричный

Подобен E или F

Минимальное число

 

 

цифр

Пример :

double dou = 1234.567;

string form = "Спецификация Е4: {0:E4}, спецификация F4: {0:F4}"; string result = string.Format(form, dou);

Console.WriteLine(result);

В обоих полях подстановки строки форматирования опущена ширина поля, и

предполагается дважды использовать только один аргумент (с номером 0).

Выводимая строка:

Спецификация Е4: 1,2346E+003, спецификация F4: 1234,5670

Обратите внимание на округление при выводе по формату Е4 и на дополнительный нуль в изображении числа с фиксированной точкой при выводе по формату F4. Это определяется спецификатором точности, равным 4.

Пример с целочисленным значением, выводимым с разными основаниями в

поля из 4-х позиций. Обратите внимание, что ширина первого поля отрицательна: int num = 23;

string form = "Основание 10: {0,-4:D}\n основание 16: {0,4:X}"; Console.WriteLine(form, num);

Результат в консольном окне:

Основание 10: 23 основание 16: 17

В этом примере форматирование выполняется непосредственно при обращении к методу WriteLine(). Первый аргумент выступает в роли форматной строки, а вызов метода string.Format() осуществляется неявно.

Если в этом примере в полях подставки указать спецификаторы точности, то в

изображениях целых чисел могут появиться незначащие нули. Пример: int num = 23;

string form = "Основание 10: {0,-4:D3}\n основание 16: {0,4:X3}";

Console.WriteLine(form, num);

Результат:

Основание 10: 023 основание 16: 017

Примечание: если в поле подстановки указана ширина, недостаточная для представления выводимого значения, то ширина поля будет автоматически увеличена до необходимого количества позиций.

8.6. Строка как контейнер

Как мы уже знаем, оператор foreach "оператор: foreach" предназначен для последовательного перебора всех элементов некоторого контейнера. Если в качестве контейнера выступает массив, например, с элементами типа long, то для просмотра значений всех его элементов можно использовать цикл с заголовком

foreach (long cell in массив)

В этом цикле итерационная переменная cell имеет тот же тип, что и элементы массива и последовательно принимает значения его элементов.

Если нужно применить такой же цикл для перебора элементов объекта типа string, то используется итерационная переменная типа char. В качестве контейнера выступает строковый литерал, либо объект класса string (либо ссылка на такой объект). Пример со строковым литералом:

foreach (char numb in "0123") Console.Write("\t"+numb+"->"+(int)numb);

Результат:

0–>48 1->49 2->50 3->51

8.7. Применение строк в переключателях

Мы уже упоминали, что объекты класса string (и ссылки на них) могут

использоваться в метках переключателя "метка:метка переключателя" и служить значением переключающего выражения. Для иллюстрации этих возможностей рассмотрим схему решения такой задачи: "Ввести фамилию человека (например,

служащего компании) и вывести имеющиеся сведения о нём". Характер этих сведений и конкретные сведения нам не важны – покажем общую схему решения

подобных задач с использованием переключателя и строк.

Console.Write("Введите фамилию:"); string name= Console.ReadLine(); swich(name) {

case "Сергеев": Console.WriteLine("Фрол Петрович");

...Вывод данных о Сергееве ...

break;

case "Туров":

...Вывод данных о Турове ...

break;

. . . .

default: Console.Write ("Нет сведений");

}

8.8. Массивы строк

Как любые объекты, строки можно объединять в массивы. Хотя внимательный читатель заметит, что в массив помещаются не строки, а только ссылки на них, но при использовании массивов ссылок на строки "массив:массив ссылок на строки" не требуются никакие специальные операции для организации обращения к собственно строкам через ссылки на них. Поэтому в литературе,

посвящённой языку C#, зачастую говорят просто о массивах строк. В следующей программе создаётся массив ссылок на строки, по умолчанию инициализированный пустыми строками. Затем в цикле элементам массива (ссылкам) присваиваются значения ссылок на объекты-строки разной длины. Далее к массиву применяется оператор перебора контейнеров foreach, и строки выводятся на консоль.

// 08_01.cs - массивы строк...

using System;

class Program { static void Main() {

string [] stAr = new string[4]; for (int i = 0; i<star.Length; i++)

stAr[i] = new string('*', i + 1); foreach (string rs in stAr)

Console.Write("\t" + rs);

}

}

Результат выполнения программы:

* ** *** ****

В программе создан массив из четырёх пустых строк. Он представлен ссылкой stAr. Обратите внимание, что для создания объектов, адресуемых элементами

массива, применяется конструктор "конструктор" с прототипом string (char, int);

Этот конструктор создаёт строку в виде последовательности одинаковых символов,

количество которых определяет второй параметр. (Первый параметр позволяет задать повторяемый символ.) Итерационная переменная цикла foreach имеет тип string, так как просматриваемым контейнером служит массив типа string[ ].

Для иллюстрации применения методов Split() "метод: Split()" , Join() "метод:

Join()" , рассмотрим следующую задачу. Пусть значением строки является предложение, слова которого разделены пробелами. Требуется заменить каждый пробел последовательностью символов "-:-". Следующая программа решает

сформулированную задачу.

// 08_02.cs – декомпозиция "декомпозиция строк" и объединение строк. using System;

class Program

{

static void Main()

{

string sent = "De gustibus non est disputandum"; // о вкусах не спорят

string[] words; //ссылка на массив строк words = sent.Split(' ');

Console.WriteLine("words.Length = " + words.Length); foreach (string st in words)

Console.Write("{0}\t", st); sent = string.Join("-:-", words); Console.WriteLine("\n" + sent);

}

}

Результат выполнения программы: words.Length = 5

De gustibus non est disputandum De-:-gustibus-:-non-:-est-:-disputandum

В строке, связанной со ссылкой sent, помещены слова, разделённые пробелами.

Определена ссылка words на массив строк (объектов класса

string). Обращение

sent.Split(' ') "разбивает" строку, адресованную ссылкой sent, на фрагменты.

Признак разбиения – символ пробел ' ', использованный в качестве аргумента. Из

выделенных фрагментов формируется массив (объект класса string[ ]), и ссылка на него присваивается переменной words.

Выражение w o r d s . L e n g t h равно длине (количеству элементов)

сформированного массива. Напомним, что Length – свойство класса массивов string[ ], унаследованное от базового класса Array.

Оператор foreach перебирает элементы массива words, и итерационная переменная st последовательно принимает значения каждого из них. (Напомним, что особенность итерационной переменной состоит в том, что она позволяет только получать, но не позволяет изменять значения перебираемых элементов.) В теле цикла foreach один оператор – обращение к статическому методу Write() класса

Console. Его выполнение обеспечивает вывод значений элементов массива (строк).

Эскейп-последовательность '\t' в поле подстановки разделяет табуляцией выводимые слова.

Статический метод Join() предназначен для выполнения действий в некотором смысле обратных действиям метода Split(). Обращение string.Join("-:-", words)

объединяет (конкатенирует) строки массива, представленного ссылкой words, то есть соединяет в одну строку слова исходного предложения. Между словами вставляется строка, использованная в качестве первого аргумента метода Join(). Тем самым каждый пробел между словами исходной строки заменяется строкой "-:-".

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

Для объектов класса string определены только две операции сравнения

"сравнение строк" == и !=. Если необходимо сравнивать строки по их упорядоченности, например, в лексикографическом порядке, то этих двух операций недостаточно. Кроме уже упомянутого нестатического метода CompareTo() в классе string есть статический метод (точнее набор перегруженных методов) с именем

Compare, позволяющий сравнивать строки или их фрагменты. Так как сравнение и сортировка строк очень важны в задачах обработки текстовой информации, то

рассмотрим два варианта метода Compare() "метод: Compare()" .

Наиболее простой метод имеет следующий заголовок: int static Compare (string, string)

Сравнивая две строки, использованные в качестве аргументов, метод возвращает значение 0, если строки равны. Если первая строка лексикографически меньше второй – возвращается отрицательное значение. В противном случае возвращаемое значение положительно.

В следующем фрагменте программы определён массив ссылок на строки, из него выбирается и присваивается переменной res ссылка на лексикографически

наибольшую строку (08_03.cs):

string[] eng = {"one", "two", "three", "four"}; string res = eng[0];

foreach (string num in eng)

if (string.Compare(res, num) < 0) res = num;

Значением строки, связанной со ссылкой-переменной res, будет "two".

Проиллюстрированная форма метода C o m p a r e ( ) оценивает лексикографическую упорядоченность, соответствующую английскому алфавиту.

Следующий вариант этого метода позволяет использовать разные алфавиты.

int static Compare (string, string, Boolean,CultureInfo)

Первые два параметра – сравниваемые строки. Третий параметр указывает на необходимость учитывать регистр символов строк. Если он равен true, то регистры не учитываются и строки "New" и "nEw" будут считаться равными. Четвёртый параметр – объект класса System.Globalization.CultureInfo – позволяет указать алфавит, который необходимо использовать при лексикографическом сравнении строк. Для построения объекта, который может быть использован в качестве аргумента, заменяющего четвёртый параметр, используют конструктор класса

CultureInfo(string). Аргумент конструктора – строка, содержащая условное обозначение нужного алфавита. Точнее сказать, обозначается не алфавит, а

культура (Culture), которой принадлежит соответствующий язык. Для обозначения национальных культур, приняты имена и коды, таблицу которых можно найти в литературе и документации, (см. например, [13], Приложение 2). Мы в наших примерах будем использовать два алфавита: английский (имя культуры "en", код культуры 0х0009) и русский ("ru" и 0х0019).

В следующем фрагменте программы(08_03.cs), который построен по той же схеме, что и предыдущий, определён массив ссылок на строки с русскими названиями представителей семейства тетеревиных из отряда куриных. Из массива выбирается ссылки на лексикографически наименьшую строку, т.е. расположенную

после упорядочения по алфавиту в начале списка.

string[ ] hens = {"Куропатка белая", "Куропатка тундровая", "Тетерев", "Глухарь", "Рябчик" };

string res = hens[0]; foreach (string hen in hens)

if (string.Compare(res, hen, true,

new System.Globalization.CultureInfo("ru")) > 0) res = hen;

Console.WriteLine(res);

Результат, выводимый на консоль:

Глухарь

Обратите внимание, что четвёртый параметр метода Compare() заменён в вызове безымянным объектом класса CultureInfo, сформированным конструктором класса в выражении с операцией new. Аргумент конструктора – литерная строка

"ru" – обозначение нужного алфавита (в данном примере – русского языка). Если возвращаемый результат, больше нуля, то есть первая строка, именуемая ссылкой res, лексикографически больше второй, то вторая строка, связанная со ссылкой hen,

принимается в качестве претендента на наименьшее значение.

8.9. Преобразования с участием строкового типа

Рассматривая арифметические типы, мы привели правила неявных

преобразований и операцию явного приведения типов:

(тип) первичное_выражение

К строковому типу неявные преобразования не применимы, и невозможно

использование операции явного приведения типов.

Как уже отмечалось, для всех типов существует метод ToString() "метод:

ToString()" , унаследованный всеми классами от единого базового класса object.

Таким образом, значение любого типа можно представить в виде строки, например,

так:

int n = 8, m = 3;

Console.WriteLine(m.ToString()+n.ToString() + " попугаев");

Результат вывода на консоль:

38 попугаев.

Для обратного преобразования из строки в значение другого типа можно

воспользоваться статическими методами библиотечного класса Convert,

принадлежащего пространству имён System. Ещё один путь – применение

статического метода Parse() "метод: Parse()" или метода TryParse(). Указанные

методы (их применение кратко рассмотрено в главе 5) определены в каждом классе предопределённого типа, за исключением класса object (в котором они не нужны).

Эти методы часто применяется при чтении данных из входного консольного потока.

Метод Console.ReadLine() возвращает в виде строки набранную на клавиатуре последовательность символов. "Расшифровку" этой последовательности, то есть превращение символьного представления во внутреннее представление (в код)

соответствующего значения, удобно выполнить с помощью метода Parse() или

TryParse(). Наиболее просто, но совсем небезопасно, применить метод Parse(),

например таким образом:

int res = int.Parse(Console.ReadLine());

В данном случае изображение целого числа в виде набранной на клавиатуре

Соседние файлы в папке CSBasicCourse2ndedPodbelsky