Как сделать конкатенацию в c

Добавил пользователь Alex
Обновлено: 10.09.2024

Неформатированные ввод из стандартного потока и вывод в стандартный поток

С помощью функции printf() можно легко вывести на экран строку, содержащую пробелы:

С другой стороны, ввести строку произвольной длины, содержащую пробелы в неизвестных местах, исключительно с помощью функции scanf() невозможно. Для scanf() любой символ пустого пространства является сигналом завершения ввода очередных данных, если только не производится считывание символа.

На помощь может прийти функция getchar() , осуществляющая посимвольный ввод данных:

В заголовке цикла getchar() возвращает символ, далее записываемый в очередную ячейку массива. После этого элемент массива сравнивается с символом '\n'. Если они равны, то цикл завершается. После цикла символ '\n' в массиве "затирается" символом '\0'. В условии цикла должна быть также предусмотрена проверка на выход за пределы массива; чтобы не усложнять пример, опущена.

Однако в языке программирования C работать со строками можно проще. С помощью функций стандартной библиотеки gets() и puts() получают строку из стандартного потока и выводят в стандартный поток. Буква s в конце слов gets и puts является сокращением от слова string (строка).

В качестве параметров обе функции принимают указатель на массив символов (либо имя массива, либо указатель).

Функция gets() помещает полученные с ввода символы в указанный в качестве аргумента массив. При этом символ перехода на новую строку, который завершает ее работу, игнорируется.
Функция puts() выводит строку на экран и при этом сама добавляет символ перехода на новую строку. Простейший пример использования этих функций выглядит так:

Итак, если вы работаете со строками, а не другими типами данных, при этом нет необходимости выполнять их посимвольную обработку, то удобнее пользоваться функциями puts() и gets() . (Однако функция gets() считается опасной и была выпилена из версии языка C11.)

Массив символов и указатель на строку

Как мы знаем, строка представляет собой массив символов, последний элемент которого является нулевым символом по таблице ASCII, обозначаемым '\0'. При работе со строками также как с численными массивами можно использовать указатели. Мы можем объявить в программе массив символов, записать туда строку, потом присвоить указателю адрес на первый или любой другой элемент этого массива и работать со строкой через указатель:

В заголовке цикла указателю сначала присваивается адрес первого элемента массива, его значение увеличивается до тех пор, пока не встретится пробел. В итоге указатель указывает на пробел и мы можем получить с его помощью вторую часть строки.

Иногда в программах можно видеть такое объявление и определение переменной-указателя:

Строку, которая была присвоена не массиву, а указателю, также можно получить, обратившись по указателю:

Но давайте посмотрим, что же все-таки происходит, и чем такая строка, присвоенная указателю, отличается от строки, присвоенной массиву.

Когда в программе определяются данные и объявляются переменные, то под них отводится память. При этом данные, которые не были присвоены переменным, поменять в процессе выполнения программы уже нельзя.

Что происходит в примере? В программе вводится строковый объект, который по сути является строковой константой (литералом). Ссылка на первый элемент этой строки присваивается указателю. Мы можем менять значение указателя сколько угодно, переходить к любому из элементов константного массива символов или даже начать ссылаться на совершенно другую строку. Но вот поменять значение элементов строки не можем. Это можно доказать таким кодом:

В последней строке кода возникнет ошибка, т.к. совершается попытка изменить строку-константу.

Тем более нельзя делать так:

В данном случае память не была выделена под массив символов, который мы пытаемся считать функцией scanf() ; память была выделена только под указатель. Поэтому записать строку просто некуда. Другое дело, если память была выделена с помощью объявления массива, после чего указателю был присвоен адрес на этот массив:

Поэтому если вам требуется в программе неизменяемый массив символов, то можете определить его через указатель.

Передача строки в функцию

Передача строки в функцию ничем не отличается от передачи туда массива чисел:

В этом примере функция change() принимает в качестве параметра указатель на символ. В теле функции значение указателя инкрементируется, указывая на следующий символ массива. В теле цикла инкрементируется значение, которое находится по адресу, который содержит указатель.

