LINUX.ORG.RU

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

 


13

7

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

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

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

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

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

★★★★★

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

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

В общем, это то, во что транслируется объявление динамического массива. Они все располагаются на стеке, соответственно, выделение памяти под массив - это всего лишь беззнаковое вычитание из указателя стека. На x86 то же самое

...some calculations with result in R15...
sub sp, r15

Да, в эпилоге функции будет увеличение sp на длину массива.

И какая разница, переставляет компилятор переменные, и выделяет ли место в стеке для них вообще?

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

не не не

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

как заместо компилятора это делать вручную это второе.

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

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

для теоретиков, использующих микроконртоллер от практиков, использующих микроконтроллер

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

если критично и memcpy этого не умеет, то при больших строках подкручу dma, переключу процесс. правда, до сих пор этого никогда не приходилось делать.

работа с кучей (кроме как при инициализации) на контроллерах без mmu вообще моветон, к тому же стек не резиновый, да и вообще память очень быстро кончается

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

Динамические массивы в языке появились только в С99. До того была изобретена функция alloca(). В общем-то, особой разницы, фиксированные или нет массивы на стеке, нет. Единственное, о чем нужно позаботиться - это сохранение и восстановление указателя стека при входе в функцию/возврате из нее

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

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

emulek
()

Что люди только не придумают, лишь бы не использовать символ точки для конкатенации, как в нормальных языках. Ппц сколько проблем на ровном месте.

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

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

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

Боюсь, что rust умрёт раньше си.

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

Если массив короче на один элемент, то не спасет даже sprintf.

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

Что люди только не придумают, лишь бы не использовать символ точки для конкатенации, как в нормальных языках. Ппц сколько проблем на ровном месте.

ты упоролся? Для операции «точка» нужен специальный тип «строка». А в сишке такого типа НЕТ, есть только «указатель на char». При этом char определён как «что-то типа целого, размером 1». IRL он может быть из любого количества бит.

И да, этот «указатель» может указывать на что угодно. Например в никуда, или на 1 char, или на 123 char'а. И нет никакой возможности узнать, на сколько char'ов указывает указатель.

emulek
()
NSString *stringOne = @"Hell";
NSString *stringTwo = @" world";
NSString *stringThree = @[NSString stringWithFormat:@"%@%@",stringOne,stringTwo];
NSLog(@"%@",stringThree);

Hell world

anonymous
()

Склеенных строк не существует. Есть только жалкая их имитация.

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

Меньше символов - не обязательно проще. А если один и тот же символ означает дофига всего, это уже усложнение. Я всегда уверен, что «+» в objective c означает сложение чисел. встретив «+» в c++ мне предстоит прогулка по коду, что-бы узнать что же это такое.

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

Длиннее и непонятнее. Куча лишних символов, скобки квадратные, двоеточие. Монструозно все. Ты всерьёз это сравниваешь с s1 +s2?

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

Зачем тебе гулять по коду? Если ты пишешь на C++, то знаешь, что такое + для std::string

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

встретив «+» в c++ мне предстоит прогулка по коду, что-бы узнать что же это такое.

«+» в этом плане ничем не отличается от названия обычной функции. Даже название concatenate_one_std_string_with another_std_string_and_returns_new_std_string_instance не даст тебе больше информации. И тем более не гарантирует ничего.

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

Отвечу сразу на все.

Длиннее и непонятнее.

Дело привычки. Квадратные скобки и двоеточие универсальный синтаксис и применим ко всему. «+» же непонятно как работает без прогулки по коду. Для std::string известно заранее, но как быть с другими классами? Ты действительно думаешь, что куча значений для «+», «&», «[]», "()", «*», ".", и прочего, делает язык проще?

Даже название concatenate_one_std_string_with another_std_string_and_returns_new_std_string_instance не даст тебе больше информации.

даст точно уж больше чем «+».

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

даст точно уж больше чем «+».

Нет, это как раз дефолтное ожидаемое поведение для «+». То, что описывать не надо. Что для чисел, что для строк, что для матриц и т.д. А вот «stringByAppendingString», например, ничего не говорит о том - вернет функция новую строку, или добавит к существующей.

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

Разве в objc мутабельные строки?

