LINUX.ORG.RU

А как комфортно работать со строками в современном C++?

 , ,


0

8

Привет, ЛОР.

Старый добрый std::string, как мы знаем, это по сути char* на стероидах. А во многих случаях надо работать со строками именно как со строками текста.

К примеру, в библиотеке QtCore, входящей во фреймворк Qt, есть класс QString. Её часто ругают за изобретение велосипедов. Но именно благодаря этой «фабрике велосипедов» я могу написать, например, так:

QString s;
QStringList sl;
...
if (sl.contains(s, Qt::CaseInsensitive)) {
    ...
}

И оно мне проверит наличие строки в списке, причём регистронечувствительным (второй параметр) способом. И не только для латинских символов. То есть если в списке есть «Капибара», в строке подойдёт как «Капибара», так и «капибара». Ещё есть split(), join() и дофига полезного.

А как такое сделать без QtCore, на голом STL? В C++20 появился некий std::u8string, он мне поможет, например?

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

в ублюдочном Юникоде, который превратился из 2х байтового чара в ICU

Если бы юникод оставался двухбайтовым, мы бы имели обиженных китайцев, чьи иероглифы в первой версии юникода унифицировали с японскими. Поэтому переход на 4 байта был обусловлен объективно.

Вот отказ от фиксированной длины это уже был неоправданный перебор, который всё попутал. Эмодзи, символы фекалий и всё такое – это дискредитация юникода как способа записи текста и типографских символов разных языков. Пусть разными алфавитами, пусть с вымершими языками, но всё-таки текста. Насколько я понимаю, 4 байт на символ бы для этого хватило с запасом.

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

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

Как тут не вспомнить вечнозелёный рассказ про топологию

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

«таков путь»

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

«отверстие для дефекации» в стандарте объективное отражение реальности

идеализм не панацея

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

неа - там проблема имхо именно в том что хоть языки и обусловленны Хомско лаконичностью

но сама запись не факт что не протеворичива промеж нотаций

т/е универсальность vs самосогласованность

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

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

Иероглифы - это отсталая форма передачи информации, которая должна была отмереть вместе с австралопитеками, в 21 веке возможен только алфавит, который имеет постоянное и фиксированное количество символов. При всей любви к дорогим китайцам, но им или переходить на алфавит, или пользоваться какой-то другой кодировкой, которая никака несовместима с алфавитами.

Такой подход сохранил бы чистую, простую и понятную систему. Пусть это было всё в ASCII совместимом utf-8, никаких проблем. Но всё пошло по неправильному пути. Не знаю, его нужно сжечь и сделать нормально

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

Ото ж… Помню, его публиковали в журнале «Наука и жизнь» ещё тех времён, когда меня на свете не было, от деда достались.

Название перевели немножко скучно, «Лист Мебиуса». В оригинале было «A Subway Named Moebius», правильнее было бы, наверное, «метро имени Мёбиуса» или «подземка имени Мёбиуса».

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

Современный С++ концептуально не отличается от С++ 89 года разлива или даже раньше. Это все тот же С с классами — читай язык про двигание чисел в регистрах и байт в памяти с попыткой в zero-cost абстракции по типу ООП. Это макро ассемблер на стероидах, эдакий конструктор. Именно поэтому только в плюсах (и сишке) ты найдешь миллиард реализаций строк и прочих контейнеров и алгоритмов — потому что это язык про это, про абстракции вокруг байтодрочки, а не решение скучных повседневных задач.

Ну а юникод — это просто позорище. Если utf-8 кодировку еще можно назвать вменяемым ответом на проблему экономной пересылки символов разных алфавитов, но сам юникод с его сраной компоновкой глифов… Зато с вишенкой 🍒 говна 💩 на торте 🎂.

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

А при чём тут языки, если проблема в рендеринге глифов, которые заведомо не встретятся на практике иначе как в целях вот таких залго-извращений? Тут ещё нужно смотреть, как в самих шрифтах запрограммирована обработка сочетаний глифов. Даже в твоём примере можно заметить, что отдельные последовательности глифов шрифт пытается выстроить в удобочитаемом порядке, но в общем случае такое он не решит. И тут никакая кодировка не поможет: мы же хотим сделать отдельный глиф для буквы и отдельные глифы для акцентных знаков. А если оставить только буквы с акцентами (как в Win-1252), то несколько глифов для буквы в принципе не получится добавить.

static_lab ★★★★★
()

(на правах троллинга с элементами реальности)

«Современным C++», вообще, тяжело пользоваться, не то, что строками. Это все таки не Rust какой-нибудь, который прост как три копейки.

А ты попробуй разберись во всех этих многоэтажных конспектах… Без той печально известной книги Александреску по-моему так нечего даже и подходить к современному C++.

Поэтому люди обычно ограничиваются C++11 с элементами из C++14 и C++17.

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

Если бы юникод оставался двухбайтовым, мы бы имели обиженных китайцев, чьи иероглифы в первой версии юникода унифицировали с японскими. Поэтому переход на 4 байта был обусловлен объективно.

Да, только китайцы до сих пор обижены, а иероглифы до сих пор унифицированы. Хуже того, что один и тот же набор символов будет рисоваться по-разному в зависимости от локали текста. То есть, иметь просто набор байт с валидным юникодом – недостаточно, нужны метаданные, чтобы его отрендерить. Это просто мрак, ад и холокост на ровном месте, мать его. Как можно было так обосраться, я даже не представляю.

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

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

Да, только китайцы до сих пор обижены, а иероглифы до сих пор унифицированы

Кстати, кириллица тоже совмещена.

Гм, так ведь и латиница совмещена. Там тоже все друг на друга обижены? :))

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

Гм, так ведь и латиница совмещена.

Латиница хотя бы одинаково рисуется. А вот русские и болгарские буквы – не всегда.

Там тоже все друг на друга обижены? :))

Не друг на друга, а юникодовцами.

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

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

ya-betmen ★★★★★
()
Ответ на: комментарий от hateyoufeel

Да, только китайцы до сих пор обижены,

Да ладно, шрифтами всю разницу в написании глифов можно устранить. Да и их 1.5 миллиарда, наверняка все что нужно уже запили.

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

Да ладно, шрифтами всю разницу в написании глифов можно устранить.

Проблема не в шрифтах. Шрифты как раз часто включают в себя все возможные варианты написания. Но как ты одним только шрифтом устранишь разницу в тексте, где языки совмещены? У тебя есть текст на китайском о Японии с цитатами на японском. Или наоборот. Херли ты в этом-то случае будешь делать без метаданных?

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

В прокаченом текстовом процессоре наверное можно перехватывать смену языка и автоматом переключать фонт, т.е. почти как обычный word документы с разными стилями для разных фрагментов текста, а тут будет для японского включаться какой-нибудь шрифт Pretty Japan, для китайского шрифт Grate China.
Для делопроизводства где нужно мешать разные языки я бы сделал так, это первое что пришло мне в голову. Не знаком как это реализовано на практике.

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

В прокаченом текстовом процессоре наверное можно перехватывать смену языка и автоматом переключать фонт, т.е. почти как обычный word документы с разными стилями для разных фрагментов текста, а тут будет для японского включаться какой-нибудь шрифт Pretty Japan, для китайского шрифт Grate China.

Ещё раз: нормальные шрифты имеют варианты для обоих языков. Проблема не в шрифте, проблема в хранении метаданных. Потому что сами по себе байты текста нифига не говорят о том, какой это язык. Хотя могли бы, но юникодники здесь обосрались.

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

На практике это реализовано метаданными. Например, тегом в HTML.

<p lang="en-GB">This paragraph is defined as British English.</p>

<p lang="fr">Ce paragraphe est défini en français.</p>

А теперь сценарий: тебе друг Вася пишет в чат строчку текста иероглифами. Как именно их нужно отрендерить? Вот именно: хер знает.

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

Потому что сами по себе байты текста нифига не говорят о том, какой это язык.

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

В текстовых редакторах пишут кодеры, обычные люди нет.

друг Вася пишет в чат

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

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

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

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

друг Вася пишет в чат

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

Какие-такие китайцы? Повторюсь: мой друг Вася скопировал из сабов любимого аниму строчку и кинул мне в чат. Как эту строчку рендерить?

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

Повторюсь: мой друг Вася скопировал из сабов любимого аниму строчку и кинул мне в чат. Как эту строчку рендерить?

проблема решается просто: не дружить с анимешниками

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

Да какая тебе разница чего туда напихали? Главное чтобы была спецификация нормальная, чтобы можно было глянуть что и как. А там с этим уже работай, не?

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

Вот отказ от фиксированной длины это уже был неоправданный перебор, который всё попутал. Эмодзи, символы фекалий и всё такое – это дискредитация юникода как способа записи текста и типографских символов разных языков. Пусть разными алфавитами, пусть с вымершими языками, но всё-таки текста. Насколько я понимаю, 4 байт на символ бы для этого хватило с запасом.

О чём речь вообще? Конкатенация кодепоинтов в юникоде была тыщу лет, до всяких эмодзи. Всякие двоеточия над символами, вот это вот всё. Эмодзи вообще ничего не изменили. 4 байт на кодепоинт и сейчас хватает с запасом.

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

Эмодзи, символы фекалий и всё такое – это дискредитация юникода как способа записи текста и типографских символов разных языков.

