C# и Я

О программировании в C#, о себе и немного флуда на разнообразные темы.

Работа со строками в C#.

Чистый C#, by admin.

Строки в C# – это не простые переменные типа int или bool. Когда мы объявляем какую-либо переменную, то система сразу знает сколько памяти необходимо выделить для хранения значения. Как в этом случае системе быть со строками? Каждый символ в строке занимает 2 байта (в .NET по умолчанию используется Unicode), но количество символов может быть разным.

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

C# – это довольно молодой язык программирования и его разработчики постарались учесть все возможные нюансы и тонкости работы со строками. Вот об том мы сегодня с вами и поговорим.

Строки в C# – это объекты типа String значением которого является текст. Что это значит? Как я и обещал,  вначале рассмотрим аналогию строк в Delphi и C#. 

Вот так мы могли работать со строкой в Delphi:

var s: string; //объявили переменную
begin
  Label1.Caption:=S;
end;

И такой код в Delphi компилируется на ура. В итоге мы бы получили в Caption пустую строку. Но в C# строка – объект. Проведите аналогия с объектом в Delphi. Что получим, если попробуем обратиться к свойству объекта, когда его ещё не существует, он не создан? Правильно – AV, со всеми вытекающими последствиями. Примерно то же самое и при обращении к непроинициализированной строке в C#. Если написать в Visual Studio:

private void button1_Click(object sender, EventArgs e)
  {
   string s;
   label1.Text = s;
  }

То сразу получим сообщение об ошибке "Ошибка: Использование локальной переменной "s", которой не присвоено значение". Так то. Прежде, чем обращаться к строке ей следует создать, т.е. передать объекту какое-либо значение. В C# строки (да и любые переменные в принципе) можно объявлять следующим образом:

string s;//объявление без инициализации
string s = null; //инициализируем, присваивая значение null
string s = "Hello World";//инициализируем, присвоив в качестве значения текст

Теперь исправим немного листинг и напишем:

private void button1_Click(object sender, EventArgs e)
  {
   string s = null;
   label1.Text = s;
  }

Вот после этого код Delphi и код C# будут работать идентично – в Caption метки выведется пустая строка. Это что касается объявления строк.

Теперь следующий момент – в .NET нельзя изменять строки. Что это значит? Например, есть код:

string str;
str = "Строка 1";
str = "Строка с другим количеством символов"

Что здесь такого необычного? На самом деле вторая и третья строка кода содержат разные переменные. Поясню по порядку: строка №1: объявили переменную типа string; при этом память под неё не выделена. строка №2: выделили память под строку и записали в неё значение. строка №3: несмотря на то, что строка уже проинициализирована память старого значения уничтожается, затем повторно под новое значение выделяется память и записывается значение. И все эти операции происходят автоматически. С одной стороны – выглядит мощно, с другой – бьет по скорости выполнения. Но о скорости мы ещё успеем поговорить. А пока ещё несколько слов о неизменности строк в C#. Аналогичным образом (как в предыдущем примере) выполняются и операции соединения строк, т.е. код:

string s = "Hello";
string s = s + " World";

Также приведет к переопределению памяти и созданию нового объекта строки. Как видите процесс работы со строками с одной стороны довольно прост – всю рутинную работу берет на себя система, но с другой стороны можно легко в ходе работы программы нарваться на пустую или неинициализированную строку. Как избежать подобных случаев? В C# есть замечательный метод под названием IsNullOrEmpty, которые возвращает True в случае, если передаваемый параметр равен null или пустой строке. Использовать метод можно, например так:

  string s=null;
  if (String.IsNullOrEmpty(s))
     {
       label1.Text = "Пустая строка";
     }

Так как мы проинициализировали строку значением null, то в Label1.Caption выведется значение "Пустая строка".

О проверке строк тоже поговорили. Теперь поговорим о строке как об объекте. Как и любой другой объект строка имеет свои методы.

Методы для работы со строками

Contains() – позволяет узнать, содержит ли строка подстроку, переданную в качестве параметра. Если содержит, то метод вернет True. Пример использования:

string s="Hello world";
if (s.Contains("Hell"))
  {
    Console.WriteLine("Содержит");
  }

Format() – статичный метод ( аналог классового метода в Delphi), который позволяет форматировать строки. Внутри строки можно указывать в фигурных скобках места куда должны вставляться второй, третий и т.д. параметры, например:

  string s=null;
  s = String.Format("Вместо параметра 0 вставим приветствие {0}", "Hello World");
  Console.WriteLine(s);

