Литералы
Литерал(literal) – запись в коде программы, который имеет фиксированное(константное) значение. Литералами также называют представление некоторых типов данных в виде текстовых строк. С помощью литералов, в языке C#, переменным передаются значения.
- логические или булевы;
- целочисельные;
- вещественные или дробные;
- символьные;
- строковые;
- массивы-литералы;
- объектные литералы;
- null-литерал.
Логические(булевы) литералы
В .Net есть две булевы(от типа данных bool) константы: true(истина) та false(ложь):
Целочисельные литералы
Данный тип литералов предназначен для представления, положительных и отрицательных, целых чисел к примеру -9, 0, 11, 42.
C# поддерживает чисельные литералы для разных систем счисления.
Двоичные(бинарные)
Появились в C# версии 7.0. Используются для записи чисел в двоичной системе счисления, перед числом нужно ставить префикс 0b, за которым следует, набор нулей и единиц двоичной формы: 0b101, 0b100111, 0B001010.
В бинарных литералах, для форматирования, можно использовать символ подчеркивания “_”: 0b____1011 то же, что и 0b00001011.
Восьмеричные
Предназначены для представления чисел восьмеричной системы счисления, используется префикс 0, после которого записывают восьмеричное число(от 0 до 7): 0123, 0742, 0349.
Десятичные
Запись в десятичной форме счисления. Числа записываются в привычной для нас форме: -5, 12, 78.
Шестнадцатеричные
Предназначены для шестнадцатеричной системы счисления, используется префикс 0x, после которого записывают число в шестнадцатеричной системе(от 0 до 9 и от A до F): 0x12, 0xA56B, 0xff430c1.
Регистр символов не различается компилятором: 0b01 то же, что и 0B01, 0xaBc = 0XAbC = 0xABC.
Вещественные литералы
Дробные или вещественные литералы используют для записи дробных чисел. Этот тип литералов имеет две формы записи.
Числа с фиксированной точкой – в этой форме целая часть числа отделяется от дробной с помощью точки “.”. Например: 3.1415, -2.0012, 1.137.
Экспоненциальная форма – в такой форме записи, вещественное число имеет мантиссу и порядок.
Число Number = Mantissa ⋅ 10 p , где Mantissa — мантисса, p — порядок, записывается в виде Number = MantissaEp.
1000 = 1 ⋅ 10 3 = 1e3;
23400 = 2.34 ⋅ 10 4 = 2.34e4;
-0.00000056 = -5.6 ⋅ 10 -7 = -5.6e-7;
В экспоненциальной форме записи, регистр символа Е не имеет значения.
Символьные литералы
Для записи отдельных букв(символов), я в зыке C#, используются символьные литералы. Символы представляются в одинарных кавычках: ‘a’, ‘x’, ‘%’.
Кроме обычных символов, в C#, есть так званые, управляющие последовательности(escape sequence). Они предназначены для представления специальных символов, записываются как обратный слэш, за которым расположен символ.
Наиболее распространенные Escape-последовательности:
| Управляющая последовательность | Значение |
|---|---|
| \b | Backspace |
| \n | Переход на новую строку |
| \r | Возврат каретки |
| \t | Горизонтальная табуляция |
| \v | Вертикальная табуляция |
| \’ | Одиночная кавычка(апостроф) |
| \” | Двойная кавычка |
| \\ | Обратный слэш |
| \xHH | Символ ASCII в шестнадцатеричной нотации |
| \uHH | Символ Unicode в шестнадцатеричной нотации |
Использование управляющих последовательностей:
Строковые литералы
Строковые литералы – строка символов записанная в двойные кавычки. В строковых литералах также можно использовать управляющие последовательности.
Массивы-литералы
Массивы-литералы предназначены для инициализации массива. Можно использовать две формы записи: с указанием типа данных и без типа.
Объектные литералы
Используются для инициализации объектов.
К примеру для класса
объектный литерал будет иметь форму:
null-литерал
null – особенный ссылочный тип литерала, указывает на отсутствие значения(то есть указывает на то, что переменной не задано значений, или объект отсутствует).
How do I write a backslash (\) in a string?
I want to write something like this C:\Users\UserName\Documents\Tasks in a textbox :
I get the error:
How do I write a backslash in a string?
![]()
6 Answers 6
The backslash ( "\" ) character is a special escape character used to indicate other special characters such as new lines ( \n ), tabs ( \t ), or quotation marks ( \" ).
If you want to include a backslash character itself, you need two backslashes or use the @ verbatim string:
Read the MSDN documentation/C# Specification which discusses the characters that are escaped using the backslash character and the use of the verbatim string literal.
Generally speaking, most C# .NET developers tend to favour using the @ verbatim strings when building file/folder paths since it saves them from having to write double backslashes all the time and they can directly copy/paste the path, so I would suggest that you get in the habit of doing the same.
Строки в C# и .NET
От переводчика: Джон Скит написал несколько статей о строках, и данная статья является первой, которую я решил перевести. Дальше планирую перевести статью о конкатенации строк, а потом — о Юникоде в .NET.
Тип System.String (в C# имеющий алиас string) является одним из наиболее часто используемых и важных типов в .NET, и вместе с тем одним из самых недопонимаемых. Эта статья описывает основы данного типа и развенчивает сложившиеся вокруг него мифы и непонимания.
Так что же такое string
Строка в .NET (далее — string, я не буду использовать полное имя System.String каждый раз) является последовательностью символов. Каждый символ является символом Юникода в диапазоне от U+0000 до U+FFFF (будет рассмотрено далее). Строковый тип имеет следующие характеристики:
Строка является ссылочным типом
Существует распространённое заблуждение о том, что строка является значимым типом. Это заблуждение истекает из свойства неизменяемости строки (см. следующий пункт), так как для неискушенного программиста неизменяемость часто по поведению кажется схожей со значимыми типами. Тем не менее, string — ссылочный тип, со всеми присущими ссылочным типам характеристиками. Я более детально расписал о различиях между ссылочными и значимыми типами в своих статьях «Parameter passing in C#» и «Memory in .NET — what goes where».
Строка является неизменяемой
Никак невозможно изменить содержимое созданной строки, по крайней мере в безопасном (safe) коде и без рефлексии. Поэтому вы при изменении строк изменяете не сами строки, а значения переменных, указывающих на строки. Например, код s = s.Replace («foo», «bar»); не изменяет содержимое строки s, которое было до вызова метода Replace — он просто переназначает переменную s на новообразованную строку, которая является копией старой за исключением всех подстрок «foo», заменённых на «bar».
Строка может содержать значение null
В языке C строки являются последовательностями символов, оканчивающимися символом ‘\0‘, также называемым «nul» или «null». Я называю его «null», так как именно такое название имеет символ ‘\0’ в таблице символов Юникода. Не путайте символ «null» с ключевым словом null в C# — тип System.Char является значимым, а потому не может принимать значение null . В .NET строки могут содержать символ «null» в любом месте и работать с ним без каких-либо проблем. Тем не менее, некоторые классы (к примеру, в Windows Forms) могут расценивать «null»-символ в строке как признак конца строки и не учитывать всё содержимое строки после этого символа, поэтому использование «null»-символов таки может стать проблемой.
Строка переопределяет оператор равенства ==
При вызове оператора == для определения равенства двух строк происходит вызов метода Equals , который сравнивает именно содержимое строк, а не равенство ссылок. К примеру, выражение «hello».Substring(0, 4)==»hell» возвратит true , хотя ссылки на строки по обеих сторонах оператора равенства разные (две ссылки ссылаются на два разных строковых экземпляра, которые, при этом, содержат одинаковые значения). Вместе с тем необходимо помнить, что равенство значений, а не ссылок происходит только тогда, когда оба операнда на момент компиляции являются строго строковым типом — оператор равенства не поддерживает полиморфизм. Поэтому если хотя бы один из сравниваемых операндов будет иметь тип object , к примеру (хотя внутренне и будет оставаться строкой), то будет выполнено сравнение ссылок, а не содержимого строк.
Интернирование
В .NET существует понятие «пула интернирования» (intern pool). По своей сути это всего лишь набор строк, но он обеспечивает то, что когда вы в разных местах программы используете разные строки с одним и тем же содержимым, то это содержимое будет храниться лишь один раз, а не создаваться каждый раз по-новому. Вероятно, пул интернирования зависит от конкретного языка, однако он определённо существует в C# и VB.NET, и я бы был очень удивлён, увидев язык на платформе .NET, не использующий пул интернирования; в MSIL пул интернирования очень просто использовать, гораздо проще, нежели не использовать. Наряду с автоматическим интернированием строковых литералов, строки можно интернировать вручную при помощи метода Intern , а также проверять, является ли та или иная строка уже интернированной при помощи метода IsInterned . Метод IsInterned не интуитивен, так как вы ожидаете, что он возвратит Boolean , а вот и нет — если текущая строка уже существует в пуле интернирования, то метод возвратит ссылку на неё, а если не существует, то null . Подобно ему, метод Intern возвращает ссылку на интернированную строку, причём вне зависимости от того, была ли текущая строка в пуле интернирования до вызова метода, или же она была туда занесена вместе с вызовом метода, или же пул интернирования содержит копию текущей строки.
Литералы
- \’ — одинарная кавычка, используется для объявления литералов типа System.Char
- \» — двойная кавычка, используется для объявления строковых литералов
- \\ — обратный слеш
- \0 — null-символ в Юникоде
- \a — символ Alert (№7)
- \b — символ Backspace (№8)
- \f —смена страницы FORM FEED (№12)
- \n — перевод строки (№10)
- \r — возврат каретки (№13)
- \t — горизонтальная табуляция (№9)
- \v — вертикальная табуляция (№11)
- Uxxxx — символ Юникода с шестнадцатеричным кодом xxxx
- \xn[n][n][n] — символ Юникода с шестнадцатеричным кодом nnnn, версия предыдущего пункта с переменной длиной цифр кода
- \Uxxxxxxxx — символ Юникода с шестнадцатеричным кодом xxxxxxxx, используется для вызова суррогатных пар.
Строки и отладчик
Довольно часто при просмотре строк в отладчике (используя VS.NET 2002 и VS.NET 2003) люди сталкиваются с проблемами. Ирония в том, что эти проблемы чаще всего создаёт отладчик, пытаясь быть полезным. Иногда он отображает строку в виде стандартного литерала, экранируя обратными слешами все спецсимволы, а иногда он отображает строку в виде дословного литерала, оглавляя её @. Поэтому многие спрашивают, как удалить из строки @, хотя его там фактически нет. Кроме этого, отладчики в некоторых версиях VS.NET не отображают строки с момента первого вхождения null-символа \0, и что ещё хуже, неправильно вычисляют их длины, так как подсчитывают их самостоятельно вместо запроса к управляемому коду. Естественно, всё это из-за того, что отладчики рассматривают \0 как признак окончания строки.
Учитывая такую путаницу, я пришел к выводу, что при отладке подозрительных строк их следует рассматривать множеством способов, дабы исключить все недоразумения. Я предлагаю использовать приведённый ниже метод, который будет печатать содержимое строки в консоль «правильным» способом. В зависимости от того, какое приложение вы разрабатываете, вы можете вместо вывода в консоль записывать строки в лог-файл, отправлять в трассировщики, выводит в модальном Windows-окне и т.д.
Использование памяти и внутренняя структура
В текущей реализации .NET Framework каждая строка занимает 20+(n/2)×4 байт, где n — количество символов в строке или, что одно и то же, её длина. Строковый тип необычен тем, что его фактический размер в байтах изменяется им самим. Насколько я знаю, так могут делать только массивы. По факту, строка — это и есть массив символов, расположенный в памяти, а также число, обозначающее фактический размер массива в памяти, а также число, обозначающее фактическое количество символов в массиве. Как вы уже поняли, длина массива не обязательно равна длине строки, так как строки могут перераспределяться со стороны mscorlib.dll для облегчения их обработки. Так само делает, к примеру, StringBuilder . И хотя для внешнего мира строки неизменяемые, внутри mscorlib они ещё как изменяемые. Таким образом, StringBuilder при создании строки выделяет несколько больший символьный массив, нежели того требует текущий литерал, а потом прибавляет новые символы в созданный массив до тех пор, пока они «влезают». Как только массив заполняется, создаётся новый, ещё больший массив, и в него копируется содержимое из старого. Кроме этого, в числе, обозначающем длину строки, первый бит отведён под специальный флаг, определяющий, содержит ли строка не-ASCII символы или нет. Благодаря этому флагу исполняющая среда в некоторых случаях может проводить дополнительные оптимизации.
Хотя со стороны API строки не являются null-терминированными, внутренне символьные массивы, представляющие строки, являются. А это значит, что строки из .NET могут напрямую передаваться в неуправляемый код безо всякого копирования, предполагая, что при таком взаимодействии строки будут маршаллированы как Юникод.
Кодировки строк
Если вы не знакомы с кодировками символов и Юникодом, пожалуйста, прочтите сначала мою статью о Юникоде (или её перевод на Хабре).
Как я уже сказал вначале статьи, строки всегда хранятся в Юникод-кодировке. Всякие домыслы о Big-5-кодировках или UTF-8-кодировках являются ошибкой (по крайней мере, по отношению к .NET) и являются следствием незнания самих кодировок или того, как .NET обрабатывает строки. Очень важно понять этот момент — рассматривание строки как такой, которая содержит некий валидный текст в кодировке, отличной от Юникода, почти всегда является ошибкой.
Далее, набор символов, поддерживаемых Юникодом (одним из недостатков Юникода является то, что один термин используется для разных вещей, включая кодировки и схемы кодировок символов), превышает 65536 символов. А это значит, что один char (System.Char) не может содержать любой символ Юникода. А это приводит к понятию суррогатных пар, где символы с кодом выше U+FFFF представляются в виде двух символов. По сути, строки в .NET используют кодировку UTF-16. Возможно, большинству разработчиков и не нужно углубляться касательно этого в детали, но по крайней мере это стоит знать.
Региональные и интернациональные странности
Некоторые странности в Юникоде ведут к странностям при работе со строками и символами. Большинство строковых методов зависимы от региональных настроек (являются culture-sensitive — регионально-чувствительными), — другими словами, работа методов зависит от региональных настроек потока, в котором эти методы выполняются. Например, как вы думаете, что возвратит этот метод «i».toUpper() ? Большинство скажут: «I», а вот и нет! Для турецких региональных настроек метод вернёт «İ» (код U+0130, описание символа: «Latin capital I with dot above»). Для выполнения регионально-независимой смены регистра вы можете использовать свойство CultureInfo.InvariantCulture и передать его как параметр в перегруженную версию метода String.ToUpper , которая принимает CultureInfo .
Есть и другие странности, связанные со сравнением и сортировкой строк, а также с нахождением индекса подстроки в строке. Некоторые из этих операций регионально-зависимы, а некоторые — нет. Например, для всех регионов (насколько я могу видеть) литералы «lassen» и «la\u00dfen» (во втором литерале шестнадцатеричным кодом указан символ «S острое» или «эсце́т») определяются как равные при передачи их в методы CompareTo или Compare , но вот если передать их в Equals , то будет определено неравенство. Метод IndexOf будет учитывать эсцет как «ss» (двойное «s»), но вот если вы используете одну из перегрузок CompareInfo.IndexOf , где укажете CompareOptions.Ordinal , то эсцет будет обработан правильно.
Некоторые символы Юникода вообще абсолютно невидимы для стандартного метода IndexOf . Однажды кто-то спросил в группе новостей C#, почему метод поиска и замены уходит в бесконечный цикл. Этот человек использовал метод Replace для замены всех сдвоенных пробелов одним, а потом проверял, окончилась ли замена и нет ли больше сдвоенных пробелов в строке, используя IndexOf . Если IndexOf показывал, что сдвоенные пробелы есть, строка снова отправлялась на обработку к Replace . К сожалению, всё это «ломалось», так как в строке присутствовал некий «неправильный» символ, расположенный точно между двумя пробелами. IndexOf сообщал о присутствии сдвоенного пробела, игнорируя этот символ, а Replace не выполнял замену, так как «видел» символ. Я так и не узнал, что это был за символ, но подобная ситуация легко воспроизводится при помощи символа U+200C, который является «не-связующим символом нулевой ширины» (англ. zero-width non-joiner character), что бы это не значило, чёрт возьми! Поместите такой или ему подобный в вашу строку, и IndexOf будет его игнорировать, а Replace — нет. Снова-таки, чтобы заставить оба метода работать одинаково, вы можете использовать CompareInfo.IndexOf и указать ему CompareOptions.Ordinal . Мне кажется, что уже написано достаточно много кода, который будет «валиться» на таких «неудобных» данных. И я даже не намекаю, что мой собственный код застрахован от подобного.
Microsoft опубликовала некоторые рекомендации касательно обработки строк, и хотя они датируются 2005-м годом, их всё ещё сто́ит прочесть.
Строки. Средства работы со строками
Строка в C# — это массив знаков, объявленный с помощью ключевого слова string. Строковый литерал объявляется с помощью кавычек, как показано в следующем примере.
string s = «Hello, World!»;
Переприсваивание
Строки можно целиком переприсваивать:
string s1 = «Hello»;
string s2 = s1; //переприсваиваем
Объединение строк
Можно объединять строки с помощью оператора +, как показано в следующем примере:
string s1 = «orange»;
Console.WriteLine(s1); // напечатается «orangered»
Escape-знаки
Строки могут содержать escape-знаки, такие как «\n» (новая строка) и «\t» (табуляция). Пример:
string hello = «Hello\nWorld!»;
string s = «чтобы вставить \»кавычки\» в строку используем обратный слэш»;
Если требуется добавить в строку обратную косую черту, перед ней нужно поставить еще одну обратную косую черту. Следующая строка:
string filePath = «\\\\My Documents\\»;
Точные строки: символ @
Символ @ служит для того, чтобы конструктор строк пропускал escape-знаки и переносы строки. Следующие две строки являются идентичными:
string p1 = «\\\\My Documents\\My Files\\»;
string p2 = @»\\My Documents\My Files\»;
Чтобы поставить в точной строке знак двойных кавычек, нужно использовать по два таких знака, как показано в следующем примере:
string s = @»You say «»goodbye»» and I say «»hello»»»;
Доступ к отдельным знакам
Квадратные скобки [] служат для доступа к отдельным знакам в объекте string, но при этом возможен доступ только для чтения:
string str = «test»;
char x = str[2]; // x = ‘s’;
string s5 = «Printing backwards»;
for (int i = 0; i < s5.Length; i++)
Console.Write(s5[s5.Length — i — 1]);
// напечатается «sdrawkcab gnitnirP»
Извлечение подстрок
Для извлечения подстроки из строки используется метод Substring.
string s3 = «Visual C# Express»;
string s4 = s3.Substring(7, 2);
Замена по образцу
Для замены подстроки в строке по образцу используется метод Replace.
string s3 = «Visual C# Express»;
string s5 = s3.Replace(«C#», «Basic»);
// напечатается «Visual Basic Express»
Смена регистра
Чтобы изменить регистр букв в строке (сделать их заглавными или строчными) следует использовать ToUpper() или ToLower(), как показано в следующем примере:
string s6 = «АлтГТУ»;
Сравнения
Самый простой способ сравнения двух строк — использовать операторы == и !=, осуществляющие сравнение с учетом регистра:
string color1 = «red»;
string color2 = «green»;
string color3 = «red»;
if (color1 == color3)
if (color1 != color2)
Console.WriteLine(«Строки не равны»);
Не допускается использование >,<,>=,<= для сравнения строк. Для строковых объектов существует метод CompareTo(), возвращающий целочисленное значение, зависящее от того, что одна строка может быть меньше (<), равна (==) или больше другой (>). При сравнении строк используется значение Юникода, при этом значение строчных букв меньше, чем значение заглавных. Дополнительные сведения о правилах сравнения строк см. в разделах CompareTo().
string string1 = «ИИТ»;
string string2 = «Иит»;
int result = string1.CompareTo(string2);
Console.WriteLine(» <0>больше чем <1>«, string1, string2);
else if (result == 0)
Console.WriteLine(» <0>равно <1>«, string1, string2);
else if (result < 0)
Console.WriteLine(» <0>меньше чем <1>«, string1, string2);
// Напечатается ИИТ больше чем Иит
Удаление фрагментов и вставка строк в строки
Может быть выполнена с помощью методов Remove и Insert:
string x = «ZX Spectrum»;
Пустые строки
Пустая строка — это экземпляр объекта String, содержащий 0 знаков. Пустые строки часто используются в различных сценариях программирования, представляя пустое текстовое поле. Для пустых строк можно вызывать методы, потому что такие строки являются допустимыми объектами String. Пустые строки инициализируются следующим образом:
Массивы из строк
Могут быть инициализированы начальными значениями:
//напечатается Алтайский край
Разбиение строк
Следующий пример кода демонстрирует возможность разбора строки при помощи метода String.Split. Работа метода заключается в возврате массива строк, в котором каждый элемент представляет слово. В качестве ввода Split принимает массив символов, определяющих какие символы должны использоваться в качестве разделителей. В этом примере используются пробелы, запятые, точки, двоеточия и табуляция. Массив, содержащий эти разделители, передается в Split, и каждое слово в предложении выводится отдельно при помощи результирующего массива строк.
Пример: разбить предложение на слова
string text = «Шла Саша по шоссе и сосала сушку»;
Console.WriteLine(«Исходный текст: ‘<0>‘», text);
string[] words = text.Split(razdelitel);
Console.WriteLine(» <0>слов в тексте:», words.Length);
foreach (string s in words)
Рисунок 1 — Пример выполнения
В качестве разделителя может выступать массив символов.
string text = «one\ttwo three:four,five six seven»;
Console.WriteLine(«Original text: ‘<0>‘», text);
string[] words = text.Split(delimiterChars);
Console.WriteLine(» <0>words in text:», words.Length);
foreach (string s in words)
Рисунок 2 — Пример выполнения
Пример: Ввести текстовую строку. Напечатать слова, в которых первая буква встречается еще хотя бы раз.
foreach (string word in words)
bool flag = false;
while (i < word.Length & !flag)
if (word[i] == c) flag = true;
if (flag) Console.WriteLine(word);
Рисунок 3 — Пример выполнения
Преобразование строк в другие типы
С помощью объекта Convert:
С помощью метода Parse:
Задачи на обработку строк . Условие вида «дана строка» означает, что пользователем вводится строка с клавиатуры. Осуществить ввод необходимых данных, выполнить реализацию алгоритма, обеспечить вывод полученных результатов. Не допускается использование операторов, прерывающих ход программы (break, goto). Ввод строк, обработка и вывод результатов реализуется отдельными методами .
1 Даны строки S и S0. Проверить, содержится ли строка S0 в строке S. Не использовать стандартные средства для поиска подстрок.
2 Даны строки S и S0. Найти количество вхождений строки S0 в строку S. Не использовать стандартные средства для поиска подстрок.
3 Дана строка S. Разделить строку на отдельные слова не используя стандартные средства для разбиения строк.
4 Дана строка S. Из строки требуется удалить текст, заключенный в фигурные скобки. В строке может быть несколько фрагментов, заключённых в фигурные скобки. Возможно использование вложенных фигурных скобок и, следовательно необходимо, чтобы программа это учитывала.
5 Дана строка S. Найти количество различных букв в ней. Программа должна работать без учёта регистра букв.
6 Дана строка S. Найти количество различных слов в ней. Программа должна работать без учёта регистра букв.
7 Дана строка S. Определить есть ли в строке удвоенные буквы (пара соседствующих одинаковых букв), напечатать слова, содержащие их.
8 Дана строка S (предложение). Найти самое длинное слово в строке не используя стандартные средства для разбиения строк.
9 Дана строка S (предложение). Составить программу, определяющую является ли текст перевёртышем без учёта пробелов.
10 Дана строка. Вывести все слова, у которых первая и последняя буквы одинаковые не используя стандартные средства для разбиения строк.