LINUX.ORG.RU

Конкатенация в С/С++

 


0

2

Приветствую. Возникла задача условно говоря уложить все элементы массива в одну строку. Как делается конкатенация c добавлением в себя самого?

char *total;
gchar *str;
while (g_variant_iter_loop (iter, "s", &str)) {
// -----
total = total + str; // Надо все элементы str уложить в конец total
// -----
g_variant_iter_free (iter);
}

Пробовал через std:string, но оно чото сегфолтится с terminate called after throwing an instance of 'std::bad_alloc', так что лучше все таки простейшими С-функциями.

Благодарю.

★★★★★

Последнее исправление: Dimez (всего исправлений: 1)
Ответ на: комментарий от beastie

strcat, strncat, strlcat, malloc(total_len), много как можно.

Да.

Совсем обленились миллениалы!

Верно. Просто непривычно возвращаться с нормальных ЯП туда где есть такие детские болячки.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от windows10

«Нормальные» это которые не могут в эмбед? Вы спустились на уровень ниже и теперь жалуетесь, что у вас нет высокоуровневых инструментов.

Если у вас возникают вопросы «как саллоцировать память для суммы всех строк и поместить их одна за другой» - то С вам не нужен.

PPP328 ★★★★★
()
Ответ на: комментарий от PPP328

Если у вас возникают вопросы «как саллоцировать память для суммы всех строк и поместить их одна за другой» - то С вам не нужен.

Если у меня возник вопрос - я пришел и спросил как его решить. Вопроса о нужности или не нужности С в теме нет.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от Dimez

Он экранировал пробел в слове " С++", чтобы тот не считался за часть пробелов между словами, а ты зачем-то всё испортил, убрал пробелы вообще и добавил вместо них какой-то слэш.

firkax ★★★★★
()
Ответ на: комментарий от Bfgeshka

Есть варианты типа strcat(), но ты складываешь типы разные.

gchar это синоним char. То есть типы одинаковые

смотрим https://docs.gtk.org/glib/types.html#gchar

gchar

Equivalent to the standard C char type.

This type only exists for symmetry with guchar. The standard C char type should be preferred in new code.

и множество вопросов к ТС

  • почему люди использующие glib/gtk (qt/somelib) не читают оф.документацию
  • сколько надо выпить чтобы назвать переменную «char *total»
MKuznetsov ★★★★★
()

Забавно так наблюдать за тем, чем выше уровень входа в ЯП, тем больше дилетантов с разрывающимся пуканом, стремлению которых, закидать тебя тухлыми помидорами, можно позавидовать. Чувак, я в тебя верю! У тебя всё получится…=)

P.S> Как сказал @Bfgeshka - «Это Вам не пэхапэ»

Shprot ★★
()
Последнее исправление: Shprot (всего исправлений: 1)
Ответ на: комментарий от Bfgeshka

Ок, я подумал, что это какие-то стринги из glib.

стринги из glib «это другое» :-) https://docs.gtk.org/glib/struct.String.html

struct GString {
  gchar* str;
  gsize len;
  gsize allocated_len;
}

A GString is an object that handles the memory management of a C string.

и ТС должен был не ипать моск про char*, а их использовать в аккумуляторе. Заодно и избежит ошибок с realloc в конкатенации, судя по вопросам - там он точно упорется, и будет новая тема лор

Если уж glib и g_variant_iter_loop, то и прочие сущности оттуда брать, а не делать салат «тут переменная char*, рядом gchar, тут ещё какие-то»..на std::string уже замахивается.

MKuznetsov ★★★★★
()

Если конкатенаций в задаче много, то неплохой вариант вообще переаллокации физически не делать, char* хранить в списке и конкатенация - это добавление ссылки на уже имеющийся в памяти массив char. Естественно под это дело сделать свои функции ввода/вывода. Или собирать список в одну строку, когда нужно.

anonymous
()

По теме, как уже написали выше – strcat() и аналоги.

А что касается

Пробовал через std:string, но оно чото сегфолтится с terminate called after throwing an instance of ‘std::bad_alloc’

я так на всякий случай напомню: Пежо и Порше C и C++ это два разных языка. Хотя в плюсовый проект можно включать сишные файлы. Но у меня где-то в глубине души есть жуткое подозрение, что ты попытался сделать наоборот. Возможно, моя Ванга ошибается, но на то она и Ванга. :)

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от anonymous

Конкатенация в Java/PHP++

Приветствую. Возникла задача условно говоря уложить все элементы массива в одну строку. Как делается конкатенация c добавлением в себя самого?

Пробовал через java.lang.String, но оно чото падает по OOM, так что лучше все таки простейшими PHP-функциями.

Благодарю

lovesan ★★
()
Ответ на: комментарий от lovesan

RE: Конкатенация в Java/PHP++

Вы писали:

Приветствую. Возникла задача условно говоря уложить все элементы массива в одну строку. Как делается конкатенация c добавлением в себя самого?

Переходи на Лисп и будет тебе счастье! Да пребудет с тобой баланс скобочек!

anonymous
()

для си строк - то есть ноль терминированных массивов - strcat (что в переводе на общепонятный - string concatenate).

для всяких std::string - или функция append, или оператор +=

my_string.append("abc")
my_string += "abc";

для прочих релизаций строк в плюсах, иногда есть оператор <<

my_string << "abc"

короче плюсы - волшебный лес возможностей, в котором каждая красная шапочка найдет своего волка.

alysnix ★★★
()

Такие «знатоки» в треде, на одном гектаре не присядешь.

Раз написано с использованием glib, так и используйте glib. А там много чего есть. Вам нужна g_strconcat(). То же самое можно сделать и через g_strdup_prinyf().

akk ★★★★★
()
Последнее исправление: akk (всего исправлений: 1)

Почему бы не написать что-нибудь такое?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void strappend(char **str, const char *append)
{
    if (*str == NULL)
    {
        *str = malloc(0);
    }

    size_t strLen = strlen(*str);
    size_t appendLen = strlen(append);
    size_t newLen = strLen + appendLen;

    *str = realloc(*str, newLen + 1);

    memcpy(*str + strLen, append, appendLen);
    (*str)[newLen] = '\0';
}

int main()
{
    char *str = NULL;

    const char *array[] = { "Hello", " ", "World", ", epta", "!" };

    for (int i = 0; i < sizeof(array) / sizeof(*array); i++) {
        strappend(&str, array[i]);
    }

    printf("%s %ld\n", str, strlen(str));

    free(str);
    return 0;
}

strcat - гавно, нужно резервировать под него память, чтобы не было переполнения.

Skullnet ★★★★★
()
Последнее исправление: Skullnet (всего исправлений: 2)
Ответ на: комментарий от MOPKOBKA

Тогда так, потому что strlen NULL не жуёт.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void strappend(char **str, const char *append)
{
    size_t strLen = 0;
    
    if (*str)
    {
        strLen = strlen(*str);
    }

    size_t appendLen = strlen(append);
    size_t newLen = strLen + appendLen;

    *str = realloc(*str, newLen + 1);

    memcpy(*str + strLen, append, appendLen);
    (*str)[newLen] = '\0';
}

int main()
{
    char *str = NULL;

    const char *array[] = { "Hello", " ", "World", ", epta", "!" };

    for (int i = 0; i < sizeof(array) / sizeof(*array); i++) {
        strappend(&str, array[i]);
    }

    printf("%s %ld\n", str, strlen(str));

    free(str);
    return 0;
}
Skullnet ★★★★★
()
Ответ на: комментарий от Skullnet

Тогда так

O(N^2) из-за постоянных realloc() не смущает? Если уж так хочется в рамках C оставаться нужно делать примерно как господин @Psilocybe выше предложил. Там тоже не всё идеально, но по крайней мере без таких ляпов.

bugfixer ★★★★★
()
Ответ на: комментарий от etwrq

В данном конкретном примере имеем набор строк вся информация о длине которых это нуль на конце, почему использование strcpy тут неприемлемо, при том, что мы прошлись strlen и всё посчитали? Где тут UB?

Речь не одет о случает вообще.

Psilocybe ★★★★
()
Ответ на: комментарий от Psilocybe

Да всё там нормально у вас. Если что и крутить - от лишних strlen() избавляться: лучше делать их «до» и потом memcpy() (strcpy() там действительно ни к чему). Ну и zero-terminate‘ить один раз в самом конце.

bugfixer ★★★★★
()