LINUX.ORG.RU

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

 


13

7

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

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

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

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

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

★★★★★

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

а это не философия, это реальность, строки надо не только генерировать, но и отдавать, хранить и передавать, да-да, ты прекрасно осведомлен, просто напоминаю

а этот тред - про их конкатенацию на языке C. тоже просто напоминаю.

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

и все несовместимы друг с другом :)

Что понимать под совместимостью? QString, например, умеет в/из std::string и std::wstring. Как и различные кодировки. Этого недостаточно?

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

а этот тред - про их конкатенацию на языке C. тоже просто напоминаю.

когда я пришел в тред - ты уже рассуждал на другую тему, тоже просто напоминаю

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

ВНЕЗАПНО: есть php написанный на сишке

Ты упоролся? Предлагаешь, если нужно в программе на Си конкатенировать строки, отказываться от Си и писать на тормозящем php?

Сишкак как раз и нужна, если задача _нестандартная_.

Я тебя разочарую, большинство кода - стандартные. И как раз stl собирает в себе инструменты для решения стандартных задач, при том, вполне удачно.

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

нет, это конвертация. дополнительный оверхед. в нормальных языках — строковой тип 1, и его используют все программы.

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

когда я пришел в тред - ты уже рассуждал на другую тему, тоже просто напоминаю

что и сейчас делать продолжаю. отвечая на вопросы анонимов. хотя тема C++ мне вообще неинтересна.

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

и все несовместимы друг с другом :)

Отлично совместимы, через всё тот же const char *.

потому что есть libc, которого вполне достаточно. и это хорошо.

И это тред - результат достаточности :)

Прямо как у Высоцкого:

сорок душ посменно воють,
раскалились до бела
во как сильно беспокоють
треугольные дела
(с) :)

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

нет, это конвертация. дополнительный оверхед. в нормальных языках — строковой тип 1, и его используют все программы.

Это очевидно не случай С и С++. По различным и очевидным причинам.

anonymous
()

а ты их в нужном формате в поток выводи, в чем проблема?

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

Какой ты толстый

Блин, я бегло и неверно прочитал твой пост, решил, что ты имел ввиду, что calloc всегда не malloc + memset, извини.

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

Там того оверхеда ничтожно мало, тем более по сравнению с «нормальными языками».

invy ★★★★★
()
Ответ на: может быть ты ответишь на вопрос от wakuwaku

Я не специалист по тредам, но судя по коду (strlcat, strlcpy) должно быть thread safe.

PS: в линуксах оно, оказывается, доступно через libbsd.

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

А ты видел промышленные научные приборы, которые в количестве > 1 экземпляра нафиг никому не вперлись?

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

Вот так всякой хренью занимаешься, а на науку и времени не остается!

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

Там написано про ситуации в которых память не очищается. Хм? Я всегда считал, что так и поступает calloc, память может быть уже обнулена.

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

Какой ты толстый [1, 2]

Ну так и есть: calloc = malloc + memset

Ты какой-то тупенький, а не толстый.

mix_mix ★★★★★
()
Ответ на: просто меня смущает от wakuwaku

Здаётся мне, что Эдик путает нитебезопастность и атомарность.

Все эти функции нитебезопастны, т.к. у них нет внутреннего состояния. Вызвав одну и туже функцию два раза на разных данных, то каждая будет работать со своими данными и не смешивать их.

Но все эти функции так же не атомарны — если мы начнём, во время их вызова, менять им входные данные, то и получим кашу на выходе.

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

Собственно, про то и вопрос, та же strtok опасна в этом отношении, а в бсдшных манах это явно не оговаривается и не ясно, чего ждать.

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

А где было про атомарность?

И каким раком memset может быть атомарным? Офигительно, конечно, было бы атомарно обнулить пару гигов оперативы...

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

Во-во. Надо будет свою c-cgi-lib обновить, как буду очередную веб-морду делать: заменить все strtok на эти, т.к. собираюсь на вебсокеты переходить, а там не принцип "1 клиент == 1 процесс", а потоки. Т.е. уже обычную strtok использовать нельзя будет.

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

Офигительно, конечно, было бы атомарно обнулить пару гигов оперативы...

А не через mmap ли это и COW по пейджфолту делается?

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

А где было про атомарность?

Тут:

strlcpy() — потокобезопасна?

Нет, конечно. Если кто-то начал менять буфер во время хоть strcpy, хоть memcpy, на выходе получишь черт-те что. Это ясно.

В общем, я к тому, что если подходить с этой стороны, то вообще ни одна функция, работающая с более чем одним байтом, не «потокобезопастна». (Хотя на самом деле речь про атомарность.) И не важно, что там в мане стоит.

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

Можно еще один нубский вопрос? Чем отличются

const char* s =  "Sabakabarabaka";

и

char s[] = "Sabakabarabaka";

У первого sizeof s == 8. У второго - 15

makoven ★★★★★
() автор топика

Очень просто же

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

int main(int argc, char* argv[])
{
    char* stringOne = "123";
    char* stringTwo = "321";
    int resultStringSize = strlen(stringOne) + strlen(stringTwo) + 1;
    char resultString[resultStringSize];
    int charIndex = 0;
    for (int i = 0; i < strlen(stringOne); i++) {
        resultString[charIndex] = stringOne[i];
        charIndex++;
    }
    for (int i = 0; i < strlen(stringTwo); i++) {
        resultString[charIndex] = stringTwo[i];
        charIndex++;
    }
    resultString[charIndex] = 0;
    printf("%s", resultString);
    return 0;
}
anonymous
()
Ответ на: комментарий от anonymous

Для еще большей оптимизации замени циклы на while и вычисляй strlen внутри них

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

Первое — это указатель на строку, и имеет соответственно размер указателя. Второе — это массив, и размер соответсвующий.

Две разные сущности. Не надо их путать с array decay (_[] -> *_), который происходит при передаче аргументов в функцию.

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

for (int i = 0; i < strlen(stringOne); i++)

И сразу же получаем O(n^2). Кстати, может знает кто, какой-нибудь компилятор уже научился оптимизировать такой говнокод?

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

отличаются типом. 1й указатель, 2й массив.

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

кто-нибудь из компиляторов умеет оптимизировать такой говнокод?

вероятно, если использовать restrict char *stringOne

но лучше не полагаться на компилятор.

(в конкретном примере выше, это указатель на константную строку, и компилятор это знает, но сумеет ли оптимизнуть, или нет - хз)

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