Избитый вопрос про кириллицу

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

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

Избитый вопрос про кириллицу

Сообщение dunin » 10.02.2014 10:55:09

Сразу извиняюсь ибо эта тема уже сорок раз тут на форуме поднималась, но сегодня столкнулся с необъяснимой вещью. :shock:
Всегда сколько работал с Лазарусом такой код прокатывал
Код: Выделить всё
unit UnitMain;

{$mode objfpc} {$H+}
{$WARN SYMBOL_DEPRECATED OFF}           

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Caption:= 'Привет';
end;

Сейчас открыл проект и увидел, что в заголовке "???" Если переписать так
Код: Выделить всё
unit UnitMain;

{$mode objfpc} {$H+}
{$WARN SYMBOL_DEPRECATED OFF}           

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Caption:= UTF8Encode('Привет');
end;

то все работает.

Я так понимаю, что в компиляторе где-то что-то неведомым мне образом переключилось.

Вопрос: как вернуть "нормальную" обработку строк? Где что переключить? Какой флаг куда поставить?

Спасибо.
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: Избитый вопрос про кириллицу

Сообщение qivi » 10.02.2014 16:42:15

Какая версия FPC?

Проверь что б исходник был в кодировке UTF8.

Если не поможет, можно принудительно задать кодовую страницу модуля:

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

{$mode objfpc}{$H+}
{$codepage UTF8}   


Это для новых 2.7.X версий FPC. Когда только уже выйдет эта "новая" 2.8.0 версия... похоже план пятилетки... а тут ещё 3 года не прошло...
Аватара пользователя
qivi
энтузиаст
 
Сообщения: 703
Зарегистрирован: 19.01.2009 13:45:54
Откуда: Россия

Re: Избитый вопрос про кириллицу

Сообщение SSerge » 10.02.2014 16:48:07

qivi писал(а):можно принудительно задать кодовую страницу модуля:


Нельзя этого делать. Сразу появятся маркеры кодовой страницы на переменных и скрытые преобразования (для 2.7.х)
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Избитый вопрос про кириллицу

Сообщение dunin » 10.02.2014 16:51:03

Кодировка UTF8. Не помогло.
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: Избитый вопрос про кириллицу

Сообщение SSerge » 10.02.2014 18:48:30

dunin писал(а):Кодировка UTF8. Не помогло.


А вот посмотри, не стоит ли в начале файла маркёр BOM. Если оный есть - убрать. Потому что если он есть, как раз и включается ретрансляция строк и маркирование переменных. Появляется, если подвергнуто редактированию в каком нибудь типично вендовом редакторе. Впрочем, даже редактор FARа может украшать UTF8-файлы этим маркёром. В требованиях же лазаруса сказано чётко - маркёра UTF8 в начале файла быть не должно
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Избитый вопрос про кириллицу

Сообщение dunin » 11.02.2014 09:18:01

Уффф... Помогло.

Может кому пригодится:
1. лазарус - меню - сервис - преобразовать кодировку проектов (так помогло, видать какой-то файл с BOM где-то затисался);
2. {$codepage UTF8} НЕ ставить!!!! (FPC 2.6.2)

Всем огромное спасибо. :)
Аватара пользователя
dunin
энтузиаст
 
Сообщения: 634
Зарегистрирован: 02.05.2007 13:18:11
Откуда: Тољя††и

Re: Избитый вопрос про кириллицу

Сообщение qivi » 11.02.2014 09:36:18

А я при использовании FPC 2.7.Х ставлю {$codepage UTF8} + строки типа UnicodeString и вообще не парюсь какие у меня кодировки кроме как чтение из текстовых файлов.
Если это не правильно, расскажите пожалуйста как оно концептуально правильно для нового FPC. С годик назад интересовался никто ничего конкретного не сказал.

Кстати, очень интересует вопрос как вообще правильно работать со строками в новом FPC? Какие типы строк останутся? Как юникод FPC будет согласоваться с юникодом Lazarusa? Когда выйдет релизный FPC 2.8.0?
Аватара пользователя
qivi
энтузиаст
 
Сообщения: 703
Зарегистрирован: 19.01.2009 13:45:54
Откуда: Россия

Re: Избитый вопрос про кириллицу

Сообщение SSerge » 11.02.2014 09:55:18

qivi

Я ж ссылу на это http://sirserge.altai.info/articles/?id=45 уже наверно более десятка раз постил...

Вкратце, в при использовании самого FreePascal версии 2.7.х как такового можно пользоваться всеми его средствами, если это необходимо.
Если ваш проект - project lazarus - никаких {$codepage} и соответствующих ключей компиляции, иначе будет чертовски малоприятное поведение. Вы можете этого не заметить на linux, у которого системная кодовая страница UTF-8, но во всех других случаях - строки при передаче в функции библиотек lcl или обратно будут испорчены, если не принять специальных мер по снятию маркёра кодовой страницы.
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Избитый вопрос про кириллицу

Сообщение qivi » 11.02.2014 11:58:50