А вот это как раз то, что надо узнавать в документации. Речь очевидно шла про более общий случай чем строки в objc.

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

Квадратные скобки и двоеточие универсальный синтаксис и применим ко всему. «+» же непонятно как работает без прогулки по коду.

Так ты и числа так складываешь?

Для std::string известно заранее, но как быть с другими классами?

А что с ними? Ты же знаешь, что используешь, правда?

Ты действительно думаешь, что куча значений для «+», «&», «[]», "()", «*», ".", и прочего, делает язык проще?

Там возможны два варианта. Или операторы являются естественными для данного типа в общепризнанной нотации(или языковой, как в случае << и >> для ввода-вывода в C++) и тогда проблем никаких нет. Или операторы вводятся для формирования некоего EDSL, который будет описан в отдельной документации, что так же не приводит к проблемам. Так что да, это делает язык более выразительным, а код на языке более читаемым.

Я больше люблю Scala, чем C++, если что.

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

Отвечу сразу на все.

Там, кстати, разные анонимусы.

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

Речь очевидно шла про более общий случай чем строки в objc.

в общем случае, в objc намного понятнее, что делает код, по сравнению с C++.

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

Если хочешь сравнивать плюсы и objective c, попробуй покодить на обеих языках. По себе знаю, что это очень не комфортно смотреть в код и постоянно ждать подвоха от () или +, после работы на objective c.

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

в общем случае, в objc намного понятнее, что делает код, по сравнению с C++.

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

map<string, int> m;
...
m["str"] = 1;
...
m["str"]++;

Можешь даже не делать в своем «понятном objс» фиксированные типы ключей и значений. Ведь это понятности то не добавит и особо не нужно ;) Ну и надеюсь, ты не будешь жульничать.

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

Если хочешь сравнивать плюсы и objective c, попробуй покодить на обеих языках. По себе знаю, что это очень не комфортно смотреть в код и постоянно ждать подвоха от () или +, после работы на objective c.

Так уже, насчет «подвоха от () или +» - ты либо чрезмерно мнительный (реально куда вероятней попасть на недокументированную особенность работы сторонней функции или баг в ней), либо не пишешь сам свой код в своих проектах, а работаешь на подхвате или мелочевке всякой. Я угадал?

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

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

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

Что люди только не придумают, лишь бы не использовать символ точки для конкатенации, как в нормальных языках. Ппц сколько проблем на ровном месте.

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

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

не буду. literal syntax для мутабельных контейнеров в objc нету, поэтому только так:

NSMutableDictionary *m = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@1, @"str", nil];
int incrementedValue = [[m objectForKey:@"str"] intValue]+1;
[m setValue:@(incrementedValue) forKey:@"str"];
waker ★★★★★
()
Ответ на: комментарий от anonymous

ps: про вот это не понял, что ты имел ввиду, и зачем такое делать:

Можешь даже не делать в своем «понятном objс» фиксированные типы ключей и значений.

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

и кстати, если тебе нужен map<string,int> — в objc++ это тоже работает. думаю, оно будет эффективнее во многих случаях, чем родные контейнеры corefoundation, если тебе не надо работать с objc-объектами.

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

в общем случае, в objc намного понятнее, что делает код, по сравнению с C++.

Работал. Вынужден не согласиться. На C++ хуже читается только отсутствующие в objc шаблоны, но такой код находится или в библиотеке или в ..эм.. в базовых частях проекта, куда редко лазают.

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

По себе знаю, что это очень не комфортно смотреть в код и постоянно ждать подвоха от () или +

А в чем подвох-то? Я на обоих языках пишу. C++ понятнее как-то чисто синтаксически.

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

не буду. literal syntax для мутабельных контейнеров в objc нету, поэтому только так:

Не совсем аналог (я специально не использовал список инициализации), но и на нем видно - никакой понятности и читабельности objc не дает даже на самых простых операциях. Слишком много слов (которые по сути не отличаются от того, что написал бы К.О.) и слишком мало сахара. В принципе Apple это сама признала, когда представила всем более удобный и простой swift. А больше крупных пользователей ObjC то и нет.

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

я тож пишу на обоих, и мне понятнее и приятнее objc. видимо, смотря что на нем писать (я на нем только гуету под cocoa пишу).

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