LINUX.ORG.RU

Правильный(???) стиль работы со строковыми данными на С

 ,


2

4

Иногда (прямо сейчас) приходится обрабатыавть строки на C.
Меня коробит от громоздкости операций выделения памяти, конкатенации и самое главное это snprintf с проблемой размера буфера под конечную строку, гигантское поле для выращивания вских мемориликов по невнимательности.

К примеру, размеры mult1_str, mult2_str и equal_str известны, нужно выделить память под всю строку:

snprintf(
    buf,
    buflen,
    "%s miltilple %s equals %s",
    mult1_str,
    mult2_str,
    equal_str
    );
варианты:
- махнуть шашкой и сделать килобайт на стеке ( ((( )
- ничем не размахивать и посчитать руками. (еще хуже)
- написать функцию которая будет вычислять длину «%s miltilple %s equals %s» без символов подстановки (уже лучше)
- отказаться от snprintf и собирать строку пачкой конкатенаций с аллокациями памяти и прочим...

А как делаешь ты?


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

Ядру линя 25 лет

от того ядра что было 25 лет назад практически ничего не осталось а С живее всех живых и перехода на современные языки не предвидится.

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

предлагает переписать тонны легаси

еще одиин идиот - какое легаси ? это самое современное коммерчески успешное ядро ОС.

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

Они там еще переписывают иногда важные подсистемы, модернизируют ядро постоянно, могли бы уже начать новое делать, по настоящему шовременное!

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

А у Оракла самая коммерчески успешная СУБД. Знаешь сколько в ней легаси? Чини словарь.

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

коммерчески успешная СУБД. Знаешь сколько в ней легаси?

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

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

У вас либо какое-то очень странное представление о программировании микроконтроллеров и о высокоуровневых языках, либо его полное отсутствие.

Ну вот самый простой пример: тебе надо обращаться напрямую к конкретным адресам оперативной памяти… Большинство высокоуровневых языков тебе такой возможности не предоставляют.

Какие, назовите их. Хотя бы понимание того что C++ может всё что может C у вас должно быть? Про unsafe в rust слышали? Про inline assembler в микропитоне может и не слышали, так будете знать. При этом современные языки гораздо более выразительны чем убогий сишный (volatile uint16_t*)0x123 которым наверняка ограничивается всё ваше знание, и позволяют более точно указывать семантику регистра, а значит получать более оптимизированный код.

Или, к примеру, runtime-среда не имеет механизма динамического выделения-управления памятью, без чего использование высокоуровневых языков просто в принципе не прокатывает…

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

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

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

пример будет или опять болтовня ?

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

обычно не пишу ничего фанатикам, но мне интересно реакция на такой вопрос.. на чем сложнее писать — на Си или на крестах?

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

Подсказка: он в строке

size++; /* For '\0' */

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

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

Не согласен. Результат vsnprintf в случае успеха должен быть ниже второго параметра.

Что-то мне подсказывает, что ты даже не понял, в чём там потенциальный баг.

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

пример будет или опять болтовня ?

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

Спрашиваешь совета на stackoverflow по крестам в микроконтроллерах, получаешь массу идиотских говнорешений, даже человеку, что последние пятнадцать лет на жёстком высоком уровне работал с высокими нагрузками, а до этого ещё десяток в лютом энтерпрайзе, ясно, что так писать нельзя, в итоге он пишет сам на С++ и, что характерно, правильно, в отличие от горе-плюсовиков. Получается крестоводы сами топят за то, чего сами же толком не знают? Лично я, к воинствующим крестоводам отношусь с опаской, писать код не умеют, а бред несут.

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

Что характерно, у меня коллега на Qt пишет, мировой чел, и кодит прилично, так вот, он в программисты из менеджеров пришёл, возможно потому у него и иммунитет. Сейчас, например, на Андроиде под явкой пишет, без всяких выпендрёжей! Он единственный нормальный плюсовик, которого я знаю лично. С остальными(хорошими) я знаком только по их коду в котором ковырялся/правил. Остальные знакомцы — сраные елитарии и нарцисы, выдающие свой говнокод, за божественное откровение.

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

... Хотя бы понимание того что C++ может всё что может C у вас должно быть? ...

Ну вот мне, например, очень нравится C# - писал на нём код за денежки. Или к примеру, если речь пойдет о backend-е, то, пожалуй Golang возьму - из-за встроенной асинхронности работы с сокетами и наличия изначально встроенных в язык «зеленых» потоков. И на С++ очень много писал, и свой и чужой Cи-шный код приходилось и дорабатывать и использовать (это иногда дает понимание того, что есть задачи чисто для C) - всё тоже не для себя, а за денежки. Ну вот я почему-то не лезу в чужие темы с выступлениями типа «ваш язык - говно, а вы все - чудаки»... Всякому языку своё место. Ну давайте еще Oracle на Питоне перепишем! ))))))))))

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

Не путайте понятия «высокоуровневый язык» и «высокоуровневое программирование». Когда вы пишете строчку типа «str1 = str2 + str3», в процессе её выполнения для сохранения значений переменных используется не стек - память выделяется динамически (иначе она очень быстро закончится). Когда вы используете плюсовый new-оператор, то память под объект тоже выделяется динамически.

Если есть память, её можно выделять динамически

Можно написать код, который будет реализовывать этот функционал, но пишется такой код не на C++ и не на Питоне )))

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

