Урок 11. Строки

Лабораторные работы си шарп и задания по теме «Язык программирования c sharp: работа со строками»

Теория

Символы и строки

  • Символ заключается в одинарные кавычки:
  • Console.WriteLine('A');
  • Можно использовать переменную типа char для хранения символьных данных:
  • char symb = 'A'; 
    Console.WriteLine(symb);
  • Строка — это объект типа String, значением которого является текст. Внутренне строка хранится в виде последовательности объектов типа Char, доступной только для чтения.
  • Строка заключается в двойные кавычки:
  • Console.WriteLine("Добрый день");
  • Можно использовать переменную типа string для хранения текстовых данных:
  • string phrase = "Добрый день"; 
    Console.WriteLine(phrase);  // Добрый день
    Console.WriteLine(phrase[1]); // o

Объявление и инициализация строк

    Рассмотрим несколько способов:

    Объявление без инициализации:

    string str1;

    Инициализация значением null:

    string str2 = null;

    Инициализация пустым значением:

    string str3 = "";

    Или лучше использовать константу Empty (с англ. «пустой») вместо значения "":

    string str3 = System.String.Empty;

    // Инициализировать обычным строковым литералом:

    string str4= "Microsoft Visual Studio";

    Инициализировать с помощью дословным строковым литералом (использование @):

    string str5= @"Microsoft Visual Studio";

    Или можно использовать System.String:

    System.String greeting = "Привет мир!";

    Для локальных переменных (т.е. в теле метода/функции) вы можете использовать неявную типизацию (var):

    var temp = "I'm Ok";

    Используйте строковую константу, в случае, если значение не нужно менять:

    const string str6 = "У меня всё хорошо!";

    Использование строкового конструктора только в том случае, когда строка формируется из символов (char[]), или sbyte:

    char[] letters = { 'A', 'B', 'C' };
    string alphabet = new string(letters);
    Console.WriteLine(alphabet); // ABC

    Изменение строк

    • Конкатенация — слияние (склеивание) строк.
    • Для конкатенации используется оператор += :
    • string s1 = "Строка - это больше, чем просто ";
      string s2 = "набор символов.";
       
      // Конкатенация s1 и s2. После чего создается
      // основная объединенная строка s1:
      s1 += s2;
       
      System.Console.WriteLine(s1);
      // Вывод: Строка - это больше, чем просто набор символов..
    • Если вы создадите ссылку на строку (присвоите одну строку другой строке), а затем измените значение исходной строки, то ссылка будет продолжать указывать на исходный объект вместо нового объекта, который был создан при изменении строки:
    • string s1 = "Hello ";
      string s2 = s1; // ссылка на строку s1
      s1 += "World";
       
      System.Console.WriteLine(s2);
      //Вывод: Hello

    Наиболее распространенные Escape-символы в строках
    Дословные строки

    Escape-символы — это специальные символы, которые используются в строке c#.

    • Escape-символы в C#:
    • // Клавиша Tab (табулярный отступ)
      string columns = "Column 1\tColumn 2\tColumn 3";
      //Вывод: Column 1        Column 2        Column 3
       
      // Новая строка
      string rows = "Row 1\r\nRow 2\r\nRow 3";
      /* Вывод:
        Row 1
        Row 2
        Row 3
      */
       
      //если мы хотим использовать кавычки, мы используем обратную косую черту перед ней:
      Console.WriteLine("Я читаю букву \"Я\" в тексте"); // Я читаю букву "Я" в тексте
       
      string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
      //Вывод: "The Æolean Harp", by Samuel Taylor Coleridge
    • В c# есть своего рода строка, которая называется дословная строка. В дословной строке не нужно использовать двойную обратную косую черту (слэш), когда она, казалось бы, необходима. Перед строкой достаточно установить знак @.
    • В каких случаях необходимо использовать дословные строки:
    • когда строка содержит символы обратной косой черты;
    • для инициализации многострочных строк;
    • когда у нас есть кавычки внутри строки.
    • string filePath = @"C:\Users\scoleridge\Documents\";
      //Вывод: C:\Users\scoleridge\Documents\
       
      string text = @"My pensive SARA ! thy soft cheek reclined
          Thus on my arm, most soothing sweet it is
          To sit beside our Cot,...";
      /* Вывод:
      My pensive SARA ! thy soft cheek reclined
         Thus on my arm, most soothing sweet it is
         To sit beside our Cot,... 
      */
       
      string quote = @"Ее зовут ""Катя.""";
      //Вывод: Ее зовут "Катя."

    Методы Substring, Replace и indexOf строкового типа

    • В c# существует множество стандартных методов внутри типа string. Если поставить точку после переменной, то подсказка Visual Studio выдаст список ко всем методам:
    • variable. ... 
      
    • Подстрока — это любая последовательность символов, содержащаяся в строке:
    • string str = "Visual C# обучение";
       
      Console.WriteLine(str.Substring(7, 2));
      // Вывод: "C#"
       
      Console.WriteLine(str.Replace("C#", "C++"));
      // Вывод: "Visual C++ обучение"
       
      // Индекс определенного символа в строке:
      // Индексы начинаются с нуля
      int index = str.IndexOf("C"); // Вывод: 7
       
      // поиск конкретного символа в строке: 
      Console.WriteLine(str.IndexOf ('z')); // Вывод: -1
    • Также имеются методы:
    • преобразование к верхнему регистру:
    • Console.WriteLine(phrase.ToUpper());
    • поиск подстроки в строке:
    • Console.WriteLine(phrase.Contains("z")); // Вывод: False

    Преобразование строки в массив: разделение строк

    • Следующий пример кода демонстрирует возможность синтаксического анализа строки с использованием строки .String.Split. Метод работает возвращает массив строк, в котором каждый элемент представляет собой слово. Метод Split принимает в качестве одного из параметров массив строк, тогда как другой параметр — символ, который следует использовать в качестве разделителя между словами. В этом примере используются пробелы, запятые, точки, двоеточия и символы табуляции. Массив и разделитель передаются методу Split, и каждое слово в предложении выводится отдельно с использованием результирующего массива строк.
    • char delimiter = ' ';
      string text = "Как твои дела?";
      Console.WriteLine($"Исходный текст: '{text}'" );
      string[] words = text.Split(delimiter);
      Console.WriteLine($"слова в тексте:{words.Length} ");
      foreach (string s in words)
           Console.WriteLine(s);

      Результат:

      Исходный текст: 'Как твои дела?'
      слова в тексте:4
      Как 
      твои 
      дела?
      
    • В качестве разделителя можно использовать массив символов:
    • char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
      string text = "one\ttwo three:four,five six seven";
      Console.WriteLine($"Исходный текст: '{text}'" );
      string[] words = text.Split(delimiterChars);
      Console.WriteLine($"слова в тексте:{words.Length} ");
      foreach (string s in words)
           Console.WriteLine(s);

      Результат:

      Исходный текст: 'one      two three:four,five six seven'
      слова в тексте:7
      one
      two
      three
      four
      five
      six
      seven

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

      string s = "wow,this is google";
      string[] words = s.Split(' ', '.', ',');
      foreach (string word in words)
       {
          char c = word[0];
          bool flag = false;
          int i = 1;
          while (i < word.Length & !flag)
                      {
                          if (word[i] == c) flag = true;
                          i++;
                      }
          if (flag) Console.WriteLine(word);
       }
      Console.ReadKey();

    Доступ к символам строки

    • Строка состоит из символов. Чтобы получить доступ только для чтения к отдельным символам внутри строки и вывести их, можно обратиться к символу строки по его индексу (начинается с 0):
    • s[i] – для доступа к i-му символу строки s
    • s.Length – длина строки (кол-во символов в строке)
    • Использование цикла for:

      var s = "Computer";
      for (var i=0; i < s.Length; i++)
           Console.Write($"{s[i]} "); // Вывод:  C o m p u t e r

      Использование цикла foreach:

      var s = "Computer";
      foreach (var c in s)
         Console.Write($"{c} "); //  Вывод: C o m p u t e r

    Изменение конкретного символа в строке

    • Строки в C# неизменяемы, это означает, что мы не можем использовать следующий код (ошибка!): s[i]='a';
    • Символы обрамляются одинарными кавычками.
    • 1. Использование метода Substring строкового типа:
    • Чтобы изменить конкретный символ в строке можно использовать метод Substring:
    • var str = "abcdefghijjklmnopqrstuvwxy"; 
      str = 'Z' + str.Substring(1);
      Console.WriteLine(str); // вывод: Zbcdefghijjklmnopqrstuvwxy
      string phrase = "Good Day";
      Console.WriteLine(phrase.Substring(5)); // Вывод: 'Day'
      Console.WriteLine(phrase.Substring(5,2)); // сколько символов мы собираемся взять. Вывод: 'Da'
      2. Использование класса StringBuilder
    • Можно использовать класс StringBuilder для изменения определенных символов:
    • using System.Text; // необходимо подключение этой директивы
      //...
      var str = "Group roxette";
      var sb = new StringBuilder(str);
      sb[6] = 'R';
      str = sb.ToString();
      Console.WriteLine(str); // Вывод: Group Roxette
    • Создание объекта класса StringBuilder:
    • // 1) Пустая строка:
      StringBuilder sb = new StringBuilder();
       
      // 2) Строка определенной длины:
      int n = 50;
      StringBuilder sb = new StringBuilder(n);
       
      // 3) Строка инициализированная значением:
      StringBuilder sb = new StringBuilder("qwerty");
    • Ввод и вывод значений:
    • // ReadLine() метод:
      StringBuilder sb = new StringBuilder(Console.ReadLine());
       
      // WriteLine() метод:
      Console.WriteLine(sb);
    • StringBuilder — это класс, представляющий изменяемую строку. Класс позволяет легко и быстро создавать строку и изменять ее на лету, но, в отличие от класса string, он не оптимизирован для поиска. То есть, в нем нет таких методов, как indexOf или lastIndexOf и т.д.
    • Однако класс StringBuilder предоставляет возможность использования некоторых других методов:
    • Append — добавление в конец строки;
    • Insert — вставка по индексу;
    • Remove — удаление из строки;
    • Replace — замена символа или строки.