IndexOf() – возвращает индекс символа, начиная с которого в строке найдена подстрока, переданная в качестве параметра. Если ничего не найдено, то результат равен -1. Пример использования:

 string s="Hello world";
 int index = s.IndexOf("world");
 Console.WriteLine(index);//выведет 6

Insert() – вставляет подстроку, переданную во втором параметре, в строку, начиная с символа, указанного в первом параметре. Например, вставим слово "мир" в переменную str, начиная с седьмой позиции:

string str="Привет ";
string newstr = str.Insert(7, "мир");
label1.Text = newstr;//выведет "Привет мир"

Переменная str в приведенном примере не изменится, а newstr получит уже новое значение.

PadLeft() и PadRight() похожие друг на друга методы. Суть их работы заключается в том, чтобы вписать строку в новую, размер которой задан в параметрах метода. PadLeft() при этом добавляет пробелы слева, а PadRight() справа до момента пока строка не станет заданной длины. Например, впишем строку "мир" в новую длинной десять символов:

string str="мир";
string newstr = str.PadLeft(10);
label1.Text = newstr;//слева от слова "мир" появятся пробелы

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

 string str="Привет";
 str = str.Remove(3);
 label1.Text = str;//вернет "При"

Replace() – ищет в строке подстроку, указанную в качестве первого параметра и заменяет её на строку из второго параметра, возвращая результат замены. Например:

string str="Привет";
str = str.Replace("Привет","Hello");
label1.Text = str;//вернет "Hello"

ToUpper(), ToLower() – возвращают строку, все символы которой приведены к верхнему или нижнему регистру. Например:

string str="ПрИвеТ";
str = str.ToLower();
label1.Text = str;//вернет "привет"

ToCharArray() – переводит строку в массив символов. Удобно использовать, когда необходимо проанализировать строку посимвольно, например, с использованием цикла foreach:

string str="ПрИвеТ";
char[] chars = str.ToCharArray();
foreach (char ch in chars)
   Console.WriteLine(ch);

Escape-последовательности строк

Внутри строк можно использовать следующие escape-последовательности:

Escape-последовательность

Имя символа

Кодировка Юникода

\’ Одинарная кавычка 0×0027
\" Двойная кавычка 0×0022
\\ Обратная косая черта 0x005C
\0 Null 0×0000
\a ALERT 0×0007
\b Backspace 0×0008
\f FORM FEED 0x000C
\n Новая строка 0x000A
\r Возврат каретки 0x000D
\t Горизонтальная табуляция 0×0009
\U Escape-последовательность Юникода для пар символов-заместителей. \Unnnnnnnn
\u Escape-последовательность Юникода \u0041 = "A"
\v Вертикальная табуляция 0x000B
\x Escape-последовательность Юникода аналогична "\u", за исключением строк с переменной длиной. \x0041 = "A"

Так как символ бэкслэша является управляющим, то, если Вам необходимо передать в строке, например, путь к файлу, то этот символ необходимо удвоить:

C:\\windows\\file.txt

Если же удваивать слэш Вам не хочется или Вы не можете этого сделать, то можно передать строку так:

@”C:\\windows\file.txt”

Внутри такой строки управляющие символы и escape-последовательности работать не будут.

Вот, пожалуй те основные сведения, которые пригодятся нам на первом этапе изучения языка C#. Это далеко не все возможности работы со строками. Так, например, я не стал рассматривать класс для построения строк StringBuilder или сравнение строк друг с другом и т.д. Все эти моменты мы рассмотрим в следующих статьях блога.


No related posts.

Back Top

Responses to “Работа со строками в C#.”

Comments (2) Trackbacks (0) Leave a comment Trackback url
  1. На самом деле вторая и третья строка кода содержат разные переменные. Поясню по порядку: строка №1: объявили переменную типа string; при этом память под неё не выделена. строка №2: выделили память под строку и записали в неё значение. строка №3: несмотря на то, что строка уже проинициализирована память старого значения уничтожается, затем повторно под новое значение выделяется память и записывается значение.

    Не надо забывать, что string – это ссылочный тип! Строка 3 в этом случае просто загрузит новый объект string в управляемую кучу. И в ней будут уже 2 объекта. Безусловно, предыдущий объект из строки 2 будет в конечном итоге удален сборщиком мусора. Но вот произойдет это далеко не сразу.

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

    Класс string является идеальным вариантом для представления базовых символьных данных. Но он может оказываться неэффективным и приводить к «разбуханию» кода в случае неправильного использования, особенно при выполнении конкатенации строк.

  1. No trackbacks yet.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*