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 и собирать строку пачкой конкатенаций с аллокациями памяти и прочим...

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


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

может ли попасться

Повторяю: префиксный код.
Ни один из 0..127 не может являться частью другого кодированного символа (хотя бы потому, что у них у всех взведен старший бит, хотя все еще немного сложнее).

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

Потом возьмут да опять закроят куте ваш.

Ха-ха три раза. Поезд ушёл. Qt под LGPL. Можешь поинтересоваться у корпорации ORACLE, как она пыталась закрыть OpenOffice и MySQL и как красиво пролетела по обоим пунктам.

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

А, т.е. на этот счёт всё же есть некоторые гарантии? Фух, а то по мне холодок пробежался. Я помню конечно что-то из стандарта на эту тему, но это было давно и неправда, и мне тут говорят что нельзя проверять на однобайтные ascii символы побайтово (что в общем-то очень эффективно, если сравнивать с любой альтернативой).

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

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

Deleted
()

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

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

А ты на С много писал? Интересно стало.

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

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

import subprocess
c=1
while c<=127:
  z=subprocess.call("echo -n '\\x20\\x%02x=(' $'\\x20\\x%02x'')\n'"%(c,c), shell=True)
  c+=1
linuxnewbie
()
Ответ на: комментарий от linuxnewbie
import subprocess
c=1
while c<=127:
  z=subprocess.call("echo -n '\\x%02x\\x20=('$'\\x%02x\\x20'')\n'"%(c,c), shell=True)
  c+=1

ой, ну в общем наоборот тоже работает

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

лишний пробел в затесался, жаль нельзя редактировать сообщения

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

Вот интересный сайт, но мне не хватило терпения дождаться загрузки клинописи и прочих мёртвых языков. Что там может быть? Есть ли реальная вероятность, что проблемы могут быть? Реальная в том плане, что CJK в тексте всё же может нарисоваться, стоит ли переживать? https://unicode-table.com/ru/

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

явный баг, влекущий UB при определённых условиях

Возврат пустой строки? Под ноль память выделили, но не инициализировали. Вот лишнюю проверку что-то не нахожу. Или неужто vsnprintf не может вернуть ошибку, если первый раз выдало успех?

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

использую haskell...

Haskell использует ясли для хранения временных данных. Тоже неплохой подход для сей - некоторые с этой целью делают глобальные буферы (на каждый поток).

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

А потом оказывается что начальство к которому ты пришёл с кляузой на человека наказало этому человеку писать модуль ядра и тебя увольняют через минуту.

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

Вы детский сад устроили тут какой-то: «мой папа твоему папе морду начистит». У вас своя голова есть, или за вас начальство думает?

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

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

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

просто популярен среди продвинутых аутистов

Эмм, если обвиняешь в том что я делаю детский сад, будь добр не устраивай его сам, а то выглядит как наглое лицемерие. И с чего ты взял что кто-то из нас карьерист? Не наговаривай.

А сраться по поводу С vs C++ мы с ним начали ещё до этого треда, так что ты просто не в курсе контекста :D

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

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

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

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

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

В конце-концов, на C пишут не потому, что это хороший язык, а потому что он просто популярен среди продвинутых аутистов.

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

vinvlad ★★
()

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

Так напиши свои строки, чо как паскалист.

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

Qt не приложение

Сервер БД (MySQL) тоже как бы не совсем приложение, и у него тоже есть свой API. Ничего, дистрибутивы хором переползли на Марию, после чего торговая марка MySQL стала мало кому интересна.

у них все может получиться

Если они решат прокукарекать «я устал, я закрываю» — время появления форка будет измеряться даже не в днях, а в часах. У сообщества, ИМХО, уже иммунитет к таким вещам. Если что и погубит Qt, то это не закрытие, а дурость разработчиков (например, если они внезапно решат отказаться от QtWidgets, но пока что у них хватает ума этого не делать).

Да и вообще Qt уже несколько раз переходила из рук в руки. Самый критичный момент был, когда Нокия продалась мелкомягким. Ничего, Qt выделили в отдельую компанию. (Хотя Nokia — большая компания, я точно не помню, владело ли кутями именно продавшееся подразделение.) В любом случае, опыт выживаемости в условиях нетехнических угроз у Qt имеется.

hobbit ★★★★★
()