SSerge, дак я это и читал. Ничего лучще из приведённого там чем {$codepage UTF8} + строки типа UnicodeString я не нашёл. Да единственное что при этом не работает это передача строк контролам LCL в Win, но это меня тревожит посредственно потому что у меня Linux и по причине затянувшейся недоделонности-неопределённости работы со строками в FPC+Lazarus. При не использовании {$codepage UTF8} + строки типа UnicodeString я всё время отгребал неявные перекодирования то на сохранении/чтении файлов, то на передачи из переменной в переменную (при том что повсеместно использую один тип строк), то при передачи в LCL, так же встал вопрос какими функциями парсить строки(где то читал что LCLProc вроде как "устарел" и не желательно его использовать).

Ну или объясни для тупого как работать со строками в рамках концепции нового FPC.

Статья это конечно хоть что то, но ничего конкретного. А хочется именно некое конечное понимание как работать со строками так, что б когда ни будь (если доведётся дожить) когда свершится чудо и выйдет FPC 2.8.0, а может даже Lazarus (LCL) будет подогнан под концепцию FPC ничего перекраивать не пришлось. А пока что {$codepage UTF8} + строки типа UnicodeString, для парсинка штатные методы и... верю, надеюся, жду.
Аватара пользователя
qivi
энтузиаст
 
Сообщения: 703
Зарегистрирован: 19.01.2009 13:45:54
Откуда: Россия

Re: Избитый вопрос про кириллицу

Сообщение SSerge » 11.02.2014 13:33:26

qivi писал(а): как работать со строками в рамках концепции нового FPC


А нет там ничего нового в рамках того, как обычно реализуются такие схемы работы. As пример C#, C/C++, JAVA. В качестве внутренней кодировки, с которой работает как компилятор, так и сами библиотеки рантайма, выбирается максимальный юникод, доступный для базовой операционной системы [в fp это UnicodeString=UTF16, поскольку вы понимаете, что это windows-компилятор по своему происхождению и основной области применения], при запуске программы считываются установки системной локали [в fp для этого надо явным образом показать компилятору кодировку исходного текста программы aka {$codepage}], все операции ввода-вывода корректируются под кодировку этой локали, чтобы при чтении во внутреннее представление получились правильные неискаженные строки. Всякое извращение, типа байтовых строк и прочего, является нонсенсом и используется только в исключительных случаях для взаимодействия с какими-нибудь внешними или старыми библиотеками [а вот тут, благодаря зоопарку, происходящему от Delphi и существованию маркированных AnsiStrings, картина размазывается], работа библиотек I/O с чем либо, имеющим другую кодировку, отличающуюся от системной по умолчанию, либо вообще никак не поддерживается [fp, gcc/g++], либо поддерживается явным указанием кодовой страницы при открытии текстового файла [в fp не реализовано, есть в .NET и JAVA]. Т.е. в рамках fp слепое следование концепции на сегодняшний день - полный отказ от любых строк, кроме UnicodeString (как в C/C++ - использование только wstring, wchar, wchar*). Как то так. ))

Обратной стороной медали, при слепом следовании концепции, получите крайне медленно работающие программы.
Я, конечно, допускаю, что у меня руки кривые, но сколько не пытаюсь тестов на разных языках созидать, получаю в среднем следующую картину при работе со строками: Си на первом месте при работе на указателях и байтовых строках (т.е., код, подогнанный под рунтайм и особенности языка), на втором месте по производительности, как ни странно, жабка, причем при отсутствии каких либо попыток оптимизации, на третьем месте - C# в версии .NET, опять же без явной оптимизации; и FP (при равной производительности с C# NET, на байтовых строках при попытке минимизации присвоений на уровне языка (то есть, в ассемблер еще не лезли, но это уже отнюдь не соответствующий алгоритму код, а подгонка под скорость). Обрушить производительность? :D Запросто! C# -> под Linux + Mono. Это сразу выводит его в аутсайдеры. FP меняем строки на UnicodeString -> имеем производительность еще ниже. Жабку сажаем на одноядерный процессор без гипертрединга, она махом уравнивается с fpc (ну или заставляем ее считать плавающую математику). Тоже как то так. ))
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Избитый вопрос про кириллицу

Сообщение Sharfik » 23.02.2014 21:46:57