Ну вот мне, например, очень нравится

Мне наплевать что вам нравится. Я задал конкретные вопросы, ответов я не увидел.

Всякому языку своё место

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

Когда вы пишете строчку типа «str1 = str2 + str3», в процессе её выполнения для сохранения значений переменных используется не стек - память выделяется динамически

Для начала, о какой именно реализации строк вы изволите столько снисходительно разглагольствовать?

Можно написать код, который будет реализовывать этот функционал, но пишется такой код не на C++ и не на Питоне )))

Этот код, как и любой другой, пишется и на C++ и на питоне.

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

Этот код, как и любой другой, пишется и на C++ и на питоне.

Судя по вашим выступлениям у вас отсутствует нормальное профильное образование и такая область деятельности как «системное программирование» для вас просто пустой набор слов. Я вот вам привел ссылочку на проект micropython-а. Вот идите туда и рассказывайте авторам, что они все дураки...

Это просто верх дебилизма - активно пользоваться продуктами, написанными на C, и при этом утверждать, что этот язык абсолютно не нужен!)

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

ядерные функции работы с файлами имеют в качестве параметра имени файла — нультерминальные строки

Ну отлично, и что мешает хранить счётчик рядом со строкой, а таким функциям выдавать только строку?

snprintf(path_buf, PATH_MAX, «%s/%s.%d»...

Конкретно в данном случае вопрос ТСа не актуален именно по причине того что есть заранее известный PATH_MAX, т.е. изобретать ничего не надо. Вопрос состоял в том как получить этот размер если он не известен. Так вот ИМХО лучше всего заранее иметь счётчик, т.к. при получении строки откуда-нибудь мы всё равно считаем байты.

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

Писать просто на всём. Сложнее чтоб оно потом работало и от кода не тянуло блевать.

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

ядерные функции работы с файлами имеют в качестве параметра имени файла — нультерминальные строки

Да, говнокод начинается уже с ядра.

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

Ну если для тебя проблема следить за данными и ты считаешь что код должен перемалывать любой мусор который ты ему даёшь то дааа. Давай ещё динамические строки с GC в ядро засунем.

Deleted
()
Ответ на: комментарий от no-such-file

Конкретно в данном случае вопрос ТСа не актуален

И что, у getpid() есть .lenght() ?

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

На это тут уже ответили. Есть, правда, маленькая проблема, на говномамонтных libc snprintf возвращает -1, а не длину, если размер буфера меньше, а asprintf — вообще чисто GNU-тое.

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

Если ты много писал на C++, то давно можешь ответить на вопрос - что можно сделать на C, что нельзя на C++. Или нельзя на Rust. Но от тебя ничего кроме лозунгов. Как раз таки свойственных людям без «нормального профильного образования».

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

Ветку разговора вообще читал? Там было про хождение по строке в поисках нуля в каждой из вложенных функций и на каждой итерации. Это не угарно в критичном для производительности ядре, какой там гц.

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

Если ты много писал на C++, то давно можешь ответить на вопрос - что можно сделать на C, что нельзя на C++ ...

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

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

То есть по сути у вас возражений нет, я понял. Вся аргументация «но на C же что-то написано!».

Ok, тогда продолжим возить вас лицом по _вашему_ профильному образованию. Я жду ответа

Для начала, о какой именно реализации строк вы изволите столько снисходительно разглагольствовать?

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

ссылку дал на конкретный C-шный проект

Микропитон? Ты выше микроконтроллеры привел как пример ниши для C, теперь сам приводишь проект, дающий другой, более удобный язык для этой ниши (хотя и до тебя его тут приводили). Ты там определись внутри себя. Или ты думаешь что программист на микропитоне пишет на самом деле на C?

Еще драйвера упоминались, ну так не только их, а целые ядра на C++ пишут, если это для тебя новость.

Если у вас профессиональных знаний не хватает

Для постоянных съездов на личности надо бы свою компетентность сначала показать. В этом треде от тебя вообще никакой технической конкретики.

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

Вся аргументация «но на C же что-то написано!»

так у тебя никакой аргументации вообще - «я не пишу на С значит он не нужен!»

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

Вся аргументация «но на C же что-то написано!»

так у тебя никакой аргументации вообще - «я не пишу на С значит он не нужен!»

Э не, у него аргументация другая «кто пишет на С, тот не нужен»

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

более удобный язык для этой ниши

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

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

Если питон дорог - берем кресты

ты уже написал хоть один драйвер для Linux на питоне или крестах ?

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

Вы там с тезисами определитесь. «Не могу взять язык, жена/начальник/Линус не позволяет» - не то же самое что «на языке нельзя решать эти задачи».

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

«Не могу взять язык, жена/начальник/Линус не позволяет» - не то же самое что «на языке нельзя решать эти задачи»

разумеется не то же самое, повторю вопрос - ты уже написал хоть один драйвер для Linux на питоне/крестах ? я разрешаю.

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

я не знаю чем там бсд пользуется, но в его манах asprintf есть

Да наздоровье. Это придумано в GNU. В posix - нет, значит полагаться на универсальность нельзя.

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

То есть по сути у вас возражений нет, я понял. Вся аргументация «но на C же что-то написано!».

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

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

Микропитон? Ты выше микроконтроллеры привел как пример ниши для C, теперь сам приводишь проект, дающий другой, более удобный язык для этой ниши (хотя и до тебя его тут приводили). Ты там определись внутри себя. Или ты думаешь что программист на микропитоне пишет на самом деле на C?

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

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

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

«пчёлы против мёда»

«неосиляторы против профессионалов» скорей всего.

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

Нет, я вообще против многобайтных кодировок в консоли. В pdf, ясен пень, хоть UTF64 пусть запихивают. Но в терминале и текстовых файлах — только КОИ8-Р или другая однобайтная кодировка.

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

Ниша есть? Есть, сам признал.

Ниша для чего? Для уровня хеллоуворлд? Я не против, как я уже сказал, автор микропитона — молодец. Вообщем-то, и для несложного проектика вполне подойдёт. Но если это как средство мастурбации для удовлетворения, типа лишь бы не на «треклятом Си», то да, сам я точно воздержусь. Но коли кто-то только так может удовлетворяться, да хер с вами, я не против, лишь бы меня в эту секту не зазывали.

А с эмоциями сам иди лесом.

Какие тут эмоции, голые факты и опыт.

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

Там вроде был корявенький закос, а также отдельным пакетом полный слой совместимости (с какой-то древней версией). Теперь в неё просто Убунту запихнули, так что всё норм.

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

Теперь в неё просто Убунту запихнули

Вот этого маразма не понимаю: зачем в мастдайку впихивать другую мастдайку? Ведь бубунту даже линуксом язык не поворачивается назвать: до того она анально огорожена!!11

anonymous
()

Почему бы не попробовать работать со строками на языке, более подходящим для этого? Скажем на lua или на guile? Они, насколько мне известно, дружат с Си. С помощью такого подхода можно быстро добавлять требуемые фичи, не заморачиваясь с выделениями памяти и прочими прелестями низкоуровневого языка.

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

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

Просто не пользуйся хрюникодом и будет тебе счастье!

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