Только тогда сам прекращай писать про криворуких и прочий бред, ага?
>> Я писал про то, что str(n)cat использовать может только камикадзе. В тех случаях, когда применимо использование этих функций, ВСЕГДА лучше вместо них использовать strlcat.
Ну или g_strlcat, по ситуации. Аналогично про str(n)cpy, который ещё кривее str(n)cat. В ряде случаев ещё лучше будет использовать функцию с семантикой, аналогичной strl-функциям из солярки (биздишный вариант копирует не вылезая за размер буфера с завершающим нулём, соляркин -- если суммарный размер строк больше буфера, не меняет содержимое dst).
Вариант strncat и вариант Дрепера с mempcpy не лезут ни в какие ворота в силу того, что размер буфера, передаваемый в функции, для нормальной работы должен быть на 1 меньше реального размера, что не соответствует вызову, например, snprintf.
> Только тогда сам прекращай писать про криворуких и прочий бред
да я вроде и не делал таких заявлений, может вы меня спутали с другим, но хорошо - буду следить за собой
> Вариант strncat и вариант Дрепера с mempcpy не лезут ни в какие ворота в силу того, что размер буфера, передаваемый в функции, для нормальной работы должен быть на 1 меньше реального размера, что не соответствует вызову, например, snprintf.
точно также можно сказать, что snprintf не лезет ни в какие ворота, так уж вышло - и приходится просто помнить этот ньюанс, т.к., как я уже писал, лучшего варианта в libc нет( почему лично мне strlcat не нравится - я уже упоминал )
> Они ограничены размером буфера, про который всё известно заранее.
А ввод пользователя ещё экранировать надо. Ну бывают иногда ситуации, когда размер данных неизвестен.
> Кошмар ) Надеюсь, вы несерьёзно.
Случаи бывают разные. В тех случаях, где применимы strn?(cat|cpy) -- применимы и strl(cat|cpy), причём использование последних предпочтительнее. Они применимы не всегда, но сделаны они прямо, в отличие от. Замучался уже повторять, ей-богу.
> точно также можно сказать, что snprintf не лезет ни в какие ворота
Не-не-не. У snprintf/strlcat/strlcpy и прочего семантика логичнее -- мы передаём размер, больше которого получить не должны ни в каком случае. strncat и Дреперовский вариант -- передаём размер, на один меньше размера буфера. Нелогично. (Про strncpy я вообще молчу -- оно просто не гарантирует завершение нулём)
> лучшего варианта в libc нет
Ну так в libc много чего нет... А что есть -- порой через задницу сделано как минимум в одном варианте из более-менее распространённых.
> почему лично мне strlcat не нравится - я уже упоминал
Тем, что в любом случае изменяет dst, или я перепутал? Ну так возьми соляркин -- он работает в предложенном тобой стиле. Для записи в лог вполне подходит биздишный вариант, для более ответственной работы лично я бы всё равно предпочёл работать без фиксированных буферов, пожалуй.
У strl(cat|cpy) правильная идея -- они соответствуют по параметрам другим стандартным функциям, они предоставляют возможность проверить на переполнение, они гарантируют корректное завершение строки. Это именно то, как должны были бы выглядеть strn-функции.
>У strl(cat|cpy) правильная идея ... они предоставляют возможность проверить на переполнение
возвращая длину результирующего ввода которая будет вычиляться _всегда_ даже если приемный буфер всего пара байт а на ввод поступило пара килобайт - формируй такие длинные вводные строки искуственно и вот тебе готовое решение для отказа в обслуживании.
> возвращая длину результирующего ввода которая будет вычиляться _всегда_ даже если приемный буфер всего пара байт а на ввод поступило пара килобайт - формируй такие длинные вводные строки искуственно и вот тебе готовое решение для отказа в обслуживании.
Да-да, очень реальная ситуация... При таких расхождениях проблемы с производительностью вылезут гораааздо раньше, если подобный финт ушами не был предусмотрен. В реальной жизни, естественно.
Впрочем, ладно. Специально тебе я разрешаю использовать strcat и strncat, только с одним условием -- каждый раз, когда использование этого приведёт к проблемам, ты будешь съедать по свежекупленной шляпе.
Санитары тут причем ? По существу есть что сказать ? Или ты не согласен что если оказалось по какой-то причине siz == 0 и результирующий буфер был не NULL terminated то твое утверждение неверно ? Мысль Дреппера была прямой и понятной - strl ф-ции не решат проблем а завуалируют создав новые.
> Или ты не согласен что если оказалось по какой-то причине siz == 0
По какой причине? Что значит -- "оказалось"?!
> и результирующий буфер был не NULL terminated то твое утверждение неверно ?
Если бы у бабушки были усы...
Бред сивой кобылы. Попросил записать не больше 0 байт -- тебе столько и записали. Если бы ты сказал записать 0 байт -- а тебе записали 1 байт, то именно это и есть фигня, баг и проблема, а не наоборот.
Дрепер несёт чушь, не моргнув глазом, ты за ним повторяешь. strl-функции не создают ни одной проблемы сверх str(n), причём пачку их проблем, наоборот, решают.
Учись не слепо следовать за авторитетами, а иногда думать своей головой. Ошибаются все. И Дрепер, и Торвальдс, и Кокс, и Тео де Раат, и Дилан, и МакКузик, и... Кого там из признанных гуру позабыл?
> В твоих поделках все буферы статические заранее известной длины
o_O А в твоих -- нет?! Статический буфер неизвестной длины?!
> и ты всегда можешь передать ее константой sizeof ?
o_O А ты не можешь?!
> чушь несешь ты, на котрую я больше реагировать не намерен.
У-тю-тю. Ты хоть своими словами-то способен озвучить хоть одну проблему strlcat, которой нет у strncat? Обратную ситуацию в рамках этого треда я озвучил уже раз 10.
Не можешь? Записываешься в почётные golodranez'ы и отправляешься строевым шагом служить Родине единственным доступным способом. 8))
Статический буфер в динамической памяти? О, сколько нам открытий чудных...
> Видимо не дано тебе понимать нормальную речь.
Ты сам себя-то хоть понимаешь? 8)))
> читай то что было написано ранее в этом треде.
Т.е. нет ни одной такой проблемы у strlcat, которой не было бы у strncat? Так я это и так знаю, и талдычу для альтернативно одарённых уже в пятнадцатый раз. В обратную сторону неверно, опять-таки в пятнадцатый раз повторяю. И ещё в пятнадцатый раз: из этого следует, что нет ни одного оправдания использованию strncat при наличии strlcat в обозримой OSS-вселенной. Использование strcat частенько оправдано, но не уровне компетентности автора поста (и некоторых комментаторов, ога).
PS: да, можешь не подписываться перед каждой своей фразой, я тебя и так узнаю.
можешь продолжать паясничать и коверкать фразы - умней ты от этого даже не кажешься, наоборот - неумело хочешь скрыть отсутствие элементарных знаний
>нет ни одной такой проблемы у strlcat, которой не было бы у strncat
>знаю, и талдычу
талдычишь и даже не пытаешься читать то что пишут другие, а проблем как минимум 3 уже озвучено
>PS: да, можешь не подписываться перед каждой своей фразой
дебил - это не подпись а ты, но если настаиваешь, я больше не буду писать про это, ты и так теперь знаешь это :)
Я говорил про статический буфер или всё-таки ты? Я потом вдруг резко начал говорить пр динамическую память или всё-таки ты? Ну и кто тут паясничает?
> умней ты от этого даже не кажешься, наоборот - неумело хочешь скрыть отсутствие элементарных знаний
У-тю-тю, даже сам себя ты понять не в состоянии, а ещё чего-то пыжишься... 8))))
> талдычишь и даже не пытаешься читать то что пишут другие, а проблем как минимум 3 уже озвучено
Ну так ты озвучь эти три проблемы в одном месте своими словами, топливо. Третий комментарий пытаюсь от тебя добиться этой газификации, всё бестолку, даже газификация у тебя выходит какая-то беспредметная. 8))
PS: ну я же просил -- не надо подписываться, там одну подпись движок сайта вставляет, её достаточно.
memcpy -- стандарт, mem_p_cpy, которую предлагает использовать Дрепер -- 'This function is a GNU extension.'
Впрочем, основная проблема там всё-таки в необходимости странно передавать размер буфера, а именно на 1 меньше действительного. По крайней мере, я не вижу ни одной причины использовать такой вариант. Это число (размер буфера - 1) имеет какой-то странный физический смысл. Это ни размер буфера, ни максимальное кол-во для записанных байт...
> Впрочем, основная проблема там всё-таки в необходимости странно передавать размер буфера, а именно на 1 меньше действительного. По крайней мере, я не вижу ни одной причины использовать такой вариант. Это число (размер буфера - 1) имеет какой-то странный физический смысл. Это ни размер буфера, ни максимальное кол-во для записанных байт...
Это длинна строки без учёта '\0'. По идее, эту функцию удобно применять при конкатенации строк.
Это понятно, но использовать именно это значение -- нелогично и противоречит, например, snprintf/strftime. Строки в C не бывают без завершающего нуля. По определению.
> По идее, эту функцию удобно применять при конкатенации строк.
DESCRIPTION
The mempcpy() function is nearly identical to the memcpy(3) function. It copies n bytes from the object beginning at src into the object pointed to by
dest. But instead of returning the value of dest it returns a pointer to the byte following the last written byte.
This function is useful in situations where a number of objects shall be copied to consecutive memory positions.
А У. Дреппер - весьма своеобразная личность, есть такое =).
В смысле, mempcpy? Ну, в принципе, да. Но лучше делать в виде функции с семантикой strl-функций. Явно необходима сигнализация "обрезания", а то фигня выходит. И использовать размер буфера удобнее.
> А У. Дреппер - весьма своеобразная личность, есть такое =).
А они все такие. 8)) Что Линус, что Тео, что Мэт...
>Один хрен, использовать strn?(cat|cpy) -- диверсия. Дальше каждый выкручивается как хочет, strl-функции -- просто одно из готовых рабочих проверенных решений.
А слабо
strncat (s1, s2, BUFSIZE-1);
s1[BUFSIZE-1] = 0;
?
Или BSD отучает мыслить, но предоставляет "готовые проверенные решения"?
>Вариант strncat и вариант Дрепера с mempcpy не лезут ни в какие ворота в силу того, что размер буфера, передаваемый в функции, для нормальной работы должен быть на 1 меньше реального размера, что не соответствует вызову, например, snprintf.
Я тут немного man почитал. n — это количество символов от конца строки dst до конца буфера в dst. Так что семантика очень даже правильная и полностью соответствует семантике snprintf'а, который, кстати, тоже не будет писать завершающий нулевой байт, если размеров буфера не хватит.
>Кстати, за использование здесь констант
Кстати, за незнание аргументов strncat можно было бы и со стыда покраснеть ;)
A simple implementation of strncat() might be:
char*
strncat(char *dest, const char *src, size_t n)
{
size_t dest_len = strlen(dest);
size_t i;
for (i = 0 ; i < n && src[i] != '\0' ; i++)
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
return dest;
}
malloc придумывали для других ситуаций, когда усечение результата неприменимо. Уймись уже, бывают места, где не столь важно, урезана ли строка или нет. 8))
> в любом месте, где применимы strn-функции, лучше их не использовать, нет?
для любого места - strl заменяет один баг( segmentation fault ) на другой( ошибка в логике работы программы ), как по мне второе ничем не лучше и даже опаснее, так как труднее отлавливается и может привести к порче данных
> для любого места - strl заменяет один баг( segmentation fault )
Нет там sigsegv'а. Там некорректное завершение строки, которое ловится ничуть не проще, чем обрезание.
> на другой( ошибка в логике работы программы )
(тяжко вздыхая) Выходим на сто первый круг. Нет ошибки в логике программы, там допустимо обрезание строки или там есть проверка переполнения. Точка. strl-функции позволяют корректно сделать как и допустимое обрезание, так и проверку, не обрезан ли результат.
> как по мне второе ничем не лучше и даже опаснее, так как труднее отлавливается и может привести к порче данных
Если там действительно косяк, и использовать str(n|l) никак нельзя -- то в случае strn последствия хуже. И обнаруживаются не проще, ага. Хрен редьки не слаще, но strl чуть-чуть вкуснее.