LINUX.ORG.RU

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

 


13

7

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

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

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

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

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

★★★★★

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

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

< Неужто в середине юникодовой строки может попасться нулевой байт?

а как ты думаешь, в UTF-16LE, например, ляжет символ 'A'?

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

Учи матчасть, школьник.

во первых STRLEN и РАЗМЕР по байтам строки-две разные вещи

Равны, если не считать нулевого символа.

с приходом unicode-размер чара зависит от кода символа в unicode таблице-это чар от 1 байта(ascii) 2 байта-русские 3-арабские 4-японские/китайские и до 8 байтов сейчас на 1 чар

Размер char — один байт, всегда. Unicode — таблица соответствия символов кодам. У Unicode есть “transformation points”, которые определяют, как эти коды будут преобразовываться в байты. То, что ты высрал — сколько байтов (char´ов) занимают символы разных алфавитов в UTF-8.

РУССКОГО ПРОБЕЛА(символ)

Не существует такого символа.

тоесть чтоб получить размер STRLEN плюс посимвольную длину-надо составлять КАРТУ строки где будет записана длина побайтово

и после этого только-объеденять строки

и длина(в байтах) \0 символа равна длине последнего символа в строке(если в gcc собирать) либо равна длине максимально большого символа в строке(visual studio

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

Иди лечись.

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

А про «сбоить все функции программы из за утечки памяти в логический исполняемый код» он разве не прав?

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

Слава богу в вебе utf8

LOL, в вебе может быть все что угодно.

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

утечки памяти в логический исполняемый код

What.

Если он про недовыделение одного байта под \0 — да, прав; но по этой шизофазии я этого не понял.

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

Ну типа памяти под строку мало и строка наслоится на код и этот код похерится, а процессор все-равно будет его выполнять. Или как-то так. Я в таких дебрях не разбираюсь

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

CHAR_BIT говорит о размере самого char, но все остальные размеры должны плясать от него. Каким бы ни был CHAR_BIT, sizeof(char) == 1.

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

Там sizeof(char) возвращает 2.

Значит компилятор там не соответствует стандарту.

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

6.5.3.4 The sizeof operator

3 When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

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

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

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

ну не настолько гранулировано (хотя тз разные)

но по типу куски которые чреваты утечками выносить в отдельные процессы которые по возможности рестартить

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

еще один смотрящий со своей высокой башни,раз ты не видел значит такого нет

все что я отписал в том посте постигнуто на личном опыте

то что ты описал-полный бред из доков с мсдн-а которые с реализацией не имеют ничего общего,вообще ничего

то как реализована работа с utf в висуалстудии и сколько там методов под одну функцию для разных номеров символов(с 0 по 128 одна функция с 128 по 256 другая и дубликаты всех функций от стрлена до стрцпи(ага вызывается два раза если даже в 1 строке есть цифры и буквы))

я знатно погорел на этом-я сделал проект низкоуровневая оптимизированная библиотека UI(поверх винапи конечно) надо было для встраиваемых утсройств(винxp) все было готово и все тестовые примеры работали,началось юзание-и оказалось что при вводе текста иногда происходят разные невероятные вещи,при вводе и выводе(но про вывод я допер позже)
код был просто идеален по всей теории msdn и k&r...я перековырял весь мсдн вдоль и поперек и таки нашел там ПОМЕТКИ что нельзя использовать strcpy для объеденения строк и что все функции со строками в си и кодировке отличной от ascii использовать нельзя
у меня решилось тем что я просто заменил всю кодировку на карту символов(введя внутренний char где нет бардака с байтами)

и да у меня есть рабочий пример того что я описал(да в банальном hello world у вас не будет описанных багов,нужно все немного сложнее сделать)-где при сборки программы в студии(любой версии,там все криво по прежнему) не выпадет ни 1 варнинга,сборка без утф8(но запуск обязательно в русской винде,в английской не сработает(даже с русским вводом)),все работы со строками будут по заветам k&r но из за магии винды-чар не будет одним байтом и стрлен будет выдавать невероятные результаты...и баги будут поистенне невероятны-вплоть до выхода в память видеодрайвера и артефакты на экране...при сборке через gcc программа просто крашиться при выходе за границы размеров char[](выход из за кривых подключаемых библиотек винды,подключаемых gcc) а вот через студию-нет

у меня есть пофикшенный пример,но вернуть все взад могу(хоть и было лет 5 назад),по памяти восстановлю,плюс убрать лишний код...кода на 1000 строк гдето должно быть,отпишите емайл кто интересуется скину,за разумное вознаграждение(ибо код таки показывает неприкрытую уязвимость в винде)

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

Едрить наркоман.

еще один смотрящий со своей высокой башни,раз ты не видел значит такого нет

Я знаю, что такое UTF-8 и как оно конвертируется в байты. Ты этого не знаешь. man utf-8.

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

На практике существуют платформы, на которых CHAR_BIT > 8.

Это вполне возможно.

Пример: DSP-процессоры TI C54x. Там sizeof(char) возвращает 2.

Ссылка на документацию есть?

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

я говорю не про утф8,я говорю про РЕАЛИЗАЦИЮ криворукими индусами этого всего в винде,а что реализация невероятно кривая и позволяет получать полный контроль над системой...вобщем обычный эксплоит на уровне системы,банальный пример-эксплоит с спец номером мак адреса приводящий к передаче исполняемого кода(снаружи) в ОС-такойже но причина-это именно strcpy в винде...я уже и так много сказал-используя strcpy можно выходить на уровень прав администратора из любых прав...

я говорю именно про реализацию а не абстрактную чушь КАК ОДНО ДОЛЖНО БЫТЬ,и реализация не имеет ничего общего с теорией,НИЧЕГО,ничегошеньки

всем «студентам» кто читает-вся ваша теория идет в Ж в первый день работы

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

Это абсолютный бред

Это абсолютно полный, развернутый ответ, выдающий в тебе человека неконфликтного и здравомыслящего

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

Очевидно, что у кого-то из нас логика не работает, но это не проблема логики.

vlad9486
()

Этот, казалось бы, простейший, нубский трэд мне кажется весьма эпичным и достойным анналов! Ведь по нему мы узнаём кучу интересных вещей:

1. До сих пор есть люди, не знающие про «ноль-в-конце-строки»; куда мог попасть их говнокод - боюсь представить.
2. Есть десяток функций, алгоритмов и оговорок к ним, но при этом никто так и не представил надёжное, верное решение. Другими словами, даже на ЭЛЕМЕНТАРНЕЙШЕЙ операции (к слову, используемой сплошь и рядом в каждой программе) Си сливает всем - уже потому, что не имеет одной стандартной функции и заставляет приседать с памятью. Ну что, теперь вы очень гордитесь своим «ручным контролем памяти»? Понравилось тривиальщину решать десятком строк кода? Ну-ну, а ведь за главный алгоритм вы ещё даже не брались, погрязши в говнокоде посторонних операций - вот и считайте цену своим «ебибайтам» и «микрогерцам» - стоит ли ваш убогий десяток микросекунд просраного времени.
3. При этом в ЛЮБОМ трэде «Сишечка/сипипишечка VS нормальный язык» найдётся свой студент/кретин/тролль/мечтатель, который с пеной у рта будет защищать этот высокоуровневый говноассемблер как единственное решение для геймдева/эмбеда/интыпрайзов. При этом даже понятия не имея, какую долю процента все эти области занимают в жизни _типичного_ программиста.

Я это всё к чему? ПОВЫШАЙТЕ УРОВЕНЬ - ПЕРЕХОДИТЕ НА ДИ. Язык не должен на каждом чихе макать вас в низкоуровневую хрень, есть задачи поважнее! И Линукс, будь у него комьюнити поумнее/постарше, давно бы форсировало переход от таймбомб си/сипипи к надёжным программам на Ди - уж там точно не нужно маяться внутренним устройством утилитарщины.

Я даже больше скажу: Ди не просто «Си++-подобный» брат-близнец, типа Жабы - Ди имеет море других возможностей, которые вообще выше на уровень всей сишной плоскости: mixins, CTFE, closures, вменяемое ООП, юнит-тестинг (встроенный). Да ещё и удобный синтаксис а-ля C# (в отличии от символьных костылей сипипи, от которых в глазах мельтешит).

Если слушать каждого дилетанта (или того хуже - профессионала) в С++ - так вообще других языков не надо! Но костыльность С++ не исчезает увещеваниями «в наших сипипях всё можно» - и на ассемблере ВСЁ можно, да только нужно ли? Программирование уже давно перестало быть хобби для гиков - это промышленный сектор и в нём давно пора работать на результат, а не развлекать себя сипиписными выкрутасами.
Линукс только выйграет от того, что программы станут надёжнее и писáться быстрее. Мешают переходу костолобые гики со знаниями из 70-ых, да легаси-говнокод, который «жалко выкидывать».
Дай бог в 2015 начнётся хоть какое-то поумнение социума!

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

Я даже больше скажу: Ди не просто «Си++-подобный» брат-близнец, типа Жабы - Ди имеет море других возможностейЯ даже больше скажу: Ди не просто «Си++-подобный» брат-близнец, типа Жабы - Ди имеет море других возможностей

говно короч

anonymous
()

Для неженок которые стесняются использовать strncat и трусов стесняющихся использовать asprintf есть open_memstream !

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

Ди не просто «Си++-подобный» брат-близнец, типа Жабы

Ди просто помершее говно. С++14, Go, rust в конце концов.

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

Логично, что её там не будет и будет это не посикс система.

Какбэ стандарт определяет не наличии функции, а наличие рабочей функции. Если её нет - стандарту не соответствует и логичней в такой ситуации её выпилить вообще, чем вставлять заглушки.

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

которые вообще выше на уровень всей сишной плоскости:
mixins

LOL, лалки не осилили множественное наследование и теперь кукарекают.

CTFE

Он хотя бы гарантируется, как constexpr, или как звезды сложатся?

closures

уже не аргумент

вменяемое ООП

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

юнит-тестинг (встроенный).

единственный плюс

а ещё и удобный синтаксис а-ля C# (в отличии от символьных костылей сипипи, от которых в глазах мельтешит).

да практически такой же синтаксис, уже не знаешь, что бы еще придумать

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

Есть десяток функций, алгоритмов и оговорок к ним, но при этом никто так и не представил надёжное, верное решение

Юникс вей же, предоставляй механизмы но не стратегию.

ЭЛЕМЕНТАРНЕЙШЕЙ операции (к слову, используемой сплошь и рядом в каждой программе)

нет, эта операция нужна весьма редко в сферах применения C.

3. При этом в ЛЮБОМ трэде «Сишечка/сипипишечка VS нормальный язык» найдётся свой студент/кретин/тролль/мечтатель, который с пеной у рта будет защищать этот высокоуровневый говноассемблер как единственное решение для геймдева/эмбеда/интыпрайзов. При этом даже понятия не имея, какую долю процента все эти области занимают в жизни _типичного_ программиста.

в этом треде есть один студент/кретин/тролль/мечтатель, который всех на Ди желает пересадить, а человек который преподносит сишку как единственно верное решения не наблюдается, следовательно, утверждение (3) не верно.
Для геймдева/интыпрайзов юзайте Ди всякие, для эмбеда, драйверов, ядер сишку.

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

Обсуждалась гипотетическая ситуация, когда time возвращает NULL. Было предположение, что NULL все таки может возвращать

какая-нибудь POSIX-совместимая ОС на микроконтроллере, которая не может в системное время?

Она вполне себе может работать и фейлить иногда (батарейка на часах села).
Вообще это может показаться придиркой, но я просто защищал точку зрения, что проверять на NULL нужно всегда, если стандарт такое значение допускает, иначе не будет переносимости.

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

(к слову, используемой сплошь и рядом в каждой программе)

Веб-погромист что ли?

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

D - это как вкусный тортик с вишенкой, но в самом его центре кусочек гуано под названием «сборщик мусора»

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

Но все же sizeof(char) может быть полезным. Вот придется когда-то изменить char на что-то длиннее, и программист будет с матами искать где бы еще умножить на sizeof(foo).

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

Вот придется когда-то изменить char на что-то длиннее

Если есть такая вероятность, то лучше сразу typedef'чик завести и делать везде sizeof.

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

Но все же sizeof(char) может быть полезным. Вот придется когда-то изменить char на что-то длиннее, и программист будет с матами искать где бы еще умножить на sizeof(foo).

преждевременная пессимизация еще хуже чем преждевременная оптимизация

anonymous
()

Рай для велосипедистов. И ад для тех, кому просто нужно выполнить прикладную задачу. Да и С++ не намного лучше.

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

даже на ЭЛЕМЕНТАРНЕЙШЕЙ операции (к слову, используемой сплошь и рядом в каждой программе) Си сливает всем

Сливает не столько язык, сколько убогая стандартная либа из каменного века, набыдлокоденная какими-то неандертальцами на коленке.

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

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

что то типо

macra_getints(size-1) int x[1];

ну и правдо int имя[1] тож наверно внутрь макры где имя аргумент

ибо вдруг стек не вниз на данной железке :)

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

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