Объявите в программе три массива символов. Данные для двух из них получите с помощью вызовов функции gets() . Третий массив должен содержать результат конкатенации (соединения) двух введенных строк. Напишите функцию, которая выполняет конкатенацию строк.

Массив строк и массив указателей

Рассмотрим более сложный пример. Допустим, у нас есть набор строк. Требуется выполнить сортировку строк по возрастанию по признаку длины: сначала вывести самые короткие строки, затем более длинные.

Набор строк можно представить как двумерный массив, т.е. массив, состоящий из одномерных массивов, где каждый одномерный массив — это строка символов:

Представьте себе, что значит выполнить сортировку строк. Это значит, надо поменять местами содержимое множества ячеек памяти. Это достаточно трудоемкая для компьютера работа, особенно если строк очень много. Однако можно поступить по-иному. Достаточно создать массив указателей, каждый элемент которого будет указывать на соответствующую ему строку первого массива. Далее выполнить сортировку указателей, что несомненно быстрее. Конечно, сам массив строк отсортирован не будет, однако благодаря указателям у нас будет хранится отсортированный "срез" массива:

Примечания к программе:

  • На самом деле параметром функции sortlen() является указатель на указатель. Хотя для понимания проще сказать, что параметром является массив указателей на символы. Мы передаем в функцию указатель на первый элемент массива strP, который сам является указателем. Если бы в функции мы инкрементировали переменную s, то переходили бы к следующему элементу-указателю массива strP.
  • Сортировка выполняется методом пузырька: если длина строки, на которую ссылается следующий указатель массива strP, меньше длины строки под текущим указателем, то значения указателей меняются.
  • Выражение strP[i] = &strings[i][0] означает, что элементу массива указателей присваивается ссылка на первый символ каждой строки.

Напишите программу, которая сортирует строки по алфавиту. Для упрощения задачи пусть сортировка выполняется только по первым буквам строк (если первые буквы слов одинаковы, то вторые и последующие символы проверять не надо).

Пожалуйста, приостановите работу AdBlock на этом сайте.

В языке Си предусмотрено множество разных функций, предназначенных для работы со строками. Для их использования необходимо подключить заголовочный файл string.h

Разберём самые простые из них:

  • strlen(str) – длина строки str ;
  • strcmp(str1, str2) – сравнение строк str1 и str2 ;
  • strcat(str1, str2) – конкатенация (склеивание) двух строк. К строке str1 в конце приклеивается строка str2 .
  • strcpy(str1, str2) – копирование строки str2 в строку str1 ;

Функция strlen

Данная функция возвращает целое число – длину строки, которая ей передана в качестве аргумента.

Обратите внимание. Длина строки – это не количество элементов символьного массива, а количество элементов в массиве до первого нуль-символа. Например, следующий код выведет на экран не 19 , а 7 .

Работа функции strlen.

Рис.1 Работа функции strlen.

Функция склеивания строк strcat.

Данная функция склеивает строки, которые передаются ей в качестве параметров. Функция strcat присоединяет к концу строки str1 строку str2 .

Программисту самому необходимо следить за тем, чтобы размер массива str1 позволял вместить и str1 , str2 , и завершающий нулевой символ. В противном случае, может возникнуть ошибка во время выполнения программы.

Результат работы этой программы ниже:

Работа функции strcat.

Рис.2 Работа функции strcat.

Функция сравнения строк strcmp

Данная функция сравнивает посимвольно строки, переданные ей в качестве аргументов. Функция strcmp вернёт нуль, если строки равны между собой, иначе какое-либо другое целое число (положительное или отрицательное). Общее правило таково: Если в функции strcmp() первая строка больше, чем вторая строка, то функция возвращает положительное число. Если меньше – отрицательное. Сравнение осуществляется по кодам символов в таблице ASCII

Посмотрите на пример.

Работа функции strcmp.

Рис.3 Работа функции strcmp.

Первая и вторая строки одинаковы, поэтому результат их сравнения нуль. А вот первая и третья строки различаются седьмым символом. В первой строке это строчная w , а в третьей – прописная W . Т.к. код строчной буквы w больше, чем код прописной буквы W (119 > 87) , то в n13 помещается положительное число, т.к. первая строка, больше второй. Теперь если мы поменяем строки местами, то получим отрицательное число.

Функция копирования строк strcpy.

Данная функция принимает на вход две строки, а потом копирует вторую строку в первую. Простой примерчик.

Работа функции strcpy.

Рис.4 Работа функции strcpy.

Как и в случае с strcat программисту нужно самому следить за тем, чтобы в первой строке хватило места для копирования в неё второй строки.

Есть и более сложные функции работы со строками, но о них в базовой части курса мы говорить не будем.

Практика

Решите предложенные задачи:


Для удобства работы сразу переходите в полноэкранный режим

функции strlen (), strcat (), strcpy (), strcmp () в C++

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

    • strlen() – подсчитывает длину строки (количество символов без учета \0);
      • 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 , о которой речь пойдет ниже.

      Файл String.h содержит прототипы функций работы со строками C.

      Прямо сейчас на примерах рассмотрим Си функции работы со строками.

      strcmp

      Сравнение строк в C, пример:

      Две C строки объявлены в примере. Они одинаковы. Предложим функции сравнения строк в C strcmp сравнить эти строки. Прототип функции strcmp в файле String.h:

      Если символы строки _Str1 раньше встречаются в алфавите, то _Str1 больше, чем _Str2 и результат функции будет меньше нуля. Если они равны, как в примере, то результат равен нулю. Если символы строки _Str2 раньше встречаются в алфавите, то _Str2 больше, чем _Str1 и результат функции будет меньше нуля. Функция strcmp различает большие и маленькие буквы.

      C String

      В примере строки равны, поэтому получаем:

      Нулевой результат говорит о том, что строки равны.

      stricmp

      Ещё одна функция сравнения строк в Си в файле String.h

      игнорирует разницу больших и маленьких букв, в остальном такая же как и strcm.

      strlen

      Длину строки в Си определяет функция strlen из файла String.h:

      Функция strlen возвращает длину строки C в виде количества байтов. Пример strlen:

      strlen

      Получаем:

      В примере строка “stroka” содержит 6 символов. Функция определения длины строки C strlen выдаёт результат 6 байтов, т.е. одному символу соответствует один байт. Так оно и есть на самом деле.

      strcpy

      strcpy – копирование строк в C. Это ещё одна функция работы со строками C. Пример копирования строки в Си:

      В примере создаём массив cMassiv для элементов типа char, и строку szStr. Функция strcpy копирует szStr в первый элемент массива, т.е. в cMassiv[0].

      strcpy

      Получаем:

      Прототип функции strcpy:

      strncpy

      strncpy – копирование строк в C. Это ещё одна функция работы со строками C. Пример копирования строки в Си:

      strncpy

      Получаем:

      В примере создаём массив cMassiv для элементов типа char, и строку szStr. Функция strcpy копирует szStr в первый элемент массива, т.е. в cMassiv[0]. А далее с помощью функции strncpy копируем 3 первых символа строки szStr2 в строку, хранящуюся в первом элементе массива, т.е. в cMassiv[0].

      Прототип функции strncpy:

      strcat

      strcat – конкатенация строк в C, т.е. присоединение одной строки к другой. Это ещё одна функция работы со строками C. Пример конкатенации строки в Си:

      strcat

      Получаем:

      Прототип функции strcat:

      strncat

      strncat – конкатенация строк в C, т.е. присоединение одной строки к другой. Это ещё одна функция работы со строками C. Пример конкатенации строки в Си:

      strcat

      Получаем:

      Здесь прибавляем три символа втрой строки к первой.

      Прототип функции strncat:

      strstr

      strstr – поиск первого вхождения одной строки в другую. Это ещё одна функция работы со строками C. Пример в Си:

      strstr

      Получаем:

      Прототипы функции strstr:

      char *strstr(char *szStr, const char *szSubStr);
      const char *strstr(const char *szStr, const char *szSubStr);

      Читайте также: