Опять UTF8 и русский

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

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

Опять UTF8 и русский

Сообщение rustem » 20.10.2014 13:37:08

Здравствуйте все!
Вот есть такой код:
Код: Выделить всё
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  s, s1:String;
begin
  s:=SysToUTF8(Edit1.Text);
  if UTF8Length(s)>2 then s1:=UTF8Copy(s,2,1) else s1:='!';
  Label1.Caption:=UTF8ToSys(s1);
end;

То есть при наборе текста в Label1 должен отображаться 2-ой символ строки, либо '!'. Но у меня не работает, текст лейбла пустой. Код правильный?
если заменить Label1.Caption:=UTF8ToSys(s1) на Label1.Caption:=s1; то отображается кракозябля.
Куда смотреть?

UPD
Laz 1.2.0
fpc 2.6.2
win32/win64
rustem
незнакомец
 
Сообщения: 9
Зарегистрирован: 16.04.2012 09:00:25

Re: Опять UTF8 и русский

Сообщение *Rik* » 20.10.2014 14:16:00

Вам зачем UTF8ToSys? Это здесь лишнее.
Код: Выделить всё
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  s, s1:String;
begin
  s:= Edit1.Text;
  if UTF8Length(s)>2 then s1:= UTF8Copy(s,2,1) else s1:='!';
  Label1.Caption:= s1;
end;
Аватара пользователя
*Rik*
постоялец
 
Сообщения: 451
Зарегистрирован: 19.04.2011 12:18:51
Откуда: Урал

Re: Опять UTF8 и русский

Сообщение rustem » 20.10.2014 15:04:40

:oops:
Извините, подумал, что из едита в системной кодировке передается. Туплю.
rustem
незнакомец
 
Сообщения: 9
Зарегистрирован: 16.04.2012 09:00:25

Re: Опять UTF8 и русский

Сообщение skripnik83 » 21.12.2014 00:22:30

Не стал создавать новый тред, но проблема тоже с UTF8. Весь вечер долбаюсь с тем, что fileexists не находит файл при наличии русских букв в пути.
Система Windows 8.1 x64
Версия lazarus 1.2.6
fpc 2.6.4

Простой проверочный код.
Код: Выделить всё
procedure DoSomething;
a: string;
begin
a := 'E:\lazproj\Новая папка\fff.fs1';
if FileExists(UTF8ToSys(a)) then
ShowMessage('ok');
end;


Файл точно есть и вариант FileExistsUtf8 работает, но меня не устраивает. Такое ощущение что UTF8ToSys у меня просто не работает.
Нет никакой разницы в результирующей строке (если в промежуточную переменную результат преобразования записать). Может чего включить надо какой-то директивой? Все уже облазил.
skripnik83
незнакомец
 
Сообщения: 7
Зарегистрирован: 21.12.2014 00:12:39

Re: Опять UTF8 и русский

Сообщение Ism » 21.12.2014 03:21:44

skripnik83 писал(а):Файл точно есть и вариант FileExistsUtf8 работает, но меня не устраивает. Такое ощущение что UTF8ToSys у меня просто не работает.
Нет никакой разницы в результирующей строке (если в промежуточную переменную результат преобразования записать). Может чего включить надо какой-то директивой? Все уже облазил.

Utf8tosys насколько я знаю конвертит в системную кодировку, и если системная кодировка ошибочна, то будут глюки
Можно конвертить принудительно, зная наверняка, в какой кодировке имена путей к файлам
Этот модуль http://lazarus-ccr.sourceforge.net/docs ... dex-5.html
If fileexists(utf8tocp1251) ...
1251 это кириллица виндовская кодировка

Добавлено спустя 16 минут 20 секунд:
У меня ваш код работает, проверьте разрешения на папку
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: Опять UTF8 и русский

Сообщение SSerge » 21.12.2014 05:32:36

Ism писал(а):Такое ощущение что UTF8ToSys у меня просто не работает.


Правильное ощущение. Оно и не обязано работать. :D И часто не работает.

lazutf8.pas:
Код: Выделить всё
function UTF8ToSys(const s: string): string;
begin
  if NeedRTLAnsi and (not IsASCII(s)) then
    Result:=UTF8ToAnsi(s)
  else
    Result:=s;
end;


