Обалденный глюк при работе со строками

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

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

Обалденный глюк при работе со строками

Сообщение Stertor » 20.08.2014 14:47:41

Глюк сводится к тому, что нельзя получить 1 символ строки, если строка состоит из 1 символа.

Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
//Delphi
var
  str:string;
begin
   str:='ы';
     showmessage(str[1]); // ы
end;


Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
//FPC
var
  str:string;
begin
   str:='ы';
     showmessage(str[1]); // emptystr  :(  Ок, поправим...
     showmessage(pchar(str)[0]); // emptystr {facepalm}
end;


Версия FPC: 2.6.4
Аватара пользователя
Stertor
новенький
 
Сообщения: 20
Зарегистрирован: 10.08.2014 18:11:12

Re: Обалденный глюк при работе со строками

Сообщение MiniQ » 20.08.2014 15:37:59

Что showmessage принимает на входе? string?
а ты ему даешь char
сделай так
showmessage(copy(str,1,1));
MiniQ
новенький
 
Сообщения: 81
Зарегистрирован: 28.01.2013 16:31:55

Re: Обалденный глюк при работе со строками

Сообщение Vapaamies » 20.08.2014 16:38:42

Если строка в UTF-8, буква "ы" кодируется двумя байтами.
Аватара пользователя
Vapaamies
постоялец
 
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург

Re: Обалденный глюк при работе со строками

Сообщение zub » 20.08.2014 17:05:09

>>Обалденный глюк при работе со строками
котегорично))
для полного понимания предлагаю еще поэкспериментироваь:
Код: Выделить всё
begin
   str:='s';
     showmessage(inttostr(length(str)));
     showmessage(str[1]);
end;

дальше какнибудб так:
Код: Выделить всё
begin
   str:='ы';
     showmessage(inttostr(length(str)));
     showmessage(inttostr(ord(str[1])));
     showmessage(inttostr(ord(str[2])));
end;

затем глянуть как в utf8 кодируются русские буквы и прогуглить кучу тем уже посвещенных этому вопросу... там и решение найдется:
Код: Выделить всё
uses lazutf8;
begin
   str:='ы';
     showmessage(inttostr(UTF8Length(str)));
     showmessage(UTF8copy(str,1,1));
end;
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Обалденный глюк при работе со строками

Сообщение Stertor » 20.08.2014 19:42:42

Возможно, Вам покажется странным, господа, но приведенный мной пример нормально работает на юникодной дельфе 2009.

begin
str:='s';
showmessage(inttostr(length(str)));
showmessage(str[1]);
end;

Уже видел. Глюк возникает с русскими буквами, причем независимо от типа строки - будь это utf8string или unicodestring.

uses lazutf8;
begin
str:='ы';
showmessage(inttostr(UTF8Length(str)));
showmessage(UTF8copy(str,1,1));
end;


Мне нужно работать со строкой, как с массивом. Получается, что никак не обойтись без copy/midstr?
Аватара пользователя
Stertor
новенький
 
Сообщения: 20
Зарегистрирован: 10.08.2014 18:11:12

Re: Обалденный глюк при работе со строками

Сообщение zub » 20.08.2014 19:53:28

>>Возможно, Вам покажется странным, господа, но приведенный мной пример нормально работает на юникодной дельфе 2009.

>>Уже видел. Глюк возникает с русскими буквами, причем независимо от типа строки - будь это utf8string или unicodestring.
>>Мне нужно работать со строкой, как с массивом. Получается, что никак не обойтись без copy/midstr?
1. Это не глюк
2. Ни что вам не мешает продолжать работать со строкой как с массивом. Просто учитывайте что символ может занимать не только 1 байт
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Обалденный глюк при работе со строками

Сообщение Stertor » 20.08.2014 19:54:09

1. Это не глюк

Буду спорить. Отчего же тогда в Delphi работает?

zub писал(а):Просто учитывайте что символ может занимать не только 1 байт

Просвети?

Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  str:string;
  s:string;
  i:integer;
begin
   str:='Не называйте это паскалем. Это бейсик какой-то.';
   for i:=1 to utf8length(str) do // а нафига тогда, спрашивается, length??
   begin
      s:=utf8copy(str,i,1); // а Copy тогда зачем???
    showmessage(s);
   end;
end;
Аватара пользователя
Stertor
новенький
 
