Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Podbelsky_V_V_C_Bazovy_kurs.pdf
Скачиваний:
69
Добавлен:
02.06.2015
Размер:
1.73 Mб
Скачать

130

Г л а в а 8

 

 

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

Спецификация Е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

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

Строки – объекты класса string

131

 

 

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

Как мы уже знаем, оператор 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) {

132

Г л а в а 8

 

 

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);

}

}

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

* ** *** ****

Строки – объекты класса string

133

 

 

В программе создан массив из четырех пустых строк. Он представлен ссылкой stAr. Обратите внимание, что для создания объектов, адресуемых элементами массива, применяется конструктор с прототипом string (char, int); Этот конструктор создаёт строку в виде последовательности одинаковых символов, количество которых определяет второй параметр. (Первый параметр позволяет задать повторяемый символ.) Итерационная переменная цикла foreach имеет тип string, так как просматриваемым контейнером служит массив типа string[ ].

Для иллюстрации применения методов Split(), 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("word.Length = " + words.Length); foreach (string st in words)

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

}

}

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

word.Length = 5

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

В строке, связанной со ссылкой sent, помещены слова, разделенные пробелами. Определена ссылка words на массив строк (объектов класса string). Обращение sent.Split(' ') «разбивает»

134

Г л а в а 8

 

 

строку, адресованную ссылкой sent, на фрагменты. Признак разбиения – символ пробел ' ', использованный в качестве аргумента. Из выделенных фрагментов формируется массив (объект класса string[]), и ссылка на него присваивается переменной words.

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

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

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

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

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

Строки – объекты класса string

135

 

 

Так как сравнение и сортировка строк очень важны в задачах обработки текстовой информации, то рассмотрим два варианта метода 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".

Проиллюстрированная форма метода Compare() оценивает лексикографическую упорядоченность, соответствующую английскому алфавиту. Следующий вариант этого метода позволяет использовать разные алфавиты.

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

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

136

Г л а в а 8

 

 

конструктора – строка, содержащая условное обозначение нужного алфавита. Точнее сказать, обозначается не алфавит, а культура (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, принимается в качестве претендента на наименьшее значение.

Строки – объекты класса string

137

 

 

8.9.Преобразования

сучастием строкового типа

Рассматривая арифметические типы, мы привели правила неявных преобразований и операцию явного приведения типов:

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

К строковому типу неявные преобразования не применимы, и невозможно использование операции явного приведения типов.

Как уже отмечалось, для всех типов существует метод ToString(), унаследованный всеми классами от единого базового класса object. Таким образом, значение любого типа можно представить в виде строки, например, так:

int n = 8, m = 3; Console.WriteLine(m.ToString()+n.ToString() + « попугаев»);

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

38 попугаев.

Для обратного преобразования из строки в значение другого типа можно воспользоваться статическими методами библиотечного класса Convert, принадлежащего пространству имен System. Ещё один путь – применение статического метода Parse() или метода TryParse(). Указанные методы (их применение кратко рассмотрено в главе 5) определены в каждом классе предопределенного типа, за исключением класса object (в котором они не нужны). Эти методы часто применяется при чтении данных из входного консольного потока. Метод Console. ReadLine() возвращает в виде строки набранную на клавиатуре последовательность символов. "Расшифровку" этой последовательности, т. е. превращение символьного представления во внутреннее представление (в код) соответствующего значения, удобно выполнить с помощью метода Parse() или TryParse(). Наиболее просто, но совсем небезопасно, применить метод Parse(), например, таким образом:

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]