Задания и лабораторные работы

Пример конкатенации:
string s1 = "первая строка";
string s2 = " вторая строка";
 
// Сохранение конкатенации s1 и s2 в переменной s3
string s3 = s1 + " " + s2;
 
System.Console.WriteLine(s3); // первая строка вторая строка
Пример использования метода Join:

Метод Join склеивает коллекцию элементов типа String, используя специальный разделитель между элементами. В примере разделителем является запятая:

string[] arr = new string[] { "как", "твои", "дела" };
string s = string.Join(",", arr);
Console.WriteLine($"result is: {s}"); //результат: как,твои,дела
Лабораторная работа 1. Использование операции конкатенация и дословных строк
  
Выполнить:
  
1) Объявите две переменные firstName и lastName строкового типа. Присвойте какие-либо значения этим переменным. Выведите значения переменных.
  
Примерный вывод:

Дарья
Кувшинкина

2) Объявите еще одну переменную строкового типа (fullName) и присвойте ей значение конкатенации (+) двух объявленных ранее строковых переменных с пробелом между ними. Выведите значения переменных в указанном формате:
 
Примерный вывод:

Имя = Дарья, фамилия = Кувшинкина
Полное имя:
Дарья Кувшинкина

  
3) Выведите предложение ‘Меня зовут fullName‘, используйте метод Format.
  
