Строки в С++ (класс string)

      Комментарии к записи Строки в С++ (класс string) отключены

Помечено: ,

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 7 мес. назад.

  • Автор
    Сообщения
  • #3675

    Фактически, строка (далее string) — это массив типа char. Но есть несколько отличий:

    • string – это динамический массив символов, т.е. ему не надо задавать начальный размер:
          char   a [1000];
          // создание массива char длиной в 1000
          string a;
          // создание string-a, с динамичной длиной
    • string можно приравнивать, сравнивать, складывать и.т.д (для класса string определены соответствующие операторы):
          string a, b, c, d, s;
          cin >> a >> b;
          c = a;
          d = b;
          s = a + b;
          cout << s << "\n";
          if (c == d) cout << "Equal! \n";
          if (c < d) cout << "First string is lexicographically smaller than second one \n";
          if (c > d) cout << "Second string is lexicographically smaller than first one \n";

      Заметьте, что при сравнении двух строк меньшей будет та, которая меньше лексикографически, т.е. в алфавитном порядке. Пример лексикографически отсортированного по возрастанию набора слов:

      a, abcdefg, abscissa, b, bbb, bbbbb, bulvar, bulvara, grajdanstvo, zub, zubnoy.

      При сложении двух строк, в конец первой строки будет записана вторая строка.

    Главная особенность string-а в том, что в STL (Standard Template Library, или стандартная библиотека шаблонов) для него припасено много полезных функций (некоторые из которых рассмотрены ниже). С другой стороны Маерс (да и другие авторы книг о правильном программировании на С++) настоятельно рекомендует использовать string вместо char* (так называемых Си-строк). Дело в том, что если мы используем массив символов, то либо его размер мы зададим жестко в коде (что не всегда безопасно и вообще возможно), либо выделим памяти динамически (во время выполнения программы – функциями типа malloc или new). Про динамическое выделение памяти мы подробнее поговорим потом, но уже сейчас вы сможете понять, что после выделения памяти ее надо освобождать (это не всегда легко сделать, т.к. в программе могут возникать исключения, ну или обрабатываться коды ошибок). Однако, при использовании string от программиста не требуется вручную контроллировать выделение и освобождение памяти – все делается автоматически и корректно работает даже при возникновении исключений.

    string.size()

    Возвращает размер string-a, а именно количество символов в нем. Стоит упомянуть, что символы в string-е пронумерованы начиная с нуля.

        string user_name;
        cin >> user_name;
        cout << user_name.size() << "\n" << s << "\n";

    string.empty()

    Возвращает true, если string пуст.

        string str;
        cin >> str;
        if (str.empty() == true)
         cout << "Error! Empty filename! \n";
        else
         cout << "Success! \n";

    string.clear()

    Очищает строку, т.е. string.size() становится нулем, а string.empty() будет возвращать true.

        string s;
        cin >> s;
        cout << s;
        s.clear();
        cin >> s;

    string.push_back (char)

    Добавляет в конец строки char-овский символ.

        char ch;
        string str;
        whlie (cin >> ch)
          str.push_back(ch);
        cout << str;

    string.insert (int start1, string from, int start2, int amount)

    Вставляет в строку начиная с позиции start1, amount символов, начиная со start2, из строки from. Т.е. написав:

    str.insert (6, name, 17, 3);

    мы вставив в строку str, начиная с ячейки 6, символы из строки name с номерами 17, 18 и 19.

        string a = "to be", b = "or not", c = "that is", d = "the question!", s;
        s.insert (0, a, 0, a.size());
        s.insert (s.size() - 1, b, 0, b.size());
        s.insert (s.size() - 1, a, 0, 5);
        s.insert (s.size() - 1, c, 0, c.size());
        s.insert (s.size() - 1, d, 0, d.size());
        cout << s;

    string.erase (int from, int amount)

    Стирает из строки amount символов, начиная с ячейки from.

        string s = "a shot in the dark";
        s.erase (2, 1);
        cout << s;

    string.reverse (int from, int to)

    Перевернет строку начиная с ячейки from до ячейки to (to не включительно).

        string a = "sator arepo tenet opera rotas";
        a.reverse (0, a.size());
        cout << a;

    В начале статьи была, возможно, не совсем понятная часть про исключения, безопасность, выделение памяти и т.д. – по этим темам можно почитать:

    1. Обработка исключений – статья про механизм исключений в целом (не только про С++)
    2. Реализация класса одномерного массива на С++ – статья-пример, показывающая, что даже не самая лучшая реализация “нормального” массива в С++ – это тяжело. А вот класс string – это ведь тоже массив, только реализован гораздо лучше и сложнее. В примере помимо прочего можно посмотреть на работу с исключениями. Реализованный класс, как и string сам следит за корректным выделением и освобождением памяти;
    3. Исключения (заметка по С++) – статья о некоторых специфических особенностях С++ при обработке исключений;
    4. Идиома RAII. Объекты управления ресурсами в C++. Описывается та самая идиома, за счет которой string и наш класс одномерного массива корректно работают (не допускают утечек памяти) при исключениях и прочих незапланированных действиях (кроме вызова функций типа exit и abort, разумеется).

Для ответа в этой теме необходимо авторизоваться.