Странности с Copy

Вопросы программирования и использования среды Lazarus.

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

wwswowsogon
постоялец
Сообщения: 157
Зарегистрирован: 23.12.2008 19:41:37

Странности с Copy

Сообщение wwswowsogon »

Всем здравствуйте!

Наткнулся на странную вещь: написал функцию, делающую из полного имени фамилию и инициалы.
Для получения инициалов Копируем из имени и отчества по одному, первому символу.
Если написать так (казалось бы, очевидный вариант :) )

Код: Выделить всё

n := Copy(nam, 1, 1);


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

Код: Выделить всё

n := Copy(nam, 1, 2);


Тогда получается всё, как надо.

Вопрос: с чем это связано и как предсказыать наперёд поведение Copy?
Заранее спасибо! :D
Аватара пользователя
*Rik*
постоялец
Сообщения: 453
Зарегистрирован: 19.04.2011 12:18:51
Откуда: Урал
Контактная информация:

Re: Странности с Copy

Сообщение *Rik* »

Это связано с тем, что русский текст в UTF8 имеет двухбайтную кодировку и копирование по одному символу калечит правиьность строки, а в целом один символ в UTF8 может занимать от одного до 8 байтов, поэтому UTF8 и называется. Нужно использовать для копирования специальные функции для работы с UTF8..
Аватара пользователя
zoltanleo
постоялец
Сообщения: 459
Зарегистрирован: 17.10.2013 10:55:01

Re: Странности с Copy

Сообщение zoltanleo »

Код: Выделить всё

uses
...LazUTF8;
...
n := UTF8Copy(nam, 1, 2);


Для получения крайних символов слева или справа удобнее использовать соответственно UTF8LeftStr или UTF8RightStr

Добавлено спустя 44 секунды:
*Rik* писал(а):Это связано с тем

Юр, привет. :D
Аватара пользователя
*Rik*
постоялец
Сообщения: 453
Зарегистрирован: 19.04.2011 12:18:51
Откуда: Урал
Контактная информация:

Re: Странности с Copy

Сообщение *Rik* »

zoltanleo писал(а):

Код: Выделить всё

uses
...LazUTF8;
...
n := UTF8Copy(nam, 1, 2);


Для получения крайних символов слева или справа удобнее использовать соответственно UTF8LeftStr или UTF8RightStr

Добавлено спустя 44 секунды:
*Rik* писал(а):Это связано с тем

Юр, привет. :D

:D !!
Последний раз редактировалось *Rik* 28.08.2018 21:31:15, всего редактировалось 1 раз.
wwswowsogon
постоялец
Сообщения: 157
Зарегистрирован: 23.12.2008 19:41:37

Re: Странности с Copy

Сообщение wwswowsogon »

Точно, я теперь вспомнил о UTF8Copy. Где-то когда-то на форуме встречал уже, но - забылось же. :)
Спасибо большое за информацию!!!
Аватара пользователя
Ichthyander
энтузиаст
Сообщения: 701
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань
Контактная информация:

Re: Странности с Copy

Сообщение Ichthyander »

Пару дней назад как раз обсуждали эту проблему в одном из чатов. Так вот валиднее всего использовать UTF8LeftStr. Если строка передается в LCL, то в большинстве случаев, строка обрезает неправильные байты. И мне подсказали еще вот такую функцию, если не хочется тащить LCLUTF8

Код: Выделить всё

L := Length(S);
  I := 1;
  if (L > 0) and (S[I] > ' ') and (S[L] > ' ') then Exit(S);
  while (I <= L) and (S[I] <= ' ') do Inc(I);
  if I > L then Exit('');
  while S[L] <= ' ' do Dec(L);
  Result := Copy(S, I, L - I + 1);

ПРавда последнее я не тестил. Там где виден пробел в кавычках как я понимаю это non-break whitespace #$A0
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Re: Странности с Copy

Сообщение Cheb »

Тупой вариант - перегонять строку в UnicodeString и по привычному обращаться к ней, как к массиву.
Utf8Decode - обработал - Utf8Encode

UnicodeString - теоретический, тоже многобайтовая, и один символ может занимать несколько UnicodeChar, но на практике это такие редкоземельные символы, что в ФИО никогда не встретятся. Только в пиктограмках для смайликов или там шумеро-аккадских шрифтах каких нибудь.
Аватара пользователя
zoltanleo
постоялец
Сообщения: 459
Зарегистрирован: 17.10.2013 10:55:01

Re: Странности с Copy

Сообщение zoltanleo »

Cheb писал(а):Тупой вариант - перегонять строку в UnicodeString

Мьсе - любитель нелегких путей? :D
Каков в этом сакральный смысл? И каковы преимущества перед выше упомянутым функциями?
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Re: Странности с Copy

Сообщение Cheb »

Каков в этом сакральный смысл?

Проход по строке, как по массиву, *без* использования любых функций - чем паскаль выгодно отличался от других яп пока не пересели на утф-8?
При синтаксическом разборе - самое оно, один раз перегнал в UnicodeString, дальше - затраты ничтожны. А все эти Utf8Copy, боюсь. вынуждены парсить всю строку с начала и до указанной позиции чтобы вырезать одну букевку.
..кароч, разница как между последовательным доступом к потоку и произвольным доступом к массиву.
Аватара пользователя
alexs
долгожитель
Сообщения: 4066
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Re: Странности с Copy

Сообщение alexs »

Cheb писал(а): А все эти Utf8Copy, боюсь. вынуждены парсить всю строку с начала и до указанной позиции чтобы вырезать одну букевку.

На самом деле - когда делаешь разбор - у тебя данные идут потоком. нет нужды каждый раз отматывать в начало потока (строки). Достаточно взять следующий символ.
Аватара пользователя
zoltanleo
постоялец
Сообщения: 459
Зарегистрирован: 17.10.2013 10:55:01

Re: Странности с Copy

Сообщение zoltanleo »

Cheb писал(а):При синтаксическом разборе - самое оно, один раз перегнал в UnicodeString, дальше - затраты ничтожны.

С практической точки зрения большой выигрыш по времени?
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Re: Странности с Copy

Сообщение Cheb »

когда делаешь разбор - у тебя данные идут потоком.

В идеальном мире с идеальным однопроходным синтаксисом на подобие паскалевского, ага.
Как только что-нибудь нетривиальное, где надо елозить взад-вперёд - Здравствуй. Опа. Новый год.

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

Для обработки удобнее UnicodeString.
Причём, для русского текста - что совой об пень, что пнём об сову, два байта на символ.
Аватара пользователя
zoltanleo
постоялец
Сообщения: 459
Зарегистрирован: 17.10.2013 10:55:01

Re: Странности с Copy

Сообщение zoltanleo »

Cheb писал(а):Для обработки удобнее UnicodeString

Для чего удобнее? Повторюсь, каков практический смысл?
Последний раз редактировалось zoltanleo 04.09.2018 07:45:50, всего редактировалось 1 раз.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Re: Странности с Copy

Сообщение Снег Север »

Может на гигабайтных строках выигрыш будет, но уверен, ни в каком реальном случае его не заметить.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Странности с Copy

Сообщение Vadim »

Снег Север
А есть уже готовые алгоритмы тестов. Именно тестов, чтобы было видно время исполнения?
Ответить