Как правильно склеить две строки в Си?
Для склеивания во время выполнения использовать функцию strcat — не самая лучшая идея из-за того, что при каждом склеивании функция снова и снова выполняет сканирование уже построенной части строки. (По этой причине strcat — фактически бесполезная функция.) Лучше уж воспользоваться для этих целей обычным snprintf
#include int main(void)
А уж какой способ резервирования памяти для строки-получателя вам больше подходит — зависит от ваших конкретных обстоятельств и требований.
Конкатенация (объединение) строк. Функция strcat.
Функция библиотеки <cstring> strcat позволяет объединять две строки в одну. Функция strcat имеет прототип:
char* strcat (char* str1, const char* str2);
В результате работы функции содержимое строки, на которую указывает str2 присоединяется к содержимому строки, на которую указывает str1. Указатель str1 будет указывать на результирующую строку. Велечина массива str1 должна быть достаточной, чтобы хранить там объединенные строки.
char str1[90]="Press Enter "; char str2[90]="to continue"; strcat(str1,str2); coutВ результате на экран выведется и в строке str1 будет записано: Press Enter to continue
Функция strncat
Функция strncat объединяет строки только до указанного в третьем параметре количества символов включительно. Эта функция имеет прототип:
char* strcat (char* str1, const char* str2, size_t num);char str1[90]="Press Enter "; char str2[90]="to continue"; strcat(str1,str2,6); coutПрактическое руководство. Сцепка нескольких строк (руководство по C#)
Объединение подразумевает добавление одной строки к концу другой. Вы можете сцеплять строки с помощью оператора + . Строковые литералы и константы сцепляются во время компиляции, а не во время выполнения. Строковые переменные сцепляются только во время выполнения.
Примеры C# в этой статье выполняются во встроенном средстве выполнения кода и на площадке Try.NET. Нажмите на кнопку Выполнить, чтобы выполнить пример в интерактивном окне. После выполнения кода вы можете изменить его и выполнить измененный код, снова нажав на кнопку Выполнить. Либо в интерактивном окне выполняется измененный код, либо, если компиляция завершается с ошибкой, в интерактивном окне отображаются все сообщения об ошибках компилятора C#.
Строковые литералы
В следующем примере длинный строковый литерал разделяется на более короткие строки для повышения удобочитаемости исходного кода. Код сцепляет строки меньшего размера для создания длинного строкового литерала. Сегменты сцепляются в одну строку во время компиляции. Количество строк не влияет на производительность во время выполнения.
// Concatenation of literals is performed at compile time, not run time. string text = "Historically, the world of data and the world of objects " + "have not been well integrated. Programmers work in C# or Visual Basic " + "and also in SQL or XQuery. On the one side are concepts such as classes, " + "objects, fields, inheritance, and .NET Framework APIs. On the other side " + "are tables, columns, rows, nodes, and separate languages for dealing with " + "them. Data types often require translation between the two worlds; there are " + "different standard functions. Because the object world has no notion of query, a " + "query can only be represented as a string without compile-time type checking or " + "IntelliSense support in the IDE. Transferring data from SQL tables or XML trees to " + "objects in memory is often tedious and error-prone."; System.Console.WriteLine(text);Операторы + и +=
Для сцепки строковых переменных вы можете использовать операторы + или += , интерполяцию строк, а также методы String.Format, String.Concat, String.Join или StringBuilder.Append. Оператор + прост в использовании и позволяет получить интуитивно понятный код. Даже если в одном выражении используется несколько операторов + , содержимое строки копируется только один раз. В следующем коде показаны примеры использования операторов + и += для сцепки строк:
string userName = ""; string dateString = DateTime.Today.ToShortDateString(); // Use the + and += operators for one-time concatenations. string str = "Hello " + userName + ". Today is " + dateString + "."; System.Console.WriteLine(str); str += " How are you today?"; System.Console.WriteLine(str);Интерполяция строк
В некоторых выражениях строки проще сцепить с помощью интерполяции, как показано в следующем коде:
string userName = ""; string date = DateTime.Today.ToShortDateString(); // Use string interpolation to concatenate strings. string str = $"Hello . Today is ."; System.Console.WriteLine(str); str = $" How are you today?"; System.Console.WriteLine(str);В операциях сцепки строк компилятор C# обрабатывает строки NULL так же, как пустые строки.
Начиная с C# 10, можно использовать интерполяцию строк для инициализации константной строки, если все выражения, используемые для заполнителей, также являются константными строками.
String.Format
Другие методы сцепки строк: String.Format. Этот метод лучше использовать при создании строки из небольшого числа строк-компонентов.
StringBuilder
В других случаях вы можете сцеплять строки во время цикла и не знать, сколько исходных строк вы сцепляете. При этом фактическое число исходных строк может быть большим. Для этих сценариев предназначен класс StringBuilder. В следующем коде для сцепки строк используется метод Append класса StringBuilder.
// Use StringBuilder for concatenation in tight loops. var sb = new System.Text.StringBuilder(); for (int i = 0; i < 20; i++) < sb.AppendLine(i.ToString()); >System.Console.WriteLine(sb.ToString());String.Concat или String.Join
Другой вариант объединения строк из коллекции — использовать метод String.Concat. Используйте метод String.Join, если исходные строки должны быть разделены разделителем. Следующий код объединяет массив слов с помощью обоих методов:
string[] words = < "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog." >; var unreadablePhrase = string.Concat(words); System.Console.WriteLine(unreadablePhrase); var readablePhrase = string.Join(" ", words); System.Console.WriteLine(readablePhrase);LINQ и Enumerable.Aggregate
Другой вариант объединения строк из коллекции — использовать LINQ и метод Enumerable.Aggregate. Этот метод объединяет исходные строки с помощью лямбда-выражения. Лямбда-выражение добавляет каждую строку к существующему накоплению. Следующий пример показывает объединение массива слов с добавлением между словами пробела:
string[] words = < "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog." >; var phrase = words.Aggregate((partialPhrase, word) =>$" "); System.Console.WriteLine(phrase);Этот вариант может потребовать большего числа выделений памяти по сравнению с другими методами сцепки коллекций, так как он создает в каждой итерации промежуточную строку. Если оптимизация производительности имеет решающее значение, рассмотрите StringBuilder String.Concat класс или метод или String.Join для объединения коллекции, а не Enumerable.Aggregate .
См. также
- String
- StringBuilder
- Руководство по программированию на C#
- Строки
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Как сложить строки в c
Подобно тому, как все математические функции "лежат" в библиотеке math.h, функции для работы со строками объединены в библиотеке string.h
Вопрос: КАК узнать длину строки?
Для того, чтобы точно знать, сколько выделить памяти для хранения строки, часто нам нужно получить длину конкретной строки. Разного рода функции иногда предлагают не просто ввести строку, а указать какое количество символов из неё мы хотели бы использовать. Чаще всего мы хотим ввести всю строку, поэтому есть смысл не считать вручную, а просто измерить длину строки и подставить в функцию.
#include
#include
void main()
char *str = "машина";
>
Функция strlen() возвращает количество символов в строке. Например для строки "машина" она вернёт число 6.
Вопрос: Как сложить две строки?
Помните мы писали программу, которая c нами здоровалась? Там была строка:
И умная программка добавляла в конец ваше имя.
А если мы хотим сложить две строки, которые заранее не известны? Для этого в программировании применяется операция "склеивания" - конкатенции (знаю - жуткое слово!), которая позволяет просто сложить две строки вместе и получить одну. В языке СИ такой операции нет, но зато в библиотеке string.h есть специальная функция strncat(), которая позволяет склеивать исходную строку с подстрокой.
void main()
char kuda[20];
char *otkuda="Федерация";
strcpy(kuda, "Российская "); //копирование в строку kuda
strncat(kuda, otkuda, strlen(otkuda)); //склеиваем две строки, результат - в строке kuda
cout
Функция strcpy(to, from) копирует строку from в строку to. Кстати, это ещё один из способов присвоения строке значения. Функция strncat объединяет две строки, дописывая в конец строки kuda строку otkuda. Этот процесс можно сравнить с локомотивом, в конец которого на товарной станции прицепляют ещё один вагончик. Для каждого нового вагона нам понадобится функция strncat.
Обратите внимание, что у функции strncat три аргумента. Функция гибка и позволяет скопировать не всю строку, а только её часть. Если мы точно знаем сколько символов в строке otkuda, можно третьим аргументом задать число, но проще всего измерить длину строки с помощью известной нам уже функции strlen().
Вопрос: КАК из строки сделать число?
Для чего это нужно? Часто программа получает данные от пользователя в виде строки. Например, данные полученные из текстовых полей Windows - всегда строковые. И даже если пользователь ввёл число, оно всё равно будет представлено, как строка. Чтобы подставить это число в форумулу, вам придётся его конвертировать в строку.
void main()
int n;
char *str="123456"; //объявляем строку
n=atoi(str); //конвертируем в число
В некоторых классах Windows есть методы, позволяющие сразу получать целые числа из текстовых полей, но метода, позволяющего сразу считывать числа с плавающей запятой, нет, поэтому в любом случае вам понадобится конвертирование. Для преобразования строки в число с плавающей запятой существует функция atof(char *str), которая по своему применению аналогична.
В этом примере мы используем новую для нас библиотеку "stdlib.h" - в данной библиотеке содержится большинство функций конвертирования, а также множество других функций самого разного назначения. Это библиотека очень широкого профиля.
После получения строки из поля ввода, конвертирования в число, подстановки в формулу, или куда-то ещё, ответ зачастую придётся выводить в какое-нибудь окно. Естественно, напрямую число в окно мы не сможем - оно нас просто не поймёт, и заставит выполнять обратное преобразование - теперь уже из числа в строку.
Иногда ответ должен сопровождаться каким-то текстом, например: "U = 127,24 v ". Для создания такого дружественного интерфейса удобнее использовать не саму операцию конвертирования, а записать в один буфер и число и текст.
Функция sprintf аналогична функции printf, с той лишь разницей, что вывод информации осуществляется не в какое-то устройство вывода, а в буфер данных. Используя эту функцию, мы сможем комбинировать различные типы данных в любой последовательности.
void main()
char buffer[25]; //строка, длиной 25 символов
const double f=127.24; //число с плавающей точкой
sprintf(buffer, "U = %3.2f V\n", f);
Однако, если нам необходимо просто преобразовать число в строку, можно использовать функцию конвертирования, описанную в следующем разделе.
Вопрос: КАК из числа сделать строку?
#include
void main()
<
int number = 123456;
char *string;
itoa(number, string, 10); //число 10 заботится о добавлении минуса отрицательными числам
printf("Число = %d Строка = %s", number, string);
>
Конвертирование - очень важная задача, и в математических программах без неё никуда. Если ваша программа что-то считает, получая данные от пользователя, вы будете использовать конвертирование постоянно.
Вопрос: КАК что-то найти в строке?
Иногда нам нужно проверить строку на наличие в ней какого-нибудь символа. Например, если пользователь вводит свой E-mail хорошо бы проверить, есть ли в нём символ "at", который в России чаще называют собакой @? Кроме того, в каждом адресе электронной почты есть по крайней мере одна точка.
Следующая программа последовательно проверяет наличие в строке знака "@" и точки.
void main()
char *ptr;
printf("Введите E-mail: ");
scanf("%s", email);
ptr = (char *)memchr(email, '@', strlen(email));
ptr = (char *)memchr(email, '.', strlen(email));
printf("\n%s не является E-mail адресом", email);
>
else printf("\nE-mail адрес: %s успешно введён!", email);
Переменная flag - своеобразный выключатель, который имеет два состояния "истина" и "ложь". Такие переменные программисты часто так и называют "флагами" или "флажками". Они обозначают состояние. Первоначально переменная flag = 0. Но если программа не обнаруживает в строке знака "@" или точки, значение flag поменяется на 1. Условий может быть и больше (например, мы могли бы проверить, есть ли какие-то символы до знака "@" и находится ли точка после знака @, а не до него), однако работать они будут по тому же принципу.
В конце программы проверяется значение переменной flag, и если она изменила своё значение, E-mail адрес признаётся некорректным.
При разработки больших программ подобные проверки необходимо производить буквально на каждом шагу, они делают программу более надёжной и отказоустойчивой, страхуя нас от недопустимого типа данных. Согласитесь, если мы попытаемся отправить письмо на некорректный адрес, приятного в этом будет мало! Однако во избежание увеличения кода, мы заключим процедуру проверки адреса в маленькую проверочную функцию вида:
int IsEmail(char *email)
которая будет возвращать 0, если E-mail адрес был введён недостаточно корректно.
Часто производители программного обеспечения требуют регистрации и предлагают пользователю заполнить форму, в которой в том числе есть просьба указать электронный адрес. Знать ваш E-mail адрес производителю жизненно важно, чтобы впоследствии заваливать вас своей рекламой. Поэтому если вы введёте свой адрес неправильно или вообще проигнорируете эту просьбу, электронная форма откажется вас регистрировать.
Функция поиска в строке незаменима при работе с файлами (а храним мы данные именно в них - лучшего пока ничего не придумали). Есть и другие применения поиска: когда программа предлагает пользователю сохранить файл, с которым он работал, необходимо ввести его имя. Однако пользователи попадаются с совершенно разным профессиональным уровнем: кто-то вводит имена файлов с расширениями: "picture.bmp" , а кто-то и не знает, что такое расширение. Нужно предусмотреть оба случая, и в случае, если пользователь просто ввёл имя: "моя картинка. " добавить к этому имени расширение. Пример решения этой проблемы приведён ниже.
#include
#include
#include
void main()
char *ptr;
printf("Введите имя файла: ");
scanf("%s", filename);
ptr = (char *)memchr(filename, '.w', strlen(filename));
strncat(filename, ".bmp", 4);
>
printf("\nИмя файла: %s", filename);
Вопрос: КАК сравнить две строки?
Часто, когда вы получаете от пользователя не числовые данные, а строковые, вам надо сравнить строку с уже имеющимся эталоном. Допустим, вы хотите, чтобы пользователь зарегистрировал свою версию вашей программы и ввёл пароль. Для этого и нужна функция сравнения строк strncmp(). Она возвращает ноль, если строки одинаковы.
Следующая ниже программа вполе функциональна. Она ни за что не пропустит построннего на ваш компьютер. При желании, вы можете включить её в файл autoexec.bat. Доступ посторонним будет закрыт навеки! (Конечно если вы всё ещё пользуетесь Windows 98).
char *password="BUSH"; //наш пароль
char enter[256]; //строка, которую будет вводить пользователь
do printf("Введите пароль: ");
scanf("%s", enter);
//сравниваем две строки по всей длине
ptr = strncmp(enter, password, strlen(password));
//если строки одинаковы
if (ptr == 0)
printf("Доступ открыт");
return(0);
>
else printf("Введён неверный пароль!");
>
>while(ptr!=0); //цикл повторяется, пока ptr не будет =0.
return 0;
>
Конечно в реальности никто не будет прописывать пароль в коде программы, иначе мало-мальски грамотный хаккер запросто его оттуда "достанет". Настоящие программы генерируют пароль из имени пользователя, таким образом, чтобы пароли никогда не повторялись. Также популярна онлайн регистрация, при которой пользователь получает пароль, регистрируясь на сайте фирмы. Получив такой пароль, программа преобразует его по сложному алгоритму и проверяет на соответствие какому-то правилу - например сумма кодов символов должна всегда быть равна 100 (или что-то в этом роде). Дружеский совет - никогда не давайте "говорящие" пароли, как в данном примере. Такие пароли разгадываются элементарно, путём простого перебора символов. Хороший пароль должен содержать цифры и буквенные символы разного регистра, также неплохо было бы включить в него специальные символы. В результате должно получиться нечто вроде: "$&weh!60Om17rv".
Подытожим. Мы освоили достаточно операций для работы со строками. Их хватит на первый и на второй случай. Если же вам понадобится что-то большее, читайте описания функций библиотеки string.h. В справочной системе.