Примерный вывод:

Меня зовут Дарья Кувшинкина

 
4) Создайте массив строкового типа, добавьте три элемента массива — три имени. Выведите значения элементов массива, используя метод Join с запятой (,) в качестве разделителя между именами.
 
Примерный вывод:

Иван, Елена, Мария

  
5) Выведите приветственный текст и путь к файлу, используйте дословную строку.
  
Примерный вывод:

Привет, Иван
Посмотри на путь к файлам
c:\folder1\folder2
c:\folder3\folder4

 
[Название проекта: Lesson_11Lab1, название файла L11Lab1.cs]

✍ Алгоритм:

  • Создайте новый проект и измените название главного файла согласно заданию.
  • Задание #1:

  • Создайте переменную строкового типа, назовите ее firstName. Присвойте ей значение:
  • string firstName = "Дарья";
    
  • Выведите переменную в консоль, используя метод WriteLine.
  • При объявлении переменной можно использовать ключевое слово VAR вместо указания типа string, потому что компилятор ‘знает’, что переменной присвоено строковое значение, значит, и тип переменной будет строковым. Измените код:
  • var firstName="Дарья";  
    
  • Создайте еще одну переменную — lastName и присвойте ей значение. Выведите в консоль:
  • var lastName="Кувшинкина"; 
    Console.WriteLine(lastName);
    

      
    Задание #2:

  • Будем использовать конкатенацию слияния значений трех переменных (включая пробел в качестве разделителя между двумя значениями). Объявите и инициализируйте переменную для конкатенации трех строк:
  • // Задание 2
    var fullName = firstName + " " + lastName;
    
  • Выведите данные в консоль, как это просится в Примерном выводе.
  •  
    Задание #3:

  • Класс String содержит много статических стандартных методов. Они доступны непосредственно при использовании класса. Мы будем использовать метод format, чтобы вывести результат, как того требует задание:
  • // Задание 3
    var myFullName = string.Format("Меня зовут {0} {1}", firstName, lastName);
    Console.WriteLine(myFullName);
    
    Метод Format принимает два аргумента, первый — форматная строка с шаблоном, второй аргумент — перечисленные через запятую значения для шаблона.

      
    Задание #4:

  • Создайте массив строкового типа и выведите его значения, используя метод Join:
  • // Задание 4
    var names = new string[3] {"Иван", "Елена", "Мария"};
    var formattedNames = string.Join(",", names);
    Console.WriteLine(formattedNames);
    
    Метод Join объединяет коллекцию значений строкового типа, используя указанный разделитель между элементами коллекции. В нашем случае разделитель — запятая.

      
    Задание #5:

  • Необходимо создать текст из нескольких строк, включая два пути к файлам. Если бы мы не использовали возможность дословного строкового значения, то нам бы пришлось использовать следующий код:
  • // мы должны использовать \n чтобы перейти на новую строку, необходимо использовать \ для вывода символа '\'
    var text="Привет, Иван\nПосмотри на путь к файлам\nc:\\folder1\\folder2\nc:\\folder3\\folder4";
    
  • Такой код весьма нечитабельный. Теперь будем использовать дословную строку:
  • // Задание 5
    var text = @"Привет, Иван
    Посмотри на путь к файлам
    c:\folder1\folder2
    c:\folder3\folder4";
    Console.WriteLine(text);
    
    В качестве префикса мы использовали @, затем вместо \n мы просто использовали новые строки и удалили все двойные слэши.
  • Запустите приложение и посмотрите на результат.

Лабораторная работа 2. Методы строк

Выполнить: Инициализируйте одномерный массив строкового типа следующими значениями: Иван Иванов, Петр Сидоров, Михаил Никитин, Ирина Александрова. Выведите приветственные сообщения для всех имен из списка (без фамилий).
Выполните задание дважды: в первом случае используйте методы IndexOf и Substring, во втором случае — только метод Split.
 
Примерный вывод:

Использование IndexOf и Substring:
Привет, Иван!
Привет, Петр!
Привет, Михаил!
Привет, Ирина!

Использование Split:
Привет, Иван!
Привет, Петр!
Привет, Михаил!
Привет, Ирина!

[Название проекта: Lesson_11Lab2, название файла L11Lab2.cs]

✍ Алгоритм:

  • Создайте новый проект и переименуйте основной файл, как указанно в задании.
  • Создайте массив типа string и инициализируйте его указанными в задании полными именами:
  • string[] fullNames = new string[] { "Иван Иванов", "Петр Сидоров", "Михаил Никитин", "Ирина Александрова" };
    
  • Создайте еще один массив типа string для хранения только имен (без фамилий). При объявлении массива необходимо указать количество элементов, т.к. инициализация элементов массива значениями будет происходить позже.
  • string[] firstNames = new string[fullNames.Length];
    
    Количество элементов массива совпадает с количеством элементов массива fullNames. Необходимо использовать метод Length для получения количества элементов массива fullNames.
  • Для получения значений массива имен необходимо извлекать только имена из значений полных имен, т.е., например, «Петр» из «Петр Сидоров». Или, другими словами, отсекать все символы строки, начиная с 0, до первого встреченного символа пробела:
  • П е т р  С и д о р о в
    0 1 2 3 4  
    
  • Для поиска символа пробела будем использовать метод IndexOf method. Для прохода по элементам массива будем использовать цикл for:
  • for (var i = 0; i < fullNames.Length; i++) {
       var index = fullNames[i].IndexOf(' ');
       ...
    }
    
    Метод IndexOf ищет индекс (начиная с 0) первого встреченного символа Unicode или строки в указанном экземпляре объекта. Метотд возвращает значение -1, если символ или строка не найдены.
  • После этого индекс символа пробел будет сохранен в переменной index. Теперь необходимо использовать метод Substringдля извлечения имени и вывода его со словом ‘Привет, ‘:
  • for (var i = 0; i < fullNames.Length; i++) { 
        var index = fullNames[i].IndexOf(' ');
        firstNames[i] = fullNames[i].Substring(0, index);
        Console.WriteLine("Привет, " + firstNames[i]+"!");
    }
    
    Метод Substring возвращает подстроку из fullNames. Подстрока начинается с 0 (0 индекс) и имеет определенную длину (значение переменной index).
  • Запустите приложение и проверьте выходные данные.
  • Такой же результат необходимо получить, используя метод Split method. В функции Main введите следующий код после уже добавленного код function, after the previous code:
  • Console.WriteLine("Split method:");
        for (var i = 0; i < fullNames.Length; i++)
          {
            firstNames = fullNames[i].Split(' ');
            Console.WriteLine("Привет, " + firstNames[0]+"!");
          }
    
    Метод split возвращает массив слов (определяя их по пробелам). Так для ‘Петр Сидоров’ вернется firstNames[0] = ‘Петр’ и firstNames[1] = ‘Сидоров’.
    Метод Split создает массив подстрок, используя в качестве разделителя между подстроками определенный символ, пробел (' ') в нашем случае.
  • Запустите приложение еще раз.
  • Загрузите файл .cs.

Задание 1:

Выполнить: Запрашивается символ (переменная c). Переменная s строкового типа содержит ровно два символа c. Найдите подстроку между этими двумя символами. Используйте класс string (не StringBuilder).
   
Указание 1: Для решения задания лучше использовать методы Substring, IndexOf и LastIndexOf.

Указание 2: Создайте пользовательский метод BetweenChars с двумя аргументами — сама строка и символ. Вызовите метод дважды с разными значениями параметров.

Примерный вывод:

Результат для строки astra и символа a: str
Результат для строки nana и символа a: n

  
[Название проекта: Lesson_11Task1, Название файла L11Task1.cs]


Задание 2: С методами и без методов

Выполнить: Создайте программу для поиска символа s в строке. Выведите значение true, если символ s найден, и false — если не найден.
   
Указание 1: Выполните программу разными способами: 1) используя метод Contains и 2) используя проход по символам строки циклом for.
Указание 2: Возможно, вам пригодится логическая переменная:

bool b = false;

Указание 3: Для выхода из цикла можно использовать оператор break:

// когда i принимает значение 5, компилятор выходит из цикла:
for (int i = 1; i <= 100; i++)
        {
            if (i == 5)
            {
                break;
            }
            Console.WriteLine(i);
        }

  
Примерный вывод:

Результат 1: Строка 'hello' содержит s: False
Результат 2: Строка 'hello' содержит s: False
++++++++++++++
Результат 1: Строка 'hello sir' содержит s: True
Результат  2: Строка 'hello sir' содержит s: True

  
[Название проекта: Lesson_11Task2, название файла L11Task2.cs]


Задание 3:

Выполнить: Создайте программу подсчитывающую количество сочетаний букв «ma» в тексте. Не разрешается использовать стандартные методы, выполните программу, используя цикл для перебора символов в строке.
   
Указание 1: Создайте функцию CountInText с двумя параметрами: строка с текстом и строка с сочетанием букв, которое необходимо искать в тексте.

Примерный вывод:

Строка 'hello world' содержит 0 вхождений 'ma'
+++++++++++++++++++
Строка 'my mammy is the best, ma-ma-ma' содержит 4 вхождений 'ma'

  
[Название проекта: Lesson_11Task3, название файла L11Task3.cs]

Задание 4:

Выполнить: Вводится строка (переменная s). Удалите всё между первыми двумя символами ‘*‘. Если в cтроке нет таких символов, не меняйте ничего. Если в строке только один символ *, удалите всё до конца, начиная с этого символа. Используйте класс string (не StringBuilder).
   
Указание 1: Лучше использовать методы Contains, IndexOf и Remove. Метод IndexOf может принимать два параметра:

IndexOf(char value, int StartIndex)

Указание 2: Создайте метод RemoveBetweenChars с двумя параметрами, they are the строка и символ (для символа должно быть указано значение по умолчанию *). Вызовите метод дважды с разными параметрами.

Примерный вывод:

Результат для строки ast*qqra* и символа *: ast**
Результат для строки POW*EROFBULL и символа *: POW

  
[Solution and Project name: Lesson_11Task4, file name L11Task4.cs]

Лабораторная работа 3. Использование класса StringBuilder
  
Выполнить:  Инвертировать вводимую строку.

Примерный вывод:

Введите предложение:
Hello world
Инвертированное предложение:
dlrow olleH

 
[Название проект: Lesson_11Lab3, название файла L11Lab3.cs]

✍ Алгоритм:

  • Создайте новый проект и переименуйте главный файл.
  • Подключите указанную директиву для возможности использования класса StringBuilder:
  • using System.Text;
  • Выведите сообщение пользователю с запросом ввода строки:
  •  Console.WriteLine("Введите предложение:");
    
  • Создайте экземпляр объекта класса StringBuilder. Инициализируйте экземпляр введенным значением:
  • StringBuilder sb = new StringBuilder(Console.ReadLine());
    
  • Для инвертирования предложения мы собираемся использовать следующий алгоритм: берем первый символ строки и меняем его с последним, затем берем второй и меняем его с предпоследним и т.д. пока символы не встретятся в середине строки.
  • Используйте цикл for для прохода по символам строки. Нам пригодятся два счетчика для цикла for — один из них для прохода по символам строки, начиная с начала строки, второй — для прохода по символам, начиная с конца строки:
  • char c; // для временного хранения символа
    // счетчик i - для прохода с начала строки, j - с конца строки
    for (int i = 0, j = sb.Length - 1; i < j; i++, j--) 
       {
           ...
       }
    
  • В теле цикла необходимо обменивать c значения символов с начала строки со значением таковых с конца строки:
  • for (int i = 0, j = sb.Length - 1; i < j; i++, j--)
      {
         c = sb[i];
         sb[i] = sb[j];
         sb[j] = c;
       }
    
  • После выполнения цикла мы получим результат инвертированной строки в переменной sb. Выведите результат в консоль:
  • Console.WriteLine("инвертированная строка:");
    Console.WriteLine(sb);
    
  • Запустите приложение.
  • Добавьте комментарии и загрузите файл .cs на проверку.
Задание 5:

Выполнить: Даны две строки. Добавьте такое кол-во пробелов к той строке, которая короче, чтобы длина строк стала одинаковой. Используйте класс StringBuilder.
   
Указание 1: Для выполнения задания проще использовать метод Append.

Указание 2: Создайте метод AddSpaces с двумя аргументами - сама строка и кол-во пробелов, которые необходимо добавить.

Примерный вывод:

string1=1234.  string2=123456.
result: string1=1234  .  string2=123456.

  
[Название проекта: Lesson_11Task5, название файла L11Task5.cs]

Задание 6:

Выполнить: Дана строка S, состоящая из двух чисел, разделенных пробелом; и задан символ C, который может принимать одно из следующих значений: +, -, * (знак соответствующей математической операции). Создайте строку, содержащую результат выполнения операции C с числами из строки S, например '2+3=5'.

   
Указание 1: Создайте метод Calculate с двумя аргументами: строка S и символ C.
Указание 2: Для перевода символа в строковое значение понадобится метод .ToString().

Примерный вывод:

Строка: 4 5
Символ операции: +
Результат: 4+5=9
+++++++++
Строка: 4 5
Символ операции: *
Результат: 4*5=20

  
[Название проекта: Lesson_11Task6, название файла L11Task6.cs]