Я работаю в C, и мне нужно объединить несколько вещей.
Прямо сейчас у меня есть это:
message = strcat("TEXT ", var);
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
Теперь, если у вас есть опыт работы с Си, я уверен, что вы понимаете, что это дает вам ошибку сегментации, когда вы пытаетесь запустить ее. Так как мне обойти это?
c
string
concatenation
The.Anti.9
источник
источник
Ответы:
В C «строки» - это просто
char
массивы. Следовательно, вы не можете напрямую объединять их с другими «строками».Вы можете использовать
strcat
функцию, которая добавляет строку, на которую указывает указатель,src
к концу строки, на которую указывает указательdest
:Вот пример из cplusplus.com :
Для первого параметра вам нужно указать сам буфер назначения. Буфер назначения должен быть буфером массива символов. Например:
char buffer[1024];
Убедитесь, что первый параметр имеет достаточно места для хранения того, что вы пытаетесь скопировать в него. Если вам доступно, безопаснее использовать такие функции, как:
strcpy_s
иstrcat_s
где вам явно нужно указать размер буфера назначения.Примечание . Строковый литерал нельзя использовать в качестве буфера, поскольку он является константой. Таким образом, вы всегда должны выделять массив символов для буфера.
Возвращаемое значение
strcat
может просто игнорироваться, оно просто возвращает тот же указатель, который был передан в качестве первого аргумента. Это сделано для удобства и позволяет вам объединять вызовы в одну строку кода:Таким образом, ваша проблема может быть решена следующим образом:
источник
Избегайте использования
strcat
в C-коде. Самый чистый и, самое главное, самый безопасный способ - это использоватьsnprintf
:Некоторые комментаторы поднимали вопрос о том, что число аргументов может не соответствовать строке формата, и код все равно будет компилироваться, но большинство компиляторов уже выдают предупреждение, если это так.
источник
snprintf()
БОЛЬШОЙ нет нет.sizeof(x)
иsizeof x
. Запись в скобках всегда работает, а запись без скобок работает только иногда, поэтому всегда используйте запись в скобках; это простое правило для запоминания и безопасно. Это становится религиозным аргументом - я принимал участие в обсуждениях с теми, кто возражал раньше - но простота «всегда использовать круглые скобки» перевешивает любые преимущества их неиспользования (IMNSHO, конечно). Это представлено для баланса.Люди, использование ул п CPY (), ул н кошки (), или S п Е ().
Превышение вашего буферного пространства приведет к удалению всего, что следует в памяти!
(И не забудьте оставить место для завершающего нулевого символа '\ 0'!)
источник
strncpy()
. Это не "более безопасная" версияstrcpy()
. Массив целевых символов может быть излишне дополнен дополнительными'\0'
символами, или, что еще хуже, его можно оставить неопределенным (т. Е. Не строку). (Он был разработан для использования со структурой данных, которая используется редко, массив символов, дополненный до нуля или более'\0'
символов.)Строки также могут быть объединены во время компиляции.
источник
Также malloc и realloc полезны, если вы не знаете заранее, сколько строк объединяются.
источник
num_words>INT_MAX
, возможно, вы должны использоватьsize_t
дляi
Не забудьте инициализировать выходной буфер. Первый аргумент strcat должен быть строкой с нулевым символом в конце и достаточным дополнительным пространством, выделенным для результирующей строки:
источник
Как отмечали люди, обработка строк значительно улучшилась. Поэтому вы можете узнать, как использовать библиотеку строк C ++ вместо строк в стиле C. Однако вот решение в чистом C
Я не уверен, что это правильно / безопасно, но сейчас я не мог найти лучший способ сделать это в ANSI C.
источник
<string.h>
это стиль C ++. Вы хотите"string.h"
. Вы также рассчитываетеstrlen(s1)
дважды, что не нужно.s3
должно бытьtotalLenght+1
долго."string.h"
ерунда.#include <string.h>
правильно C. Используйте угловые скобки для стандартных и системных заголовков (включая<string.h>
), кавычки для заголовков, которые являются частью вашей программы. (#include "string.h"
сработает, если у вас нет собственного заголовочного файла с таким именем, но<string.h>
все равно используйте .)Неопределенное поведение - пытаться изменить строковые литералы, что-то вроде:
попытаюсь сделать. Он будет пытаться прикрепить
name
строку к концу строкового литерала"Hello, "
, который не очень хорошо определен.Попробуй что-нибудь такое. Он достигает того, что вы пытаетесь сделать:
Это создает буферную зону , которая будет разрешено модифицировать и затем копирует как строковый литерал и другой текст к нему. Просто будьте осторожны с переполнением буфера. Если вы управляете входными данными (или проверяете их заранее), можно использовать буферы фиксированной длины, как у меня.
В противном случае вы должны использовать стратегии смягчения, такие как выделение достаточного количества памяти из кучи, чтобы гарантировать, что вы можете справиться с этим. Другими словами, что-то вроде:
источник
Первый аргумент strcat () должен содержать достаточно места для объединенной строки. Поэтому выделите буфер с достаточным пространством для получения результата.
strcat () объединит второй аргумент с первым аргументом и сохранит результат в первом аргументе, возвращенный символ * - это просто первый аргумент, и только для вашего удобства.
Вы не получите вновь распределенную строку с объединенным первым и вторым аргументом, что, как я полагаю, вы ожидаете, основываясь на вашем коде.
источник
Лучший способ сделать это без ограничения размера буфера - использовать asprintf ()
источник
char *
, а неconst char *
. Возвращаемое значение нужно будет передатьfree
.asprintf
это только расширение GNU.Если у вас есть опыт работы с C, вы заметите, что строки - это только массивы символов, где последний символ является нулевым символом.
Теперь это довольно неудобно, так как вам нужно найти последний символ, чтобы добавить что-то.
strcat
сделаю это для вас.Таким образом, strcat ищет в первом аргументе нулевой символ. Затем он заменит это на содержимое второго аргумента (до тех пор, пока оно не закончится нулевым значением).
Теперь давайте пройдемся по вашему коду:
Здесь вы добавляете что-то к указателю на текст «TEXT» (тип «TEXT» - const char *. A pointer.).
Это обычно не работает. Также изменение массива «TEXT» не будет работать, так как он обычно помещается в постоянный сегмент.
Это может работать лучше, за исключением того, что вы снова пытаетесь изменить статические тексты. strcat не выделяет новую память для результата.
Я бы предложил сделать что-то вроде этого:
Прочитайте документацию
sprintf
чтобы проверить его параметры.А теперь важный момент:
Убедитесь, что в буфере достаточно места для текста и нулевого символа. Есть пара функций, которые могут вам помочь, например, strncat и специальные версии printf, которые выделяют вам буфер. Несоблюдение размера буфера приведет к повреждению памяти и удаленному использованию ошибок.
источник
"TEXT"
естьchar[5]
, нетconst char*
. Это распадаетсяchar*
в большинстве контекстов. По причинам обратной совместимости строковые литералы не являютсяconst
, но попытка изменить их приводит к неопределенному поведению. (В C ++ строковые литералы естьconst
.)Вы можете написать свою собственную функцию, которая делает то же самое,
strcat()
но ничего не меняет:Если длина обеих строк превышает 1000 символов, строка обрезается до 1000 символов. Вы можете изменить значение
MAX_STRING_LENGTH
в соответствии с вашими потребностями.источник
strlen(str1) + strlen(str2)
, но вы пишетеstrlen(str1) + strlen(str2) + 1
символы. Так вы действительно можете написать свою собственную функцию?return buffer; free(buffer);
sizeof(char) == 1
(кроме того, есть и другие более тонкие ошибки ...) Теперь вы понимаете, почему вам не нужно писать свою собственную функцию?free(buffer);
.free(buffer);
после того,return buffer;
как никогда не выполняется, увидеть это в отладчике;) Теперь я вижу: да, вы должны освободить память вmain
функцииПредполагая, что у вас есть char [fixed_size], а не char *, вы можете использовать один творческий макрос, чтобы сделать все это одновременно с
<<cout<<like
упорядочением ("скорее% s несвязанный% s \ n", "than", "printf стиль формата "). Если вы работаете со встроенными системами, этот метод также позволит вам исключить malloc и большое*printf
семейство функций, таких какsnprintf()
(Это удерживает dietlibc от жалоб на * printf)источник
источник
Вы пытаетесь скопировать строку в адрес, который статически выделен. Вам нужно кошку в буфер.
В частности:
... чик ...
место назначения
... чик ...
http://www.cplusplus.com/reference/clibrary/cstring/strcat.html
Здесь также есть пример.
источник
Это было мое решение
но вам нужно указать, сколько строк вы собираетесь объединить
источник
Попробуйте что-то похожее на это:
источник