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

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

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

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

Сообщение wwswowsogon » 28.08.2018 21:05:35

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

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

Код: Выделить всё
n := Copy(nam, 1, 1);


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

Код: Выделить всё
n := Copy(nam, 1, 2);


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

Вопрос: с чем это связано и как предсказыать наперёд поведение Copy?
Заранее спасибо! :D
wwswowsogon
постоялец
 
Сообщения: 152
Зарегистрирован: 23.12.2008 20:41:37

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

Сообщение *Rik* » 28.08.2018 22:07:42

Это связано с тем, что русский текст в UTF8 имеет двухбайтную кодировку и копирование по одному символу калечит правиьность строки, а в целом один символ в UTF8 может занимать от одного до 8 байтов, поэтому UTF8 и называется. Нужно использовать для копирования специальные функции для работы с UTF8..
Аватара пользователя
*Rik*
постоялец
 
Сообщения: 426
Зарегистрирован: 19.04.2011 12:18:51
Откуда: Урал

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

Сообщение zoltanleo » 28.08.2018 22:12:21

Код: Выделить всё
uses
...LazUTF8;
...
n := UTF8Copy(nam, 1, 2);


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

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

Юр, привет. :D
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 457
Зарегистрирован: 17.10.2013 10:55:01

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

Сообщение *Rik* » 28.08.2018 22:21:38

zoltanleo писал(а):
Код: Выделить всё
uses
...LazUTF8;
...
n := UTF8Copy(nam, 1, 2);


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

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

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

:D !!
Последний раз редактировалось *Rik* 28.08.2018 22:31:15, всего редактировалось 1 раз.
Аватара пользователя
*Rik*
постоялец
 
Сообщения: 426
Зарегистрирован: 19.04.2011 12:18:51
Откуда: Урал

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

Сообщение wwswowsogon » 28.08.2018 22:25:50

Точно, я теперь вспомнил о UTF8Copy. Где-то когда-то на форуме встречал уже, но - забылось же. :)
Спасибо большое за информацию!!!
wwswowsogon
постоялец
 
Сообщения: 152
Зарегистрирован: 23.12.2008 20:41:37

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

Сообщение Ichthyander » 29.08.2018 00:04:53

Пару дней назад как раз обсуждали эту проблему в одном из чатов. Так вот валиднее всего использовать 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
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 668
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

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

Сообщение Cheb » 30.08.2018 12:48:30

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

UnicodeString - теоретический, тоже многобайтовая, и один символ может занимать несколько UnicodeChar, но на практике это такие редкоземельные символы, что в ФИО никогда не встретятся. Только в пиктограмках для смайликов или там шумеро-аккадских шрифтах каких нибудь.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

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

Сообщение zoltanleo » 30.08.2018 16:22:50

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

Мьсе - любитель нелегких путей? :D
Каков в этом сакральный смысл? И каковы преимущества перед выше упомянутым функциями?
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 457
Зарегистрирован: 17.10.2013 10:55:01

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

Сообщение Cheb » 31.08.2018 09:30:20

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

Проход по строке, как по массиву, *без* использования любых функций - чем паскаль выгодно отличался от других яп пока не пересели на утф-8?
При синтаксическом разборе - самое оно, один раз перегнал в UnicodeString, дальше - затраты ничтожны. А все эти Utf8Copy, боюсь. вынуждены парсить всю строку с начала и до указанной позиции чтобы вырезать одну букевку.
..кароч, разница как между последовательным доступом к потоку и произвольным доступом к массиву.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

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

Сообщение alexs » 31.08.2018 10:00:13

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

На самом деле - когда делаешь разбор - у тебя данные идут потоком. нет нужды каждый раз отматывать в начало потока (строки). Достаточно взять следующий символ.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

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

Сообщение zoltanleo » 31.08.2018 10:21:31

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

С практической точки зрения большой выигрыш по времени?
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 457
Зарегистрирован: 17.10.2013 10:55:01

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

Сообщение Cheb » 04.09.2018 00:24:27

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

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

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

Для обработки удобнее UnicodeString.
Причём, для русского текста - что совой об пень, что пнём об сову, два байта на символ.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

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

Сообщение zoltanleo » 04.09.2018 01:21:25

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

Для чего удобнее? Повторюсь, каков практический смысл?
Последний раз редактировалось zoltanleo 04.09.2018 08:45:50, всего редактировалось 1 раз.
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 457
Зарегистрирован: 17.10.2013 10:55:01

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

Сообщение Снег Север » 04.09.2018 07:08:00

Может на гигабайтных строках выигрыш будет, но уверен, ни в каком реальном случае его не заметить.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

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

Сообщение Vadim » 04.09.2018 07:11:33

Снег Север
А есть уже готовые алгоритмы тестов. Именно тестов, чтобы было видно время исполнения?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Alex2013, Google [Bot] и гости: 35

Рейтинг@Mail.ru