Перш за все, відповімо на питання, чи задає масив символів C # рядок С, що закінчується нулем? Відповідь: ні, не задає. Масив char [] - це звичайний масив. Більш того, його можна форматувати рядком символів, як це дозволяється в С ++. Константа, що задає рядок символів, належить класу String, а в C # не визначені взаємні перетворення між класами String і Char [], навіть явні. У класу String є, правда, динамічний метод ToCharArray, що задає подібне перетворення. Можливо також посимвольний передати вміст змінної string в масив символів. Наведу приклад:
public void TestCharArAndString ()
// char [] strM1 = "Hello, World!";
// помилка: немає перетворення класу string в клас char []
string hello = "Здрастуй, світ!";
char [] strM1 = hello.ToCharArray ();
char [] World = new char [3];
У нашому прикладі частина рядка strM1 копіюється в масив World. По ходу справи в методі викликається процедура PrintCharAr класу Testing, друкуюча масив символів як рядок. Ось її текст:
void PrintCharAr (string name, char [] ar)
for (int i = 0; i Метод ToCharArray дозволяє перетворити рядок в масив символів. На жаль, зворотна операція не визначена, оскільки метод ToString, яким, звичайно ж, мають всі об'єкти класу Char [], друкує інформацію про клас, а не вміст масиву. Ситуацію легко виправити, написавши відповідну процедуру. Ось текст цієї процедури CharArrayToString, спричиненої в нашому якому тестують прикладі: string CharArrayToString (char [] ar) for (int i = 0; i Клас Char [], як і всякий клас-масив в C #, є спадкоємцем не тільки класу Object, а й класу Array, і, отже, має всі методами батьківських класів, детально розглянутих в попередньому розділі. А чи є у нього специфічні методи, які дозволяють виконувати операції над рядками, int IndexOfStr (char [] s1, char [] s2) // повертає індекс першого входження підрядка s2 в int i = 0, j = 0, n = s1.Length-s2.Length; bool found = false; while ((i<=n) && !found) Console.WriteLine ( "Індекс першого входження око в У цій процедурі спочатку використовуються стандартні методи класу Array для визначення індексів входження символу в рядок, а потім створений метод IndexOfStr для визначення індексу першого входження підрядка. Коректність роботи методу перевіряється на різних рядках. Ось результати її роботи. Мал. 13.3. Індекси входження підрядка в рядок Чи існує в C # тип char * У мові C # покажчики допускаються в блоках, позначених небезпечні. Теоретично в таких блоках можна оголосити змінну типу Char *, але все одно не вдасться написати настільки ж коротку, як в С ++, процедуру копіювання рядків. Правильно вважати, що в C # рядки типу char * використовувати не рекомендується. 14. Лекція: Рядки C #. Класи String і StringBuilder У попередній лекції ми говорили про символьному типі char і рядках постійної довжини, що задаються масивом символів. Основним типом при роботі з рядками є тип string, що задає рядки змінної довжини. Клас String в мові C # відноситься до посилальним типам. Над рядками - об'єктами цього класу - визначено широкий набір операцій, що відповідає сучасному уявленню про те, як повинен бути влаштований строковий тип. • символу, повтореного заданий число раз; • масиву символів 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 =; sssss =; stryes =;" + "Strye =", world, sssss, stryes, strye); Об'єкт world створений без явного виклику конструктора, а об'єкти sssss, stryes, strye створені різними конструкторами класу String. Операції над рядками Над рядками визначені наступні операції: • дві операції перевірки еквівалентності (= =) і (! =); • конкатенація або зчеплення рядків (+); На відміну від інших довідкових типів операції, перевіряючі еквівалентність, порівнюють значення рядків, а не посилання. Ці операції виконуються як над значущими типами. Бінарна операція "+" зв'язує два рядки, приписуючи другий рядок до хвоста першої. Можливість взяття індексу при роботі з рядками відображає той приємний факт, що рядок можна розглядати як масив і отримувати без праці кожен її символ. Кожен символ рядка має тип char, доступний тільки для читання, але не для запису. Ось приклад, в якому над рядками виконуються дані операції: public void TestOpers () // операції над рядками string s1 = "ABC", s2 = "CDE"; string s3 = s1 + s2; char ch1 = s1 [0], ch2 = s2 [0]; Console.WriteLine ( "s1 =, s2 =, b1 =," + "Ch1 =, ch2 =", s1, s2, b1, ch1, ch2); Console.WriteLine ( "s1 =, s2 =, b1 =," + "Ch1 =, ch2 =", s1, s2, b1, ch1, ch2); Без констант не обійтися. У C # існують два види строкових констант: • звичайні константи, які представляють рядок символів, укладену в лапки; • @ -константи, задані звичайною константою c попереднім знаком @. У звичайних константи деякі символи інтерпретуються особливим чином. Пов'язано це насамперед з тим, що необхідно вміти ставити в рядку недруковані символи, такі, як, наприклад, символ табуляції. Виникає необхідність ставити символи їх кодом - у вигляді escape-послідовностей. Для всіх цих цілей використовується комбінація символів, що починається символом "" - зворотна коса риса. Так, пари символів: "\ n", "\ t", "", "" "задають відповідно символ переходу на новий рядок, символ табуляції, сам символ зворотної косої межі, символ лапки, що вставляється в рядок, але не сигналізує про її закінчення. Комбінація "\ xNNNN" задає символ, який визначається шістнадцятковим кодом NNNN. Хоча таке рішення виникаючих проблем цілком природно, іноді виникають незручності: наприклад, при завданні констант, що визначають шлях до файлу, доводиться кожен раз подвоювати символ зворотної косої межі. Це одна з причин, по якій з'явилися @ -конст анти. В @ -константи все символи трактуються в повній відповідності з їх зображенням. Тому шлях до файлу краще ставити @ константа. Єдина проблема в таких випадках: як поставити символ лапки, щоб він не сприймався як кінець самої константи. Рішенням є подвоєння символу. Ось відповідні приклади: // Два види констант Console.WriteLine ( "s1 =, s2 =, b1 =", s1, s2, b1); Console.WriteLine ( "s1 =, s2 =, b1 =", s1, s2, b1); Console.WriteLine ( "s1 =, s2 =, b1 =", s1, s2, b1); Погляньте на результати роботи наведених фрагментів коду, отримані при виклику процедур TestDeclStrings і TestOpers. Незмінний клас string У мові C # існує поняття незмінний (immutable) клас. Для такого класу неможливо змінити значення об'єкта при виклику його методів. Динамічні методи можуть створювати новий об'єкт, але не можуть змінити значення існуючого об'єкта. s1 = "Zenon"; ch1 = s1 [0]; Статичні властивості і методи класу String Таблиця 14.1. Статичні методи і властивості класу String s = string.Format (ci, "Разом:", 77.77); Мал. 14.2. Результати роботи методу Format Методи Join і Split Методи Join і Split виконують над рядком тексту взаємно зворотні перетворення. Динамічний метод Split дозволяє здійснити аналіз тексту на елементи. Статичний метод Join виконує зворотну операцію, збираючи рядок з елементів. Заданий рядком текст часто являє собою сукупність структурованих елементів - абзаців, пропозицій, слів, дужкових виразів і т.д. При роботі з таким текстом необхідно розділити його на елементи, користуючись спеціальними роздільниками елементів, - це можуть бути прогалини, дужки, знаки пунктуації. Практично подібні завдання виникають постійно при роботі зі структурованими текстами. Методи Split і Join полегшують рішення цих задач. Динамічний метод Split, як зазвичай, перевантажений. Найбільш часто використовувана реалізація має наступний синтаксис: public string [] Split (params char []) На вхід методу Split передається один або кілька символів, інтерпретованих як роздільники. Об'єкт string, що викликав метод, розділяється на підрядка, обмежені цими роздільниками. З цих подстрок створюється масив, що повертається в якості результату методу. Інша реалізація дозволяє обмежити число елементів, що повертається масиву. Синтаксис статичного методу Join такий: public static string Join (string delimiters, string [] items) Як результат метод повертає рядок, отриману конкатенацией елементів масиву items, між якими вставляється рядок роздільників delimiters. Як правило, рядок delimiters складається з одного символу, який і розділяє в результуючому рядку елементи масиву items; але в окремих випадках обмежувачем може бути рядок з декількох символів. Розглянемо приклади застосування цих методів. У першому з них рядок являє складнопідрядне речення, яке розбивається на прості речення. У другому пропозицію розділяється на слова. Потім проводиться зворотна зборка розібраного тексту. Ось код відповідної процедури: public void TestSplitAndJoin () string txt = "А це пшениця, яка в темній комірці зберігається, "+" в будинку, який побудував Джек! "; Console.WriteLine ( "Поділ тексту на прості речення:"); string [] SimpleSentences, Words; // розмірність масивів SimpleSentences і Words // встановлюється автоматично відповідно до // розмірністю масиву, що повертається методом SplitСхожі статті