Как правильно склеить две строки в Си?
Для склеивания во время выполнения использовать функцию strcat — не самая лучшая идея из-за того, что при каждом склеивании функция снова и снова выполняет сканирование уже построенной части строки. (По этой причине strcat — фактически бесполезная функция.) Лучше уж воспользоваться для этих целей обычным snprintf
#include int main(void)
А уж какой способ резервирования памяти для строки-получателя вам больше подходит — зависит от ваших конкретных обстоятельств и требований.
Склеить две строки в одну
Как склеить 3 строки (char*) в одну
Всем здрасте =) Как склеить 3 строки (char*) в одну. Это пример того как всё должно быть. .

Получить две строки, одну из букв, другую из цифр заданной строки
Дана строка, содержащая латинские буквы и десятичные цифры. Получить две строки, одну из букв.

Соединить две введенные строки в одну
Можете помочь с заданием??Написать программу, которая соединяет две введенные строки (длиной не.
Объединить две строки в одну, удалив все пробелы
Привет всем. Нужна помощь нубу. Ести небольшое начало программы:#include <stdio.h> #include.
76 / 76 / 30
Регистрация: 12.02.2016
Сообщений: 199
Типы в функцию передавать не нужно.
strcat(TextDlyaShifra, ImyaSaita); strcat(TextDlyaShifra, loginDlyaSaita);
Конкатенация (объединение) строк. Функция 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Шок от С. Как склеивать строки?
Осваиваю си. Всё шло хорошо пока внезапно не понадобилось склеить строки (константные и переменные). Покурил stackoverflow. Предлагают 2 варианта:
Первый - создать char buf[молись_чтобы_хватило] и делать str(n)cat/sprintf в этот buf.
Второй - использовать asprintf, который расширение, нестандарт и вообще.
Вопрос: как вы склеиваете строки? Может есть какая-нибудь общепринятая либа?
Простите за нубский вопрос
makoven ★★★★★
23.12.14 16:32:20 MSK ← 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 →
Может есть какая-нибудь общепринятая либа?
strcat/sptrinf это как бы и есть общепринятая либа, стандарт.
Зачем? Можно посчитать, сколько конкретно нужно.
no-such-file ★★★★★
( 23.12.14 16:35:59 MSK )i-rinat ★★★★★
( 23.12.14 16:36:35 MSK )anonymousПервый - создать char buf[молись_чтобы_хватило]
( 23.12.14 16:38:01 MSK )size_t sumlen = strlen(a)+strlen(b); char *concat = malloc(sumlen); snprintf(concat, sumlen, "%s%s", a, b);
Eddy_Em☆☆☆☆☆
( 23.12.14 16:40:35 MSK )
Ответ на: комментарий от no-such-file 23.12.14 16:35:59 MSKstrcat/sptrinf это как бы и есть общепринятая либа, стандарт
Зачем? Можно посчитать, сколько конкретно нужноМожет есть какая-нибудь общепринятая либа, которая считает длину, выделяет память и склеивает? Или каждый пишет это вручную?
makoven ★★★★★
( 23.12.14 16:40:49 MSK ) автор топика
Ответ на: комментарий от makoven 23.12.14 16:40:49 MSK
которая считает длину, выделяет память и склеивает?
Нет, т.к. не нужно. А тебе зачем склеивать строки если не секрет. Просто ума не приложу нахрена это понадобилось?
no-such-file ★★★★★
( 23.12.14 16:42:08 MSK )
Последнее исправление: no-such-file 23.12.14 16:43:48 MSK (всего исправлений: 1)Ответ на: комментарий от Eddy_Em 23.12.14 16:40:35 MSK
(да, надо еще таки не забывать проверять результат malloc'а, несмотря на здравомыслие Царя)
size_t sumlen = strlen(a)+strlen(b); a = realloc(sumlen); strcat(a, b);В этом случае не нужно будет следить за новым malloc
Eddy_Em☆☆☆☆☆
( 23.12.14 16:43:16 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:40:35 MSK
Поздравляю! В трёх строках «элементарщины» ты умудрился:
- вызвать strlen четыре раза вместо двух;
- создать строку, не оканчивающуюся нулём;
- и тем самым подложить мину либо себе, либо другому.
i-rinat ★★★★★
( 23.12.14 16:43:53 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:43:16 MSK
Посчитать сумму, выделить память, проследить за выделением, склеить. И так делать каждый раз когда захочется склеить строку?
makoven ★★★★★
( 23.12.14 16:46:24 MSK ) автор топика
Ответ на: комментарий от i-rinat 23.12.14 16:36:35 MSK
Сколько там интересного в этой глиб. Курю
makoven ★★★★★
( 23.12.14 16:47:24 MSK ) автор топика
Ответ на: комментарий от makoven 23.12.14 16:40:49 MSK

Может есть какая-нибудь общепринятая либа, которая считает длину, выделяет память и склеивает? Или каждый пишет это вручную?
Обычно на Сях пишут такие программы, где управление памятью более хитрое, чем отдельный malloc на каждый чих. Поэтому «общепринятая либа» решала бы тривиальную задачу, но имела бы крайне низкую гибкость.
proud_anon ★★★★★
( 23.12.14 16:48:33 MSK )
Ответ на: комментарий от makoven 23.12.14 16:40:49 MSK
anonymous
( 23.12.14 16:50:02 MSK )
Ответ на: комментарий от makoven 23.12.14 16:40:49 MSK
либа, которая считает длину, выделяет память и склеивает? Или каждый пишет это вручную?
Тебе три строчки влом написать что ли?
Eddy_Em ☆☆☆☆☆
( 23.12.14 16:50:13 MSK )
Ответ на: комментарий от i-rinat 23.12.14 16:43:53 MSK
вызвать strlen четыре раза вместо двух;
Где это там 4 раза?
создать строку, не оканчивающуюся нулём;
Врешь! Где? sprintf работал и работает!
Eddy_Em ☆☆☆☆☆
( 23.12.14 16:51:16 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:50:13 MSK
это надо уметь. ты, например, не умеешь
anonymous
( 23.12.14 16:51:39 MSK )
Ответ на: комментарий от makoven 23.12.14 16:46:24 MSK
Ну так оформи эту шнягу в отдельный макрос или функцию. Чего как маленький-то?
Или ты думаешь, что в "волшебной библиотеке" этого делаться не будет? Там будет еще хуже, т.к. общая библиотека будет еще кучу проверок содержать!
Eddy_Em ☆☆☆☆☆
( 23.12.14 16:52:16 MSK )
Ответ на: комментарий от i-rinat 23.12.14 16:43:53 MSK
Поясни насчет четырех раз, никак не могу увидеть.
anonymous
( 23.12.14 16:52:55 MSK )
Ответ на: комментарий от anonymous 23.12.14 16:51:39 MSK
Да и пофиг, что не умею! Работает — и ладно! А если поломается, то починю.
Eddy_Em ☆☆☆☆☆
( 23.12.14 16:53:00 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:51:16 MSK
Тебе повезло, что работает. Ты выделяешь на 1 байт меньше, чем надо.
anonymous
( 23.12.14 16:53:48 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:53:00 MSK

А если из-за твоей ошибки у телескопа зеркало отвалится?
crowbar ★
( 23.12.14 16:54:04 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:53:00 MSK
во-первых, не работает. во-вторых, std::string быстрее.
anonymous
( 23.12.14 16:54:43 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:51:16 MSK

у sprintf емнип адовый оверхед, который при подобной работе со строками совершенно не нужен.
к слову, strlcpy() — потокобезопасна?
wakuwaku ★★★★
( 23.12.14 16:56:02 MSK )
Ответ на: комментарий от anonymous 23.12.14 16:53:48 MSK
А, это я проглючил, да.
Eddy_Em ☆☆☆☆☆
( 23.12.14 16:56:49 MSK )

Если нужно именно что склеить строки — то strlen+memcpy. Оберни в функцию с переменным числом аргументов и всё. Ref: strjoin() в коде systemd.
Если нужно получить аналог asprintf — то snprintf (NULL, 0, . ) вернёт предполагаемый размер.
intelfx ★★★★★
( 23.12.14 16:57:01 MSK )
Ответ на: комментарий от anonymous 23.12.14 16:54:43 MSK
Такого бреда я еще не слышал! Ты еще скажи, что код на жабке будет шустрей ассемблерного работать!
Eddy_Em ☆☆☆☆☆
( 23.12.14 16:57:29 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:51:16 MSK

Два раза явно и по одному разу на каждое %s . Надо считать длины, запоминать, а потом печатать с помощью %.*s , указывая длину. И то, не факт, что snprintf не будет проверять каждый символ на \0. memcpy не проверяет, и поэтому сработает быстрее.
Ограничивая длину результата суммой длин строк, ты не даёшь snprintf добавить завершающий ноль. Память под него, кстати, ты тоже забыл выделить.
Это не показатель.
i-rinat ★★★★★
( 23.12.14 16:58:25 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:57:29 MSK

Код на жабке исполняется в VM, а std::string — это строка+длина. Поэтому при нормальной реализации и компиляторе, способном к инлайну, будет быстрее. Правда, только при количестве объединяемых строк, равном двум: иначе будут создаваться временные строки.
intelfx ★★★★★
( 23.12.14 16:58:53 MSK )
Последнее исправление: intelfx 23.12.14 17:01:18 MSK (всего исправлений: 1)
Ответ на: комментарий от crowbar 23.12.14 16:54:04 MSK

А если из-за твоей ошибки у телескопа зеркало отвалится?
А если из-за его ошибки на нас метеорит упадёт?
cipher ★★★★★
( 23.12.14 17:00:12 MSK )
Ответ на: комментарий от wakuwaku 23.12.14 16:56:02 MSK
Согласен. В микроконтроллерах printf и ей подобные используются только идиотами либо буржуями (у которых мегабайт-другой флеша в МК).
В данном случае вполне возможно, что шустрей всех будет memmove работать или memcpy .
Нет, конечно. Если кто-то начал менять буфер во время хоть strcpy, хоть memcpy, на выходе получишь черт-те что. Это ясно.
Eddy_Em ☆☆☆☆☆
( 23.12.14 17:00:12 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 16:40:35 MSK

Спасибо Эдик
#include #include #include int main()
$ gcc fail.c -o fail && ./fail Hello Worl
vertexua ★★★★★
( 23.12.14 17:03:44 MSK )
Ответ на: комментарий от intelfx 23.12.14 16:57:01 MSK
Спасибо. Не могу распарсить
r = new(char, max_length);
. Это макрос?
makoven ★★★★★
( 23.12.14 17:03:46 MSK ) автор топика
Последнее исправление: makoven 23.12.14 17:04:03 MSK (всего исправлений: 1)
const char string1[] = "string1"; const char string2[] = "string2"; char combined[sizeof string1 + sizeof string2 - 1]; memcpy (combined, string1, sizeof string1 - 1); memcpy (combined+sizeof string1-1, string2, sizeof string2);
waker ★★★★★
( 23.12.14 17:04:47 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 17:00:12 MSK

ну у меня тут написано «The strcpy() and strncpy() functions are thread-safe», то же касается и memcpy, а вот про бсдшные варианты ничего нигде не сказано.
wakuwaku ★★★★
( 23.12.14 17:04:52 MSK )
Ответ на: комментарий от waker 23.12.14 17:04:47 MSK

Вот не надо глупостей с sizeof, ТС потом скопирует начиная с третей строки и будет удивляться
vertexua ★★★★★
( 23.12.14 17:06:54 MSK )
Ответ на: комментарий от intelfx 23.12.14 16:58:53 MSK
Если тебе часто нужно вычислять strlen, то запросто можно такое сделать:
typedef struct < char *str; size_t len; >string;
и написать свои функции работы с ними:
string *allocstr(size_t L)< string *S = malloc(sizeof(string)); if(!S) return NULL; S->str = calloc(1, L + 1); if(!S->str) < free(S); return NULL; >S-> len = L; return S; > void freestr(string *S)< free((*S)->str); free(*S); *S = NULL; > string *concatstr(string A, string B)< size_t newL = A->len + B->len + 1; if(! realloc(A->str, newL)) return NULL; memcpy(A->str + A->len, B->str, B->len); A->len = newL; return A; >
Eddy_Em ☆☆☆☆☆
( 23.12.14 17:07:44 MSK )
Ответ на: комментарий от makoven 23.12.14 17:03:46 MSK

Да, судя по всему, макрос.
intelfx ★★★★★
( 23.12.14 17:09:05 MSK )
Ответ на: комментарий от intelfx 23.12.14 16:58:53 MSK

В очень быстром коде нужно учитывать что char* фиксированый длины будет лежать в стеке, а в std::string нужно включить аллокатор специальный. Конечно в глупости «С быстрее С++» только нуб вроде Эдика будет верить, но есть реальные вещи, которые просто нужно помнить и знать как обходить. В С++ увы нужно больше понимать о внутренностях STL чтобы знать откуда ждать горя
vertexua ★★★★★
( 23.12.14 17:09:27 MSK )
Ответ на: Спасибо Эдик от vertexua 23.12.14 17:03:44 MSK
Eddy_Em ☆☆☆☆☆
( 23.12.14 17:09:47 MSK )
Ответ на: комментарий от vertexua 23.12.14 17:06:54 MSK
это вполне рабочий вариант. использую постоянно. если строки не константные — sizeof легко и непринужденно заменяется на strlen.
waker ★★★★★
( 23.12.14 17:09:47 MSK )
Ответ на: комментарий от Eddy_Em 23.12.14 17:07:44 MSK

Я прекрасно это понимаю. Моё сообщение было к тому, что плюсовый std::string транслируется как раз во что-то подобное, и поэтому сравнение с жабой неуместно.
intelfx ★★★★★
( 23.12.14 17:10:02 MSK )
Ответ на: комментарий от waker 23.12.14 17:04:47 MSK
О! Массивы переменной длины. И как я о них не подумал. Они же сами уничтожаются когда функция завершается? То-есть, если я засуну этот код в функцию, мне придется в конце делать malloc чтобы вернуть склееную строку?
makoven ★★★★★
( 23.12.14 17:10:58 MSK ) автор топика
Ответ на: комментарий от waker 23.12.14 17:04:47 MSK

tailgunner ★★★★★
( 23.12.14 17:11:46 MSK )

А я вот так велосипедил:
char * str_concat (const char *fmt, . )
deep-purple ★★★★★
( 23.12.14 17:12:00 MSK )
Ответ на: комментарий от makoven 23.12.14 17:10:58 MSK
гораздо более эффективно передавать в функцию указатель на выходной буфер, его размер, и размеры входных строк. если понатыкать malloc/free везде — твоя прога на C будет работать со скоростью жабы.
waker ★★★★★
( 23.12.14 17:13:02 MSK )
Ответ на: комментарий от intelfx 23.12.14 17:10:02 MSK
ТСу остается к моему коду еще десяток функций приплюсовать и получится свой велосипед =D
(еще resize нужны и всякие другие вещи + в структуру надо бы добавить реальную длину содержимого, ну или что там по желанию)
Кстати, если еще в объявлении структуры добавить правильно выравнивание, то можно будет тупо писать
string *S = allocstr(X); // заполняем S, а затем printf("The string S is %s\n", (char*)S);
// можно макрос оформить, чтобы (char*) не писать
