Основы программирования на С++ для начинающих

Функции для работы со строками в C++

функции strlen (), strcat (), strcpy (), strcmp () в C++После того, как мы с вами познакомились со строками и символьными массивами в C++, рассмотрим самые распространённые функции для работы с ними.  Урок будет полностью построен на практике. Мы будем писать собственные программы-аналоги для обработки строк и параллельно использовать стандартные функции библиотеки cstring (string.h – в старых версиях). Так вы примерно будете себе представлять, как они устроены.  К стандартным функциям библиотеки cstring относятся:

    • strlen()   – подсчитывает длину строки (количество символов без учета \0);

 

    • strcat()    – объединяет строки;

 

    • strcpy()   – копирует символы одной строки в другую;

 

  • strcmp()  –  сравнивает между собой две строки .

Это конечно не все функции, а только те, которые мы разберём в этой статье.

strlen() (от слова length – длина)

Наша программа, которая подсчитает количество символов в строке:

Для подсчёта символов в строке неопределённой длины (так как вводит её пользователь), мы применили цикл while – строки 13 – 17. Он перебирает все ячейки массива (все символы строки) поочередно, начиная с нулевой. Когда на каком-то шаге цикла  встретится ячейка ourStr [amountOfSymbol], которая хранит символ  \0, цикл приостановит перебор символов и увеличение счётчика amountOfSymbol.

Так будет выглядеть код, с заменой нашего участка кода на функцию strlen():

Как видите, этот код короче. В нем не пришлось объявлять дополнительные переменные и использовать цикл. В выходном потоке cout мы передали в функцию строку – strlen(ourStr). Она посчитала длину этой строки и вернула в программу число. Как и в предыдущем коде-аналоге, символ \0 не включен в общее количество символов.

Результат будет и в первой программе и во второй  аналогичен:

функция strlen () в C++

strcat() (от слова concatenation – соединение)

Программа, которая в конец одной строки, дописывает вторую строку. Другими словами – объединяет две строки.

По комментариям в коде  должно быть всё понятно. Ниже напишем программу для выполнения таких же действий, но с использованием strcat(). В эту функцию мы передадим два аргумента (две строки) – strcat(someText1, someText2); . Функция добавит строку someText2 к строке someText1. При этом символ '\0'  в конце someText1 будет перезаписан первым символом someText2. Так же она добавит завершающий  '\0'

Реализация объединения двух строк, используя стандартную функцию, заняла одну строчку кода в программе – 14-я строка.

Результат:

strcat c++, strcat_s c++

На что следует обратить внимание и первом и во втором коде – размер первого символьного массива должен быть достаточным для помещения символов второго массива. Если размер окажется недостаточным – может произойти аварийное завершение программы, так как запись строки  выйдет за пределы памяти, которую занимает первый массив. Например:

В этом случае, строковая константа “Учите С++ c нами!” не может быть записана в массив someText1. В нём недостаточно места, для такой операции.

Если вы используете одну из последних версий среды разработки Microsoft Visual Studio, возможно возникновение следующей ошибки: “error C4996: ‘strcat’: This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.” Так происходит потому, что уже разработана новая более безопасная версия функции  strcat  – это strcat_s.

Она заботится о том, чтобы не произошло переполнение буфера (символьного массива, в который производится запись второй строки). Среда предлагает вам использовать новую функцию, вместо устаревшей. Почитать больше об этом можно на сайте msdn. Подобная ошибка может появиться, если вы будете применять функцию strcpy, о которой речь пойдет ниже.

strcpy() (от слова copy – копирование)

Реализуем копирование одной строки и её вставку на место другой строки.

Применим стандартную функцию библиотеки cstring:

Пробуйте компилировать и первую, и вторую программу. Увидите такой результат:

strcpy c++

strcmp() (от слова compare – сравнение)

Эта функция устроена так: она сравнивает две Си-строки символ за символом. Если строки идентичны (и по символам и по их количеству) – функция возвращает в программу число 0. Если первая строка  длиннее второй – возвращает в программу число 1, а если меньше, то -1.  Число -1 возвращается и  тогда, когда длина строк равна, но символы строк не совпадают.

strcmp c++ Программа с strcmp():

strcmp c++

Делитесь в социальных сетях  нашими статьями со своими знакомыми, которые так же изучают основы программирования на языке С++.