function NeedRTLAnsi: boolean;
{$IFDEF WinCE}
// CP_UTF8 is missing in the windows unit of the Windows CE RTL
const
  CP_UTF8 = 65001;
{$ENDIF}
{$IFNDEF Windows}
var
  Lang: String;
  i: LongInt;
  Encoding: String;
{$ENDIF}
begin
  if FNeedRTLAnsiValid then
    exit(FNeedRTLAnsi);
  {$IFDEF Windows}
  FNeedRTLAnsi:=GetACP<>CP_UTF8;
  {$ELSE}
  FNeedRTLAnsi:=false;
  Lang := SysUtils.GetEnvironmentVariable('LC_ALL');
  if lang = '' then
  begin
    Lang := SysUtils.GetEnvironmentVariable('LC_MESSAGES');
    if Lang = '' then
    begin
      Lang := SysUtils.GetEnvironmentVariable('LANG');
    end;
  end;
  i:=System.Pos('.',Lang);
  if (i>0) then begin
    Encoding:=copy(Lang,i+1,length(Lang)-i);
    FNeedRTLAnsi:=(SysUtils.CompareText(Encoding,'UTF-8')<>0)
              and (SysUtils.CompareText(Encoding,'UTF8')<>0);
  end;
  {$ENDIF}
  FNeedRTLAnsiValid:=true;
  Result:=FNeedRTLAnsi;
end;


Ism писал(а):FileExistsUtf8 работает, но меня не устраивает.


А чем не устраивает, если не секрет?
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Опять UTF8 и русский

Сообщение skripnik83 » 21.12.2014 20:54:37

Парни, спасибо за участие. Вот у некоторых работает такой код, а у меня почему-то нет. Видать какие-то вопросы в винде, которая с ноутом в комплекте.
Понять бы где подкрутить, чтоб кодировки правильно определялись. GetACP у меня кстати правильно - 1251 возвращает.

Переход к UTF8 не устраивает по некоторым причинам.
Самая главная заключается в том что дальше с этим файлом я через TFileStream работаю, а он все равно в ANSI воспринимает путь и напарывается на ту же проблему.
Принудительная замена кодировки как-то не айс, хоть и спасет временно. Я все-таки хотел мультиязычным в перспективе проектик сделать.
Может кто-то встречал статьи по данной теме?
skripnik83
незнакомец
 
Сообщения: 7
Зарегистрирован: 21.12.2014 00:12:39

Re: Опять UTF8 и русский

Сообщение Ism » 21.12.2014 21:53:00

skripnik83 писал(а):Понять бы где подкрутить, чтоб кодировки правильно определялись.

Если у вас европейская винда с дефолтной 1252 , то ничто не спасет

На самом деле у вас будут встречаться только 2 ОС, там, где имена файлов utf8 и 1251, остальное ересь
Напишите свою функцию, возвращающую имя файла в зависимости от системы, поможет директива ifdef
Исходя из того, что кодировки 2, то можно написать функцию детектор кодировки, тогда вообще не надо задумываться о именах файлов, на входе только utf8, на выходе как определите

Fileexists будет сначала
1 Получить список файлов с путями в папке
2 Сравнить со своим путем в разных кодировках, если совпало, то файл существует

Способ костыльный, но но надежный
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: Опять UTF8 и русский

Сообщение skripnik83 » 21.12.2014 22:23:05

Ism писал(а):
skripnik83 писал(а):Понять бы где подкрутить, чтоб кодировки правильно определялись.

Если у вас европейская винда с дефолтной 1252 , то ничто не спасет

На самом деле у вас будут встречаться только 2 ОС, там, где имена файлов utf8 и 1251, остальное ересь

Странно, что у меня возникают проблемы.
Если идти по шагам, то отладчик почему-то не проваливается в UTF8ToAnsi. Тут какая-то закавыка как я понимаю. Сама винда, как я понял, кодировку дает правильную.
Временно подкостылил с помощью принудительной перекодировки, чтоб людям отдать рабочий вариант.

А почему только две кодировки? А если арийцы решат попользоваться? У них же там эти всякие U с точками...
skripnik83
незнакомец
 
Сообщения: 7
Зарегистрирован: 21.12.2014 00:12:39

Re: Опять UTF8 и русский

Сообщение Ism » 21.12.2014 22:32:03

skripnik83 писал(а):А почему только две кодировки? А если арийцы решат попользоваться? У них же там эти всякие U с точками...

Насколько я знаю 1251 невозможно преобразовать в 1252 , будет абракадабра или вопросики
Поэтому на русском в европейской локали 1252 вы файл назвать не сможете, нет соответствий кириллице

Добавлено спустя 25 минут 3 секунды:
Цитаты
UTF8ToAnsi и AnsiToUTF8 из модуля system (то, что в system можно применять и в «чистом» fpc, без библиотек lcl), но, соответственно, зависящие от корректности установленного widestringmanager и «добавляющие больше двоичного кода в программу». По существующему тексту библиотек из первого просто вызывается второе для linux, c незначительной косметикой для windows|windows CE, так что...