Сообщения: 20
Зарегистрирован: 10.08.2014 18:11:12

Re: Обалденный глюк при работе со строками

Сообщение zub » 20.08.2014 20:54:25

>>Буду спорить. Отчего же тогда в Delphi работает?
вместо споров лучше таки глянь что из себя представляет кодировка utf8
кстати,
>>причем независимо от типа строки - будь это utf8string или unicodestring.
лишний раз подтверждает что глюки в программе а не в компиляторе, вы забыли перекодировать строку перед тем как закинуть ее в unicodestring.
В последних дельфях внутренняя кодировка строк utf16 емнип, в fpc 2.6 ее как таковой нет, нужно самому учитывать и перекодировать строки туда-сюда.
Могу посоветовать подождать годик другой fpc2.8 и LCL совместимую с ним - там будет также как в delphi. Уже сейчас можно потыкать 2.7.1 но будут еще более обалденные "глюки", т.к. LCL пока не умеет новые строки

>>Просвети?
На тему? в 2.6 строка - массив байтов, работай как с массивом)) - не, нехочу - "глюки"))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Обалденный глюк при работе со строками

Сообщение Vapaamies » 20.08.2014 21:28:32

Stertor писал(а):Возможно, Вам покажется странным, господа, но приведенный мной пример нормально работает на юникодной дельфе 2009.

Потому что в Delphi всё реализовано по уму, а в FPC на "отвяжись".
Аватара пользователя
Vapaamies
постоялец
 
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург

Re: Обалденный глюк при работе со строками

Сообщение zub » 20.08.2014 21:47:14

>>Потому что в Delphi всё реализовано по уму, а в FPC на "отвяжись".
Официального стабильного FPC с внутренней перекодировкой строк пока нет, такчто оставим такие заявления до выхода 2.8
На самом деле проблемы вида
Код: Выделить всё
showmessage(str[1]); // emptystr  :(  Ок, поправим...

только с виду такие страшные. в свое время перевел свой быдлокодный парсер с ansi на utf8 абсолютно безболезненно, думаю перевод на utf16 будет гораздо более проблемным.
часто из строки нужно выдрать один символ? гораздо чаще нужно выдрать подстроку, а она что в анси что в utf8 или utf16 последовательность байт\слов. Но даже если приспичело выдирать посимвольно - делать ставку на то что символ=байт\слово - ошибочно
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Обалденный глюк при работе со строками

Сообщение hinst » 20.08.2014 22:01:19

кароч в лазарусе UTF-8, а в Delphi WideChar, поэтому s[1] не буит работать как хочет начавший тему

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

Добавлено спустя 52 секунды:
твоя работа - твой головняк думать как это реализовать
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Обалденный глюк при работе со строками

Сообщение Максим » 21.08.2014 00:05:34

Stertor писал(а):Возможно, Вам покажется странным, господа, но приведенный мной пример нормально работает на юникодной дельфе 2009.

Приведённый в стартовом посте код в общем случае в Delphi также неработоспособен. В UTF-16, внезапно, помимо двухбайтных символов есть и четырёхбайтные.

Vapaamies писал(а):Потому что в Delphi всё реализовано по уму, а в FPC на "отвяжись".

Нет, реализовано не на "отвяжись", а чтобы над вами персонально поиздеваться. :mrgreen:
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 598
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Re: Обалденный глюк при работе со строками

Сообщение sign » 21.08.2014 07:52:10

Stertor писал(а):Глюк сводится к тому, что нельзя получить 1 символ строки, если строка состоит из 1 символа.

Это не глюк.
Это незнание матчасти.
С вашим понимаем сути, вы никакой символ не получите, если присутствуют не только латинские буквы и символы.

Код: Выделить всё
S := 'Привет';
Ch := S[3];

Ch - ни разу не будет 'и';
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: Обалденный глюк при работе со строками

Сообщение Vadim » 21.08.2014 13:30:20

Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
//Delphi
var
  str:string;
begin
   str:='ы';
     showmessage(UTF8Copy(str, 1, 1)); // ы
end;

и все дела... ;-)
Последний раз редактировалось Vadim 22.08.2014 04:56:45, всего редактировалось 1 раз.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Обалденный глюк при работе со строками

Сообщение SSerge » 21.08.2014 18:01:48

Vadim, запятую забыл :D
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

След.

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

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

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

Рейтинг@Mail.ru