По теме — я не настоящий сварщик (работаю на крестах, а на Си если только патчу чо-то мелкое и крайне редко), но в 2019 году, если вдруг приспичит писать на Си, скорее всего, буду копать в сторону GObject (ex-GLib). Если очень сильно поплохеет, напишу свои (но это в очень крайнем случае). Своё имеет смысл писать только если нужно будет что-то минималистичное.

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

Но зачем притягивать за уши дурацкий глиб, пытаясь из С сделать ООПщину, когда и на нормальных сях все по-человечески можно написать?

Те же строки в КОИ8-Р на С парсятся элементарно. А хрюникодофилы пусть страдают, хрюникод в командной строке не нужен, как и в текстовых файлах!

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

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

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

просто побайтово сравниваете символы

В unicode так делать нельзя.

Да что ты говоришь! А ну-ка, выкинь свой говнистый хрюникод-8 и переходи на хрюникод-32! Там фиксированно 4 байта на символ. И можно сравнивать.

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

Кстати да, тут tradeoff скорость/простота vs занимаемый обьём в памяти. В utf-8 лучше «сжимать» при сохранении, а потом «разжимать» при загрузке.

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

скорее всего, буду копать в сторону GObject (ex-GLib).

gobject/glib убъет кроссплатформенность, и превратит код в мясо. лучше не писать конечно код на C, если действительно нужно ООП. но и C++ до добра не доведет, да и собственно не решает он нужные проблемы. по большому счету он не настоящее ООП, и просто наворачивает слой гсахара поверх сишных типов. настоящее, правильное, и действительно полезное ООП есть в objc и swift, и у последнего есть все шансы стать по настоящему кроссплатформенным.

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

gobject/glib убъет кроссплатформенность, и превратит код в мясо

По второму пункту догадываюсь, о чём речь. Первый не понял. На каких платформах нету GObject?

если действительно нужно ООП

Да собственно, ТС, если я его правильно понял, хочет не «ООП вообще», а всего лишь человеческую работу со строками. И не только он. В частности, хотелось бы не проверять память перед КАЖДЫМ чихом и обеспечить нормальную обработку при длине символа больше одного байта. Второе вроде бы как решается принудительным развёртыванием в 4-байтные символы (хотя я где-то читал, что в современном хрюникоде для каких-то случаев уже и этого не хватает), с первым хуже.

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

Владимир

https://github.com/harbour/core кроссплатформенный: hbapi.h, hbjson.h, hbhash.h, hbapicdp.h, hbmsgreg.h, hbmath.h, hbatomic.h, ...

Добавляю в него иногда API и нет потребности в других библиотеках.
Правда не только https://github.com/harbour/core использую.

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

На каких платформах нету GObject?

по умолчанию ни на каких. несколько лет назад даже на андроиде не было (сейчас не знаю).

Да собственно, ТС, если я его правильно понял, хочет не «ООП вообще»

ну это я не ТСу писал, а конкретно тебе.. особенно если ты с GObject еще пока не сталкивался, но тебе кажется что он может решить какие-то проблемы :)

waker ★★★★★
()

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

Свои строки со счётчиком. Дефолтные с нулём всё равно не годятся ни для чего сложнее хеловорда.

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

Свои строки со счётчиком. Дефолтные с нулём всё равно не годятся ни для чего сложнее хеловорда.

Желаю вам всю жизнь писать, например, имена файлов с количеством символов в них.

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

всю жизнь писать, например, имена файлов с количеством символов в них

Зачем? Длина литерала известна на стадии компиляции.

no-such-file ★★★★★
()

Тред не читал. Со строками на Си всегда надо помнить про «алгоритм маляра Шлемеля» и поступать соответственно. Для единичных применений сойдет «string.h», если программа только и делает, что работает со строками - то свой велосипед или что там модно (потому что куча нюансов, заканчивая icu).

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

Зачем? Длина литерала известна на стадии компиляции.

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

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

Да, всегда фейспалмлю когда затирают про «быструю сишечку» когда там часто такой говнокод со строками.

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

Правильного способа нет.

В этом всё, что вам нужно знать о сишечке.

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

Эдик, а ты случайно не топишь за UTF-32, как саахрикту, который тоже сначала казался поехавшим, а на деле он оно как оказалось?

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

А сраться по поводу С vs C++ мы с ним начали ещё до этого треда

О каком сраче может идти речь, если вы даже не программист.

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