Вопрос: Как сохранять переменную String содержащую надпись с двойными кавычками типа - ООО "Демо заказчик" через TNativeXML.
Проблема в том, что после сохранения строка выглядит как и была введена, но двойные кавычки преобразуются в непонятные глазу символы и обратно уже не перекодируются при чтении. Т.е. программа вообще не воспринимает двойные кавычки и в любых модификациях их портит :(
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 809
Зарегистрирован: 20.07.2013 01:04:30

Re: Избитый вопрос про кириллицу

Сообщение hinst » 23.02.2014 21:57:58

как насчёт попробовать заменить " на \"
да и вообще, что за TNativeXML, чем "стандартный" не угодил
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Избитый вопрос про кириллицу

Сообщение Sharfik » 23.02.2014 22:38:50

Пробовал и экранировать, и Анси, не анси преобразовывать.. уже в голове бардак. Решение есть одно, не пробовал и не хочу его делать пока что, это преобразовать отдельные символы в тэги html. Но в MSXML все пахало нормально, а тут подстава.

TNativeXML наиболее приближен к MSXML, и когда я искал библиотеку, чтобы была и в delphi и в lazarus, то все на нее тыкали по форумам, а что есть встроенный вариант узнал. уже позже.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 809
Зарегистрирован: 20.07.2013 01:04:30

Re: Избитый вопрос про кириллицу

Сообщение hinst » 24.02.2014 14:15:55

Sharfik
В общем я посмотрел что там такое. Ошибка в модуле NativeXML была
в функции sdEscapeString

Надо было:
Код: Выделить всё
      case P^ of
      '"'  : ScratchMem.Write(AnsiString('"')[1], 6);
      '''' : ScratchMem.Write(AnsiString(''')[1], 6);
      '&'  : ScratchMem.Write(AnsiString('&')[1], 5);
      '<'  : ScratchMem.Write(AnsiString('&lt;')[1], 4);
      '>'  : ScratchMem.Write(AnsiString('&gt;')[1], 4);
      else
        ScratchMem.Write(P^, 1);
      end;


А было:
Код: Выделить всё
      case P^ of
      '"'  : ScratchMem.Write(AnsiString('&quot;'), 6);
      '''' : ScratchMem.Write(AnsiString('&apos;'), 6);
      '&'  : ScratchMem.Write(AnsiString('&amp;'), 5);
      '<'  : ScratchMem.Write(AnsiString('&lt;'), 4);
      '>'  : ScratchMem.Write(AnsiString('&gt;'), 4);
      else
        ScratchMem.Write(P^, 1);
      end;


Автор видимо немного ошибся с этим. Из-за этого в память записывалось значение указателя на строку и то, что там ещё в памяти находилось, вместо самой строки. В общем, можешь найти этот кусок кода в NativeXml.pas: Ctrl+F "sdEscapeString", ну я думаю понятно, поставишь там эти [1], и должно начать работать нормально. Я попробовал, у меня вроде бы сработало. Не знаю, правда, может быть там ещё есть ошибки подобного рода

Добавлено спустя 2 минуты 25 секунд:
В общем, надеюсь, тебе это поможет, я пол часа тупился с этим NativeXML прежде чем нашёл, в чём там баг
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Избитый вопрос про кириллицу

Сообщение Sharfik » 24.02.2014 16:04:23

hinst писал(а):Sharfik
В общем я посмотрел что там такое. Ошибка в модуле NativeXML была
в функции sdEscapeString

Надо было:
Код: Выделить всё
      case P^ of
      '"'  : ScratchMem.Write(AnsiString('&quot;')[1], 6);
      '''' : ScratchMem.Write(AnsiString('&apos;')[1], 6);
      '&'  : ScratchMem.Write(AnsiString('&amp;')[1], 5);
      '<'  : ScratchMem.Write(AnsiString('&lt;')[1], 4);
      '>'  : ScratchMem.Write(AnsiString('&gt;')[1], 4);
      else
        ScratchMem.Write(P^, 1);
      end;


А было:
Код: Выделить всё
      case P^ of
      '"'  : ScratchMem.Write(AnsiString('&quot;'), 6);
      '''' : ScratchMem.Write(AnsiString('&apos;'), 6);
      '&'  : ScratchMem.Write(AnsiString('&amp;'), 5);
      '<'  : ScratchMem.Write(AnsiString('&lt;'), 4);
      '>'  : ScratchMem.Write(AnsiString('&gt;'), 4);
      else
        ScratchMem.Write(P^, 1);
      end;


Автор видимо немного ошибся с этим. Из-за этого в память записывалось значение указателя на строку и то, что там ещё в памяти находилось, вместо самой строки. В общем, можешь найти этот кусок кода в NativeXml.pas: Ctrl+F "sdEscapeString", ну я думаю понятно, поставишь там эти [1], и должно начать работать нормально. Я попробовал, у меня вроде бы сработало. Не знаю, правда, может быть там ещё есть ошибки подобного рода

Добавлено спустя 2 минуты 25 секунд:
В общем, надеюсь, тебе это поможет, я пол часа тупился с этим NativeXML прежде чем нашёл, в чём там баг

Я сейчас на работе, домой приду проверю твой вариант. Но все равно, огромное спасибо, что полез в этот лес. Кодировки файлов для меня очень темный лес. Пытался отследить как идет запись данных через свойство Value, но все на SetValue функции теряло для меня смысл и логику.

Пока все работает, хоть и не хотелось бы делать эти преобразования в заменители, но зато все четко и быстро.
Последний раз редактировалось Sharfik 25.02.2014 10:50:30, всего редактировалось 1 раз.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 809
Зарегистрирован: 20.07.2013 01:04:30

След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru