LINUX.ORG.RU

Шок от С. Как склеивать строки?

 


13

7

Осваиваю си. Всё шло хорошо пока внезапно не понадобилось склеить строки (константные и переменные). Покурил stackoverflow. Предлагают 2 варианта:

Первый - создать char buf[молись_чтобы_хватило] и делать str(n)cat/sprintf в этот buf.

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

Вопрос: как вы склеиваете строки? Может есть какая-нибудь общепринятая либа?

Простите за нубский вопрос

★★★★★

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

Ответ на: комментарий от Xroft

Вам в сторону D смотреть нужно.

К чему это? Зачем ему смотреть в сторону Д? Почему не в сторону крестов?

Ну давай, чем это отличается от кростового

string result = s1 + s2;

и никакого геморроя.

И какой же геморрой в каком-либо другом ЯП с конкатенацией через плюсик?

Я верю, что ты не просто так это кукарекнул и сможешь мне ответить, а не сольёшься как 5-летняя балаболка.

anonymous
()

Ахренеть, царь вернулся и сейчас научит нас всех склеивать строки.

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

:) конечно играет

я делал читаемый код, в котором количество потребляемой памяти очевидно

вызывает сомнения код, в котором строки склеиваются при помощи перегрузки оператора +=, подозреваю, там большой оверхед по потреблению памяти

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

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

Ты знаешь значение слова «добавить»? Похоже нет.

	size_t bytesCount = sizeof(char) * (strlen(first) + strlen(second));

Не позорься.


	if(dest = malloc(bytesCount)) {

Просто гениально, гениально. Не позорься.

		memset(dest, 0, bytesCount);

Ведь реально непризнанный гений. Снова опозорился.

		strcat(strcat(dest, first), second);

Не, это не просто гений - это высший макаронный разум.

Я тебе задам тот же вопрос, о чем ты и чем ты думал, когда писал это убожество? Аргументируй каждую строчку, почему ты написал именно так?

anonymous
()

Почитал немного треда. Тебе все правильно рекомендуют. Что неправильно - твое (и некоторых других) восприятие.

Язык С иногда относят к языкам класса среднего уровня. То есть его положение - между языками низкого уровня и высокого уровня. Как и в языках низкого уровня, его инструментарий достаточно близок к тому, как это реализовано на уровне железа. Как в языках высокого уровня, он предоставляет достаточно много «облегчалок». Можешь рассматривать его как набор макросов к ассемблеру. Ты же не ноешь на предмет что ассемблер не умеет склеивать строки одной командой?

И, да, есть уйма библиотек, да ты и сам можешь написать функцию/макрос, которая это делает одной командой.

Если тебе нужен «высокоуровневый» C - это C++. Там ты можешь склеивать строки как str3=str1+str2;. И там ты не будешь знать, это null-terminated строка или нет, как и когда оно выделяет память и т. п.

/thread

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

я делал читаемый код, в котором количество потребляемой памяти очевидно

Что? В каком месте у его кода количество «потребляемой памяти» не очевидно? Ты же мне осилишь рассказать?

вызывает сомнения код, в котором строки склеиваются при помощи перегрузки оператора +=, подозреваю, там большой оверхед по потреблению памяти

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

могу оптимизировать по времени исполнения

Что ты там можешь?

вернее, у меня уже лежит на диске версия побыстрее

Куллстори. Ты же мне осилишь объяснить, а почему же ты её не привел сразу, раз она «уже была»?

Отмазоны типа «сижу с мобилы, а код дома», «я написал уже, но не запостил», «небыло времени» и прочее не работают. Написать и запостить нормальные 2строчки можно с мобилы за 20сек сидения в сортире. Время у тебя было - ты минимум час сидел и постил говно на лоре после поста своей «топфункции». Тут полнейший зашквар.

anonymous
()
Ответ на: комментарий от Kroz

Язык С иногда относят к языкам класса среднего уровня.
класса среднего уровня.
класса среднего уровня.
класса среднего уровня.

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

И чем же strcat() ближе к уровню железа, чем std::string::append(std::string const&)?

Ты же не ноешь на предмет что ассемблер не умеет склеивать строки одной командой?

Причем тут комманда? Их и не умеет склеивать и С++.

И, да, есть уйма библиотек, да ты и сам можешь написать функцию/макрос, которая это делает одной командой.

Какбэ я тебя удивлю, но С++ это делает написанной «функций» из либцпп. Сам С++ этого не умеет на уровне базового языка.

Если тебе нужен «высокоуровневый» C - это C++.

Датычё.

Там ты можешь склеивать строки как str3=str1+str2;

Это str3(str1.append(str2)) - это реализуется и на сишке, собственно как это реализовано в либкресты.

Другое дело, что кресты позволяют писать сахар из-за встроенной в ЯП перегрузкой операторов. Это никакого отношения к «уровню» языка не имеет, это никакого отношения к «одной комманде» не имеет и к теме треда тоже, собственно как и к вопросам автора.

И там ты не будешь знать, это null-terminated строка или нет, как и когда оно выделяет память и т. п.

Ну и? Любая сишная стринга позволяет тебе не знать это же.

Тебя никто не спрашивал - можно ли на сишке сделать конкатенацию через + - это единственное, чем отличается сишный и крестовый стринг, тред был и есть про другое.

/thread

Зачем вы приходите в тред, чтобы опозориться с умным видом? К чему это всё? К чему эти гнилые понты?

anonymous
()
Ответ на: комментарий от Kroz

Си нужен потомучто в его ABI умеют почти все остальные языки. Знаешь си - можешь в любом языке использовать сотни тысяч прекрасных сишных либ. Не говоря уже о низкоуровневых системных вещах, навроде GPU или dbus.

Если тебе нужен «высокоуровневый» C - это C++

Мне нужен высокоуровневый язык, но не C++. По субъективным причинам, о которых я уже писал. Есть множество разработчиков, разделяющих подобные взгляды относительно крестов.

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

Вот выкинут из него сборку мусора - тогда и посмотрим)

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

Мне нужен высокоуровневый язык, но не C++. По субъективным причинам, о которых я уже писал. Есть множество разработчиков, разделяющих подобные взгляды относительно крестов.

Ну возьми пример с Линуса, он с++ тоже не любит. Но subsurface пишет.

anonymous
()
Ответ на: комментарий от hobbit

K&R обязательно раскурю. Сначала надо проект закончить )

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

Ну возьми пример с Линуса

Первым делом, видимо, придется перестать писать на форумы и начать писать в мэйл-листы )

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

Первым делом, видимо, придется перестать писать на форумы и начать писать в мэйл-листы )

Я имел ввиду в плане выбора языка, но это тоже хорошая идея.

anonymous
()
Ответ на: комментарий от Legioner

Куча то чем не угодила?

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

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

И чем же strcat() ближе к уровню железа, чем std::string::append(std::string const&)?

Ты шутишь?

strcat() простая как бревно - просто копирует. Нет ни проверок переполнения, не выделения памяти, ничего «интеллектуального». Потенциальный генератор опасных и неочевидных багов, если ею пользуется человек только что прочитавший «Основы языка С».

std::string::append(std::string const&) сделает нужные проверки, выделит сколько надо памяти, предоставляет Strong guarantee в случае исключений.

Сам С++ этого не умеет на уровне базового языка.

Дай-ка определение понятия «базовый язык».

Другое дело, что кресты позволяют писать сахар из-за встроенной в ЯП перегрузкой операторов.

М-да. У тебя каша в голове.

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

Вот тебе для затравки - программа, выводящая одну строку:

$ wc -l simple.c.s 
29 simple.c.s
$ wc -l simple.cpp.s 
84 simple2.cpp.s

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

Мне нужен высокоуровневый язык, но не C++.

Но это и не С. Тогда ищи третий язык.

Я для себя когда-то решил, что мне нужен именно С++. Правда только годы спустя я понял, что C++ очень сильно отличается от С. Отличаются именно подход к программированию. C++ - это объекты, исключения, перегрузки операторов, потоки, контейнеры. В общем это отказ от Си-шных библиотек и использование библиотек C++. Это, с одной стороны, очень сильно облегчает жизнь; например, я не парюсь про выделение/освобождение памяти (утечки памяти - прощайте) и других ресурсов (защитники Java - привет), есть гарантия нормальной обработки ошибок при этом нет 100500 if'ов для проверки, вернула ли функция -1; нет монструозных конструкций для таких тривиальных вещей, как конкатенация строк (а есть и сложнее), а мета программирование - отдельная песня. Правда возникают другие проблемы; например, неплохо бы научиться правильно работать с исключениями (вот это - the must: https://www.youtube.com/watch?v=N9bR0ztmmEQ ). Неплохо бы подружиться с итераторами, шаблонами и вообще со стандартной библиотекой. Но это как сравнивать, что у неандертальца были проблемы с добычей пищи, а у современного человека - с качеством покрытия 3G.

То, что ABI несовместим я слышал, но мне это было ненужно.

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

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

char *concat

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

Правильный вариант:

char* contact
потому что это определение переменной contact, имеющей тип «указатель на char».

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

epic!

но мне интересно, а как надо писать вот такое, по твоему?

char *contact1, *contact2;

зы: не могу перестать угорать с s/concat/contact/ :D

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от i-rinat

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

int *iptr;
вместо логичного
int* iptr;
противоречит здравому смыслу и логике, что основательно выбешивает.

anonymous
()
Ответ на: комментарий от Dron

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

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

А вот хрен тебе! Такая запись — охрененный шанс на ошибку.

Сравни:

char *a, *b, c;

и

char* a, b, c;

Внезапно «забыли» сделать b указателем...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Так это и есть неправильно, если бы у Ричи и Кёрнигана руки бы росли из правильного места они не сделали бы такого противоречащего логике обозначения.

anonymous
()
Ответ на: комментарий от Eddy_Em

После 1000 комментариев я уже не смогу сюды пbсать.

Вроде как это ограничение только для анонимусов.

У тебя кстати когда начнут снова звёзды отрастать?

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

Ты у местного вахтера спроси. А то он что-то leave нас не хочет...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

char* a, b, c;

правильно:

char* a = …;
char* b = …;
char* c = …;
IRL к каждому объявлению неплохо дописать комментарий, хотя-бы короткий.

Это для C (не С++) конечно.

emulek
()
Ответ на: комментарий от Eddy_Em

А чтобы такого не было, нужно делать одно объявление на строку.

post-factum ★★★★★
()
Ответ на: комментарий от emulek

Длинно же!

Меня вообще ломает так писать. В итоге функция разрастается на пару-тройку страниц, из которых только одна страница — объявления переменных. Ну и нафиг? Если можно написать

char *a, b, *c, d, *e, *f, **g, **h, i, g, **k;
int ****l, ***m, **n, *o, ******p, **r, ***s, t, u, v, w;
double *x, y, ************z;
?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

double *x, y, ************z;

12-ти мерный массив? Ты в самом деле такое используешь в коде? Мне вот пока ни разу ещё не приходилось использовать больше чем три измерения. Стандарт языка C вообще какой максимум устанавливает?

anonymous
()
Ответ на: комментарий от Eddy_Em

P.S. Вспомнил чей-то доклад на конференции дофига лет назад. Там рассказывали про какую-то программку для визуализации многомерных данных. И отображали для наглядности визуализацию 30-мерного массива.

Так что, можно и сто звездочек нарисовать при желании...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Длинно же!

насрать.

И да, а если платят за строчки?

Если можно написать

а зачем тебе вообще объявлять столько переменных в начале функции? Тяжёлое детство с паскалем?

emulek
()
Ответ на: комментарий от anonymous

Стандарт языка C вообще какой максимум устанавливает?

вроде никакого. Мне как-то понадобилось int*****.

emulek
()
Ответ на: комментарий от Eddy_Em

Там рассказывали про какую-то программку для визуализации многомерных данных.

да, нужно, но там делается узлы, которые имеют связи с неким количеством других узлов. Ну например Kademlia может считаться DHT внутри 128и мерного пространства, на 128и мерном гиперкубе. Как наверное всем известно, все 8 вершин трёхмерного куба могут быть записаны как числа 000, 001, 010, 011, 100, 101, 110 и 111. В Kademlia используется 128и битная md5 сумма. Всего таких вершин очевидно 2¹²⁸, но почти все пустые, всего заполнено около 2²⁰ вершин.

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

emulek
()
Ответ на: комментарий от anonymous

Фигня. Достаточно один раз понять, что вначале пишется базовый тип, а дальше идет декларатор. А вот «контактенация» - вот это проблема)

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

это отказ от Си-шных библиотек

утечки памяти - прощайте

есть гарантия нормальной обработки ошибок

мета программирование

Взбугагнул над каждым высказыванием

как сравнивать, что у неандертальца были проблемы с добычей пищи, а у современного человека - с качеством покрытия 3G

Чисто для информации - около 1/3 современных кроманьонцев заняты (full-time) в производстве пищи, больше 1 млрд это т.н. subsistence farmers, люди которые живут только со своей земли

anonymous
()
Ответ на: комментарий от Kroz

деление языков на низкого, среднего, высокого [уровня] было следствие маркетинга 60ых гг

попав в образовательную машину это стало туфтой.

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

если дистанция мала язык низкого уровня для данного исполнительного устройства

если языку программирования для трансляции(и или рантайма) требуется большое число команд исполнительного устройства то язык считается языком высокого уровня.

по факту термины язык (низкого|среднего|высокого) не имеет чёткого определения что так примечательно для маркетинговых целей.

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

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

многоукладная мир-экономика фигли.

нет нужды в тотальном хайтеке.

да и опасно ибо неустойчивость.

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

Взбугагнул над каждым высказыванием

Поэтому пойди пока почитай букварь, пока дяди тут поразговаривают.

Kroz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.