Важно: UTF8ToAnsi возвратит пустую строку, если строка в UTF-8 содержит неверные символы.
Важно: AnsiToUTF8 и UTF8ToAnsi требуют менеджера "широких" строк (widestring) в Linux, BSD и Mac OS X. Можно воспользоваться функциями SysToUTF8 или UTF8ToSys (из модуля FileUtil) или добавить менеджер, включив cwstring одним из первых модулей в разделе uses программы.


Добавлено спустя 4 минуты 47 секунд:
http://wiki.freepascal.org/LCL_Unicode_Support/ru
http://sirserge.intersv.ru/articles/?id=41
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: Опять UTF8 и русский

Сообщение skripnik83 » 21.12.2014 23:17:42

Ism писал(а):
UTF8ToAnsi и AnsiToUTF8 из модуля system (то, что в system можно применять и в «чистом» fpc, без библиотек lcl), но, соответственно, зависящие от корректности установленного widestringmanager и «добавляющие больше двоичного кода в программу». По существующему тексту библиотек из первого просто вызывается второе для linux, c незначительной косметикой для windows|windows CE, так что...

Важно: UTF8ToAnsi возвратит пустую строку, если строка в UTF-8 содержит неверные символы.
Важно: AnsiToUTF8 и UTF8ToAnsi требуют менеджера "широких" строк (widestring) в Linux, BSD и Mac OS X. Можно воспользоваться функциями SysToUTF8 или UTF8ToSys (из модуля FileUtil) или добавить менеджер, включив cwstring одним из первых модулей в разделе uses программы.

UTF8ToSys один фиг на UTF8ToAnsi ссылается, только с дополнительной проверкой. А то что в FileUtil находится ссылается все равно на LazUTF8. Так что это по большому счету все одно и тоже.

А вот модуль cwstring, я че-то не нашел..
skripnik83
незнакомец
 
Сообщения: 7
Зарегистрирован: 21.12.2014 00:12:39

Re: Опять UTF8 и русский

Сообщение Ism » 22.12.2014 00:31:48

Грохните лазарус полностью с папкой и настройками и поставьте заново, возможно чтото сломалось
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: Опять UTF8 и русский

Сообщение Devel0 » 22.12.2014 15:51:51

Ism писал(а):Поэтому на русском в европейской локали 1252 вы файл назвать не сможете, нет соответствий кириллице


Хотелось бы прояснить этот момент
Сейчас ФС хранят имена файлов в юникоде, так что файл можно назвать как угодно.
Однако FileExists, насколько я понимаю, использует GetFileAttributesA - и потому не поддерживает другую локаль.
К примеру у PeaZip (который написан на Lazarus) есть проблемы с отображением имён файлов в другой локали.
Devel0
новенький
 
Сообщения: 66
Зарегистрирован: 24.07.2011 10:43:13

Re: Опять UTF8 и русский

Сообщение pupsik » 22.12.2014 23:00:32

а чем LConv не устраивает?
Там ведь есть УСЁ :). И работает корректно (по крайней мере 866, 1251 и ютф8). Т.е. :
Код: Выделить всё
ConvertEncoding(a_file, EncodingUTF8, GetDefaultTextEncoding)
длинновато, правда... Но, лазарь, требует жертв :wink: .

п.с.
Переход к UTF8 не устраивает по некоторым причинам.
это не причины.... Хотя, если онли винда, то, возможно, и причины :mrgreen:
....
дофлудились ужо до чертиков...:
SSerge не все работает..., а у Ism -надо грохнуть...
Ну..у, по теории, все правильно :mrgreen:

Добавлено спустя 5 минут 5 секунд:
в догонку:
вот коды надо лог выводить и при этом в две стороны... + передавать (принимать) строки (из) внешней проге(и) (через консоль.. ).. Вот это бред был (особенно коды у мну на винде все кул, а у друга "зяблы" рисует).. А у Вас всего то в стрим загрузить :roll:
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: Опять UTF8 и русский

Сообщение pi1 » 22.12.2014 23:09:37

Не знаю, у меня просто assignfile(file2,utf8toansi(savedialog1.FileName)); работает в winxp,win7,win8,win10 (тестовая). А весь проект однозначно в utf8.
Главное не забывать, что русский текст в поле БД в среднем в 1,8 раза длиннее.
Аватара пользователя
pi1
новенький
 
Сообщения: 59
Зарегистрирован: 19.04.2012 18:11:24
Откуда: г.Зеленокумск

След.

Вернуться в Lazarus

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

Сейчас этот форум просматривают: Yandex [Bot] и гости: 239

Рейтинг@Mail.ru
cron