51 thoughts on “Функции для работы со строками в C++

  1. Здравствуйте. Скажите пожалуйста, почему когда объединяем две строки и второму символьному массиву задаем длину массива, например

    , то в этом случае второй массив не объединяется с первым?

    1. Это неправда.
      У вас результат может просто не помещаться в someText1[].
      Увеличьте его размер – чего жадничать?
      Например: someText1[ 200 ]

  2. Объясните, пожалуйста, почему в примере с объединением строк
    int count1 = 0; // для индекса ячейки где хранится ‘\0’ первой строки
    while (someText1[count1] != 0)
    мы пишем “someText1[count1] != 0” а не “someText1[count1] != ‘\0′”?
    Мы же вроде бы ищем элемент окончания символьной строки ‘\0’? При чем здесь ноль?
    Хотя должен заметить, у меня а Коудблоксе работает и с нулем…

    1. Потому что запись ‘\0’ как-раз и означает: байт, численное значение записанное в который равно 0.
      Такие записи эквивалентны.

  3. Уважаемый автор!
    По-моему, в первом примере сравнений строк пропущена директива препроцессору #include

  4. Чета не могу понять
    char xsmibol[2] = {wParam, ‘\0’};
    вот так работает
    ————————–
    А вот так не работает:
    char xsmibol[2];
    xsmibol = {wParam, ‘\0’};

    Говорит 17 27 C:\Users\1\Documents\main1.cpp [Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11
    17 12 C:\Users\1\Documents\main1.cpp [Error] assigning to an array from an initializer list
    37 14 C:\Users\1\Documents\main1.cpp [Error] expected primary-expression before ‘)’ token

    Что я делаю не так ?

    1. Я думаю, что в первом случае – char xsmibol[2] = {wParam, ‘\0’}; компилятор сам вычисляет размер строки и подставляет за место 2. А во втором случае -char xsmibol[2];
      xsmibol = {wParam, ‘\0’}; он уже не может исправить размер строки.

    2. Потому что массиву допускается инициализация списком значений ({…,…}), но не разрешено присвоение. Это синтаксические правила C++, и это не зависит от типа элементов массива – будь это массив char (строки), или массив int, массив float и т.д.

      P.S. Это ограничение отчасти снижено в стандарте C++11 (2011г.), но его нужно указывать опциями компиляции.

  5. Добрый день. Учусь по вашим урокам и решаю задачи.
    Однако заметил некоторое расхождение в результатах по функции strcmp.
    В случае совпадения количества символов в двух строках , но отличия этих символов результат 1 или -1 зависит от того в какой последовательности эти символы. Если первая строка содержит символы , которые по алфавиту ваше чем во второй строке то результат 1, если наоборот то результат -1. Например: сравнение строк “asdf” и “bsdf”выдаст 1, а сравнение строк “bsdf” и “asdf” выдаст -1. Тоже и с числами. “1234” и “2234” выдаст 1, а “2234” и “1234” выдаст -1.

      1. Совершенно естественно – операция сравнения не коммутативная, она не допускает перестановку операндов. То же самое и для числовых значений и их сравнения (это понятнее): 2 > 1 – это true, но 1 > 2 – это false.

  6. Здравствуйте!
    Скажите, пожалуйста, почему, в примере с объединением двух строк при помощи циклов, мы обязательно указываем размерность первого строкового массива?:

    char someText1[64] = “Сайт purecodecpp.com!”;
    char someText2[] = “Учите С++ c нами!”;

    А если оставить размерность незаполненной, позволив компилятору самостоятельно подсчитать это значение, то после компиляции в консоли выводится объединенный текст, плюс какой-то случайный символ(совершенно рандомный), после чего появляется окно с ошибкой:

    (например, в данном случае, добавился знак вопроса:
    someText1: Сайт purecodecpp.com!Учите С++ c нами!?
    вместо – someText1: Сайт purecodecpp.com!Учите С++ c нами!

    1. Потому что указывая someText1[64] вы резервируете за строкой 64 байт памяти, хотя сама записанная туда строка “Сайт purecodecpp.com!”, ограниченная ‘\0’, занимает гораздо меньше байт (strlen(someText1)).
      А когда вы записываете someText1[], компилятор высчитывает и резервирует для этой строки не 64 байт, а ровно столько, сколько нужно для размещения указанной строки + концевой символ ‘\0’.

      Как только вы пытаетесь выполнить дописывание someText2 в хвост someText1, в 1-м случае копирование происходит вот в те 64 зарезервированных байтов. А во 2-м случае вы сразу начинаете писать за границу выделенной для someText1 памяти, и результата будет непредсказуем – это грубая ошибка.

  7. Здравствуйте, переписала в программу ваш первый код, запустила – пробую… Пишу для проверки одно слово, чтоб проверить корректно ли выдаст ответ, и так, слово: “лето”, состоит из 4х символов, в написании не использовались не пробелы, не кавычки, только само слово… а программы выдает:
    “Строка “лето” состоит из 8 символов!”
    …8-ми? Почему? :) Разве не 4 символа? Аналогично и с двумя словами:
    “лето утро”
    “Строка “лето утро” состоит из 17 символов!”
    Каждая буква, считается компилятором как 2 символа, пробел – 1 символ. Но ведь каждый символ должен считаться как 1… ?

  8. Так и не понял как нормально писать большой текст таким способом – ‘Ж’, и так далее – даже одну букву долго писать…. чтобы не просто кавычки!? может я не понял что-то!?

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

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