ansistring заданной длины

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

SSerge писал(а):Утверждение чем-то подтверждается практически или основано на общей теории и тестах компиляторов Си?

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

Проще говоря widestring массив , а utf8 нет
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Проще говоря widestring массив , а utf8 нет
Не правда.

>>взять символ с позиции
И часто надо брать символ с конкретной позиции? обычно позиция сначала определяется либо pos(..,'substr'), либо length('prefix')
такчто разница если есть, то никак не в пользу widestring
Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

zub писал(а):Проще говоря widestring массив , а utf8 нет
Не правда.

Докажите, возможно я ошибся

zub писал(а):взять символ с позиции
И часто надо брать символ с конкретной позиции? обычно позиция сначала определяется либо pos(..,'substr'), либо length('prefix')
такчто разница если есть, то никак не в пользу widestring


У utf8 только одно преимущество, у них меньший размер
Насчет pos, оно работает побайтово, так что разницы нет, а вот с length сложнее, есть utf8length. Чтоб вычислить нужно пройти всю строку. В widestring длина массива делить на 2 и есть длина строки
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Ism
http://wiki.freepascal.org/LCL_Unicode_Support/ru

Обратите внимание, что при доступе к WideString как к массиву, каждый его элемент представлен 2 байтами, а символ в UTF-16 может состоять из 1 или 2 элементов, занимающих соответственно 2 или 4 байта. Поэтому при доступе к WideString как к массиву совершенно неправильно ожидать соответствия "один элемент -- один символ", наличие в строке 4-х байтовых символов приведёт к ошибкам. Заметьте также, что UTF-16 как и UTF-8, допускает составные (decomposed) символы. Например, символ "Á" может быть представлен как одним элементом, так и парой: "A" + изменяющий акцент. Таким образом, включающий акцентированные буквы текст в юникоде часто может быть закодирован различными способами, Lazarus и FPC не обрабатывают такие случаи автоматически.
Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

Упс, тогда widestring теряет смысл
Хотя можно конвертить в него так, чтоб отсекать вариант не 2 байта, ведь насколько я понимаю остальные случаи экзотические
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Докажите, возможно я ошибся
Это аксиома. Для компилятора строка - "массив" байтов/слов, что там лежит utf8, ansi/utf16 ему глубако паралельно
Индексный посимвольный доступ не возможен в общем случае как в utf8, так и в utf16. Поэтому работать нужно не с символами а с подстроками.

>>В widestring длина массива делить на 2 и есть длина строки
нет длины массива, есть длина строки и компилятор определяет ее не в символах а в байтах\словах. Длина "массива" в байтах это lenhth(s)*sizeof(s[1]) независимо ни от кодировки, ни от utf8\utf16

utf8length, utf8pos...
copy(s,pos('подстрока'),length(s)-length('подстрока')-1)
работает абсолютно также как
utf8copy(s,utf8pos('подстрока'),utf8length(s)-utf8length('подстрока')-1)
какая разница что передается в процедуры - "посимвольный" или "побайтовый" адрес?
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Ism
У widestring еще масса замечательностей.
Если задаться историей появления этого типа - так он сделан был исключительно для того, чтобы передавать zero-terminated строки в кодировке UCS2 в OLE-объекты и API Windows. Это и есть его единственное назначение. :D
Потому там нет счетчика ссылок, потому использование widestring с точки зрения общего менеджера строк rtl неоптимально всегда. Я как-то в теорию процесса не вдавался, но есть такое мнение, что wide-string строки, вышедшие из зоны видимости кода, скорее всего будут освобождены в последнюю очередь, если вообще будут освобождены.

А вот как только выходим за рамки windows, то надо уже лепить в uses widestringmanager, основным назначением которого будет не то, как управлять строками, а то, как производить скрытую конверсию из кодировки операционной системы в widestrings при присваиваниях переменных разных string-типов к wideString и обратно.
Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

Тогда остается один вариант - конвертим для быстрой обработки в однобайтовую кодировку и используем tstringstream, а после обработки обратно в utf8
Памяти меньше, проблем с позициями нет
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Ism писал(а):Памяти меньше, проблем с позициями нет


при преобразовании теряем все экзотические и акцентированные символы :D
Ism
энтузиаст
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Сообщение Ism »

SSerge писал(а):при преобразовании теряем все экзотические и акцентированные символы

Ну это частные случаи
Делал процедуру , которая работала с utf8 строкой как с однобайтовой кодировкой, так как не затрагивались юникодовые символы, то все работало
Но это неправильно, я вообще думал обрабатывать в UTF32 https://ru.wikipedia.org/wiki/UTF-32
Но в fpc не нашел нормальных инструментов
sts
энтузиаст
Сообщения: 549
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

SSerge писал(а):Обратите внимание, что при доступе к WideString как к массиву, каждый его элемент представлен 2 байтами, а символ в UTF-16 может состоять из 1 или 2 элементов,

тут надо помнить что изначально тип WideString (PWideChar^) равен типу UNICODE (а не UTF-16) в котором как раз строго 1 символ = 2 байта, да, лет 10 назад обращаться по индексу к символу (в делфе, ну или винапи) было вполне нормально.
по этому если вы используете старую либу, или запускаете прогу на старой винде то надо передавать строки без составных символов.
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

Ism писал(а):Хотя можно конвертить в него так, чтоб отсекать вариант не 2 байта, ведь насколько я понимаю остальные случаи экзотические

Экзотическими они были в прошлой жизни. Например, если писать программу, работающую с VK API, можно напороться на смайлики в сообщениях, закодированные по стандарту и требующие суррогатной пары. С появлением стандартов любая экзотика рано или поздно становится обыденностью.
Сквозняк
энтузиаст
Сообщения: 1159
Зарегистрирован: 29.06.2006 22:08:32

Сообщение Сквозняк »

Sergei I. Gorelkin писал(а):Ну, идея строк LongString - наподобие ShortString, только с двухбайтным полем длины - имела место быть, что видно по коду компилятора и RTL. Проблема в основном в том, что количество преобразований, которое нужно поддерживать, растет с добавлением каждого типа строк не линейно, а в геометрической прогрессии. Чего нельзя сказать о количестве разработчиков...

Со строками понятно, но почему в модуле system есть процедуры переименующие и удаляющие файл, создающие каталог, но нет копирующей файл? Ведь всё это замена команд командного процессора. Можно было бы подумать что имя "copy" занято, но ведь "filecopy" свободно.
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Сквозняк писал(а):но нет копирующей файл? Ведь всё это замена команд командного процессора. Можно было бы подумать что имя "copy" занято, но ведь "filecopy" свободно


Когда-то во времена оны, в библиотеках времени исполнения любых языков поголовно отсутствовали операторы и функции, приводящие к возникновению исключительных ситуаций. Такие, например, как арксинус и арккосинус, операция возведения в дробную степень, а кое-где - и квадратный корень. :D Теперь, давайте сосчитаем количество исключений, которые способна сгенерировать команда copyfile и проанализируем время, на которое нужно фактически остановить программу, вернуть прерывания и т.п. в исходное состояние и передать управление этому, как его там, командному процессору. С учетом того, что из операции копирования "командный процессор" может и не вернуться, (или не вернуться в обозримое время), получаем еще один зомби-процесс операционной системы. В принципе, логично тогда уж напрямую вызвать командный процессор и передать ему то что надо. Набор средств имеется.
Mikhail
энтузиаст
Сообщения: 565
Зарегистрирован: 24.10.2013 16:06:47

Сообщение Mikhail »

Сквозняк писал(а):Со строками понятно, но почему в модуле system есть процедуры переименующие и удаляющие файл, создающие каталог, но нет копирующей файл? Ведь всё это замена команд командного процессора. Можно было бы подумать что имя "copy" занято, но ведь "filecopy" свободно.

По хорошему надо вообще убрать все эти функции оттуда, как и математику и пр., RTL должен быть минимальным. Но это вряд-ли возможно, по соображениям обратной совместимости.
Ответить