Как известно сумма разума на Земле постоянна, а население растет. Причем в сумме разума надо учитывать интеллект носимых гаджетов. Это кстати объясняет парадокс Ферми (почему мы не видим на небе следов деятельности высокоразвитых цивилизаций) - цивилизация в какой то момент открывает для себя IT, смартфоны/планшеты а дальше все.

Сейчас мы вживую наблюдаем формирование нового универсального языка из эмодзи. Скажем в аэропортах ты можешь спокойно ориентироваться по пиктограммам (эмодзи) не читая надписей. Этот общепринятый набор будет расти и в какой то момент вообще вытеснит слова для сапиенсов. В конце концов Эллочка-людоедка обходилась 30-ю словами - эмодзи примерно столько же.

Хорошая новость - после формирования такого словаря эмодзи юникод снова станет однобайтовым, причем с большим запасом;-)

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

Повторюсь: мой друг Вася скопировал из сабов любимого аниму строчку и кинул мне в чат. Как эту строчку рендерить?

а в UTF8 разве нельзя определить алфавит по символу(то есть мультибайту этого символа)?

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

Нет. Читай выше, в юникоде символы разных языков обозначаются одним кодпоинтом. Даже если в этих языках они рисуются по-разному.

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

В том, что там много тысяч правил конкатенации набора юникод-символов в символ. Из разряда акут + а = а́. Добавление всего нескольких сотен емоджи вообще привело к добавлению более десяти тысяч (!) комбинаций того, как надо рендерить. Там вообще теперь нужно не шрифт использовать, а детектить эмоджи, останавливать рендер шрифта, делать там пробел нужного размера, потом рендерить отдельно рисуя там графический эмоджи. Причем эта херня может быть сконкатенирована из комбинации 8 обычных эмоджи.

Это не говоря о том, что в строке могут быть модификаторы направления (из-за чего сегодняшние редакторы ни один не могут корректно такой случай обработать), можификаторы сдвига буквы, превращающий ее в надстрок/подстрок, при этом эти надстроки/подстроки по стандарту должны накапливаться неограниченно, но при попытке нарисовать такую zalgo-херню 99.99% редакторов не может определить высоту рендера и ломает нахер отображалку или делает графические артефакты при выделении текста.

Это я еще на упомянул, что нет нормального способа поделить шрифты на группы, чтобы использовать согласно вот текущей языковой группе, из-за чего вот вы выбрали шрифт, а все символы, которых у него нет будут браться не из какого-то другого который ВЫ указали, а какой он первый найдет. Например рисую я этикетку для товара и мне надо руками искать шрифт, в котором будут символы всех алфавитов и не сильно уебищные или самому из нескольких шрифтов собирать один Франкенштейн. Потому что ни в одной библиотеке рендера нельзя сказать «для группы 0х50000-0х70000 используй шрифт А», потому что тык тык, композитные символы, херак, и группа совсем другая. Китайцы вообще не парятся, всё что не китайский язык рендерится первым попавшимся говном.

И это всё не говоря о том, что просто так найти правила рендера в инете не получится, потому что всё это делалось кусками аппендиксами к стандартам, какими-то договоренностями и в итоге если вы напишете всё верно у вас будет вообще не так как у других, даже если у вас правильней.

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

Причем эта херня может быть сконкатенирована из комбинации 8 обычных эмоджи.

На самом деле, всё хуже. Ты можешь сконкатенировать буквально три мегабайта говна в один эмоджи.

Неплохой пример по ссылке: https://paulbutler.org/2025/smuggling-arbitrary-data-through-an-emoji/, и это не единственный способ.

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

Например, U+00F3 - это испанский или польский символ?

Latin Small Letter O with acute 

какая разница-то? просто нужен фонт с таким символом. тебе ж рендерить, а не грамматику проверять.

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

Потому что в зависимости от того, текст на каком именно языке рендерится, символ будет нарисован по-разному. Я об этом выше писал же уже.

Вот пример для иероглифов, где разница достаточно существенная. В юникоде это всё один и тот же символ U+8FD4. Больше примеров есть в педивикии.

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

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

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

за иероглифы кстати пора карать. в 21 веке живем. пора это камменоугольные кракозябры отправить на свалку истории.

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

Требования к обратной совместимости.

Это все отговорки. Ничего не мешает завезти Traversable => Iterator/IteratorAggregate интерфейсы и на их базе добавить функции по работе со строками так как это есть уже во всех остальных языках в базе.

Но этого не произойдет пока не исчезнет догма двадцатилетней давности: char хватит для всего.

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

Оно умеет комбинироваться, создавая новые символы?! Шта?! А я тут на луа написал пару функций для работы с ютф8 и такой: «Как просто, ты смотри и чего все возмущаются?».

А если реально не париться и юзать конкретное?

LightDiver ★★★★★
()