Замена символов в строке

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

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

Re: Замена символов в строке

Сообщение *vmr » 29.10.2008 19:00:54

Mr.Smart писал(а):Кодировка между USC-2 и 1251 работает также как и в Делфи.
А для UTF-8 используйе функции UTF8Decode\UTF8Encode

Т.е. для ANSI производится перекодирование константных строк, а для UTF-8 нет?
Приехали...


ЗЫ: может точно автор забыл указать кодировку сорцов?
Аватара пользователя
*vmr
постоялец
 
Сообщения: 168
Зарегистрирован: 08.01.2007 01:46:07
Откуда: Киев

Re: Замена символов в строке

Сообщение Sergei I. Gorelkin » 29.10.2008 21:08:24

При указании {$codepage utf8} строковые литералы, содержащие не-ascii символы считаются (по крайней мере, версией 2.3.1) WideString, хранятся как WideString, а при их присвоении AnsiString производится перекодировка.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Замена символов в строке

Сообщение Mr.Smart » 29.10.2008 22:57:32

Sergei I. Gorelkin писал(а):При указании {$codepage utf8} строковые литералы, содержащие не-ascii символы считаются (по крайней мере, версией 2.3.1) WideString, хранятся как WideString, а при их присвоении AnsiString производится перекодировка.


Покапавшись в исходниках нашол файлы с сопоставлением кодовых таблиц с уникодом (source/rtl/ucmaps/). Которые загружаются функцией loadunicodemapping.

Подскажите а как fpc в рантайме делает преобразование динамически формируемых строк? Что в бинарник включается таблица перекодировки?
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Замена символов в строке

Сообщение Sergei I. Gorelkin » 30.10.2008 00:08:31

В рантайме - в винде вызывается WideCharToMultibyte()/MultiByteToWideChar(), в линуксе и ему подобных - iconv(). Таблицы перекодировок в бинарник не включаются.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Замена символов в строке

Сообщение Troublemaker » 30.10.2008 13:48:05

Sergei I. Gorelkin писал(а):При указании {$codepage utf8}

Обязательно проверю, спасибо. Может именно в этом и грабли. Но!

s:widestring
s:='Хрен вам!" //кодировка исходника - utf8
LeftStr(s,1) вовсе не равно "Х"!
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Замена символов в строке

Сообщение Brainenjii » 30.10.2008 14:26:55

Uses ...LCLproc;
...
Var
S: String;
Begin
S := 'Хрен вам';
ShowMessage(UTF8Copy(S, 1 ,1));
Close;
end;
...
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Замена символов в строке

Сообщение Troublemaker » 30.10.2008 14:48:25

Brainenjii писал(а):UTF8Copy

Идея, спасибо. Тоже проверю

Добавлено спустя 17 минут 42 секунды:
Sergei I. Gorelkin писал(а):{$codepage utf8}

Попробовал. Исходники - и так в utf-8. Получилось то же самое, что я писал в теме "где мои тексты???"

Добавлено спустя 1 час 14 минут 23 секунды:
Пока сделал так, работает:
Код: Выделить всё
function ReplaceCharByNum(s,c:string;p:Integer):string;
begin
  ReplaceCharByNum:=UTF8Copy(s,1,p-1)+c+UTF8Copy(s,p+1,Length(s)-p);
end;
...
    s:=Format('** %2.2D%2.2D %-.30S',[ComData.MyType,ComData.ID,ComData.Desc]);
    s:=ReplaceCharByNum(s,'Т',1);

Не в восторге, я, правда, от того, что 'T' - это строка, а не символ. Зато делает то, что я сказал: меняет 1 символ в указанной позиции на другой.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Замена символов в строке

Сообщение Sergei I. Gorelkin » 30.10.2008 20:23:46

Troublemaker писал(а):s:widestring
s:='Хрен вам!" //кодировка исходника - utf8
LeftStr(s,1) вовсе не равно "Х"!


А так:

uses strutils;
...
if strutils.LeftStr(s) = widechar('X') then...
?

Но вообще вся эта катавасия несколько досаждает...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Замена символов в строке

Сообщение Troublemaker » 31.10.2008 01:02:45

Sergei I. Gorelkin писал(а):if strutils.LeftStr(s) = widechar('X')

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

"вовсе не равно" - это попробуйте из widestring-a c кириллицей leftstr-ом выделить первый символ. Один символ (байт) вам и вернется. Вместо двух положенных.

Катавасия, говорите? Вернитесь в тему "где мои тексты" и почитайте радостные отклики любителей utf-a, о том, какое счастье наступило в 0.9.26. с приходом великой утээфизации.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Замена символов в строке

Сообщение Sergei I. Gorelkin » 31.10.2008 01:35:40

Я там в спешке забыл про второй аргумент у LeftStr. Он имеется в виду равный единице.

Добавлено спустя 9 часов 6 минут 18 секунд:
...отредактировать свое сообщение уже не дает :( ну ладно.

Тут фишки вот в чем:
1) В модуле sysutils есть ф-ция LeftStr, работающая с AnsiString, а в модуле strutils - она же для WideString. Если не подключить strutils, то все молча скомпилируется со вставкой неявного преобразования wide->ansi, и результат будет неправильным. На линуксе. А на винде - правильным, потому что в ней системная кодировка однобайтовая (!!!).
2) Иногда компилятор не совсем понимает, какую из перегруженных ф-ций вызывать (см. багрепорт 11327). В этом случае иногда помогает внушение в виде явного указания типа аргумента, отсюда и widechar('Х').

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

Добавлено спустя 2 минуты 43 секунды:
...оказывается, предыдущее сообщение таки редактируется. Шайтан, однако...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Пред.

Вернуться в Free Pascal Compiler

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru