Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: FPC 3.x.x: что творится с юникодом(UTF8)?

Честно говоря, наткнулся на непонятное для меня поведение редактора Лазаря. четко сказано: ребяты, с переходом на fpc 3.х.х. вам больше не надо парится с функциями типа UTF8..., они используются лишь для работы с API, где кодовая страница по умолчанию не UTF8.

Пробуем:
+
unit Unit1;

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

interface

uses 
...
const
  RusStr: String = 'Шла Саша по шоссе и сосала сушку';
  EngStr: String = 'Peter Piper picked a peck of pickled peppers';
...
procedure TForm1.FormShow(Sender: TObject);
begin
Label1.Caption:= RusStr;
Label3.Caption:= EngStr;

Label2.Caption:= 'ReverseString';
Label7.Caption:= ReverseString(RusStr);

Label4.Caption:= 'ReverseString';
Label8.Caption:= ReverseString(EngStr);

Label10.Caption:= 'Utf8ReverseString';
Label11.Caption:= Utf8ReverseString(RusStr);

Label12.Caption:= 'Utf8ReverseString';
Label13.Caption:= Utf8ReverseString(EngStr);
end; 


получаем
+ windows

+ nix

Исходники в редакторе в кодировке UTF8.

Что не так я понял?
=================
Док.

Win7 Ultim x64/Deb 8.7 i386:
FB 3.0.2.32703, диалект 3, SS(win)/SC(Deb),
Lazarus 1.9(r.54619); FPC 3.1.1 (r.35802), IBX by -Rik-; IBE 2016.5.14.1

К сообщению приложен файл (published.7z - 57Kb)
Ответ: Любезный,

ты прав, конечно, на 146%. Мне стыдно
Вопрос: про utf8 в БД и контроллы ввода.

Мысленный эксперимент...
Есть поле varchar(10) character set utf8.
Работа идёт под виндой. Программа на юникодной Delphi.
В гриде и контролах ввода для поля выставлен MaxLength = 10, чтобы пользователь не ввёл лишнего. В БД в этом поле уже имеется 40-байтная 10-символьная строка (максимальный размер UTF8-символа в 4 байта это позволяет).
При конвертации (допустим на уровне компонентов доступа) значение этого поля из UTF8 в string, получается строка больше десяти UTF16-символов, и просто не входит в контроллы ввода.
Если у контроллов поставить MaxLength = 20, то пользователь сможет ввести больше символов чем положено.
Как быть?
Ответ:
delphi user
При конвертации (допустим на уровне компонентов доступа) значение этого
поля из UTF8 в string, получается строка больше десяти UTF16-символов, и просто не входит
в контроллы ввода.

Запретите процедуре конвертации использовать supplementary. Или перестаньте использовать
древнеегипетские иероглифы.

Posted via ActualForum NNTP Server 1.5

Вопрос: FibPlus 7.4, Firebird 2.5 UTF8 и кракозябры для юникодных символов в Exception в БД

Доброй ночи.

Программа выполняет в БД (FB 2.5, charset UTF8) запрос через FibPlus 7.4. База данных вежливо этот запрос прерывает exception-ом.

exception ex_data_error '[Periods slēgts!]';

Программа текст этого exception-а получает с кракозяброй: [Periods slÄ“gts!]

Подскажите где взять компонент, чтобы такой ошибки не было

В чём может быть проблема?

Сам подозреваю, что проблема в Fib+ 7.4 которые не ждут юникодного текста и ничего не раскодируют. Кто-нибудь может подтвердить/опровергнуть (проверить у себя)?

Не могу придумать как исправить, то ли тупо все приходящие из базы exception-ы на клиенте прогонять через Utf8Decode() то ли Fib-ы пропатчить (аналогично раскодируя UTF8)?
Ответ: Поправил раскодированием из UTF8 в обработчике pFibErrorHandler1.FibErrorEvent

procedure TDM.pFibErrorHandler1FIBErrorEvent(Sender: TObject; ErrorValue: EFIBError; KindIBError: TKindIBError; var
    DoRaise: Boolean);
begin
  /// skipped
  if Sender<>nil then
    if Sender is TFibQUery then
      if TFibQUery(Sender).Database.IsUnicodeConnect then
        ErrorValue.Message := UTF8Decode(ErrorValue.Message);
end;
Вопрос: Qt-ofstream-и-UTF8 в локали - как убрать "кракозябры"?

Пишу простенький код
using namespace std;
    setlocale(LC_ALL, "ru_RU.UTF-8");
    vector<string> v{"русский", "язык"};

    ofstream of;
    of.open("c:/temp/test_ru.html");
    of << "<HTML>";
    for(const auto &e : v ){
        of << e << "<br/>" << endl;
        for(const auto ch : e){
            of << '[' << ch << ']' << endl;
        }
    }
    of << "</HTML>";

вместо ожидаемого вывода
русский
[р]
[у]
[с]
...
получаю
русский
[?]
[?]
[?]

Среда разработки - QT Creator под Win7. Кодировка исходника - UTF8. Кодировка выходного файла (как установил) - UTF8. Получается, т.к. std::string ничего о UTF не знает, при выводе строки целиком "магическим образом" происходит преобразование в UFT8, а вот при выводе "по символу" такого преобразования не происходит...

Как можно весь текст привести к одной локали?
Ответ: (boost.org/libs/locale)

или перевести utf8 to utf16
Вопрос: Юникод и utf8

Юнико́д активно всем навязывали и наконец практически всем навязали.

Эта штука реально бесит. С какой стати мы должны платить увеличением объема строк в два раза из-за китайцев, у которых ущербная письменность. Тогда как русский алфавит прекрасно умещается в один байт.

А utf8 нарушает представление строки в виде массива символов, на что рассчитаны все алгоритмы с начала эры программирования.

Причем англосаксы то себе неудобств этим utf8 создали намного меньше, чем другим, т. к. их символы в нем записываются в один байт. Вероятно, многие из них даже не учитывают возможную многобайтовость символов и работают с ними как с одиночными байтами.

Зато все другие языки низвели до иероглифов.

Как вы относительсь к юникоду и utf8? По мне что то, что другое - зло.
Ответ: Что за файл? CSV?
Вопрос: Работа с UTF8 в Lazarus 1.6

Здравствуйте.
При загрузке проекта в недавно вышедший Lazarus 1.6 получаю предупреждения, что функции работы с юникодом SysToUTF8 и UTF8ToSys не работают ("deprecated").
При компиляции и запуске проекта получаю ошибку, например, при подключении к базе данных:
Delphi
1
2
3
4
5
6
7
8
9
  curpath:=SysToUTF8(ExtractFilePath(Application.ExeName));
  with DBForm.AccessODBCConnection do
  try
    ...
    Params.Add(UTF8ToSys('DBQ='+curpath+'base\base.mdb'));    
    Connected:=true;
  except
    ...
  end;                
Как правильно сейчас работать с utf8? Как я понимаю, есть новый модуль, который требуется подключить lazutf8 и использовать функции оттуда. Но в этом модуле функции имеют то же самое название, например:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function UTF8ToSys(const s: string): string;
begin
  {$IFDEF UTF8_RTL}
  Result:=s;
  {$ELSE}
  if NeedRTLAnsi and (not IsASCII(s)) then
    Result:=UTF8ToAnsi(s)
  else
    Result:=s;
  {$ENDIF}
end;
 
function SysToUTF8(const s: string): string;
begin
  {$IFDEF UTF8_RTL}
  Result:=s;
  {$ELSE}
  if NeedRTLAnsi and (not IsASCII(s)) then
  begin
    Result:=AnsiToUTF8(s);
    {$ifdef FPC_HAS_CPSTRING}
    // prevent UTF8 codepage appear in the strings - we don't need codepage
    // conversion magic in LCL code
    SetCodePage(RawByteString(Result), StringCodePage(s), False);
    {$endif}
  end
  else
    Result:=s;
  {$ENDIF}
end; 
Собственно, повторюсь, как теперь нужно работать со строками utf8 в Lazarus?
Ответ: edukra, кажется, разобрался.
Аналогами функций UTF8ToSys и SysToUTF8 теперь являются UTF8ToWinCP и WinCPToUTF8 соответственно (разумеется, речь о Windows).
Но теперь в Lazarus системная кодировка автоматически меняется на utf8 везде, поэтому в примере выше функция ExtractFilePath возвращает строку в кодировке utf8, а не в системной, как раньше. Следовательно, нужно поменять только кодировку строки подключения к БД на системную.
Правильно будет так:
Delphi
1
2
3
4
5
6
7
8
9
10
  
  curpath:=ExtractFilePath(Application.ExeName); .// убрал SysToUTF8
  with DBForm.AccessODBCConnection do
  try
    ...
    Params.Add(UTF8ToWinCP('DBQ='+curpath+'base\base.mdb')); // заменил UTF8ToSys на UTF8ToWinCP   
    Connected:=true;
  except
    ...
  end;
В uses нужно подключить модуль LazUTF8.
Вопрос: в кодировке UTF8 можно читать программно текстовый файл?

здравствуйте, щас пользуюсь кодом
Sub ReadTextFileLine()
 
Dim a As String
Open ("w:\new 2222.txt") For Input As #1
Do Until EOF(1)
Line Input #1, a
 MsgBox$ a
Loop
Close #1
 
End Sub

пока кракозябры выдаёт месседж в кодировке UTF8, если читать в кодировке ANSI текстовый файл тогда всё ОК, но нужно в кодировке UTF8, как? спасибо
Ответ: а скажите, если читать текстовый файл
AscW(любой_знак) всегда будет = 9474
Asc(любой_знак) всегда будет = 166
???
Вопрос: Клавиатурный сканер (или USB), QR-код и UTF8

Вот такая проблема.
Есть QR-код (во вложении), в котором данные - одна русская буква А в UTF8 и всё. Как пример.

Вот то, что приходит в окно с сообщениями при сканировании.

WM_CHAR:
(ANSI-окно) - EF BB BF D0 0A - т.е. BOM и 2 почти левых символа (для UTF8 русская А это D090)
(Unicode-окно) - EF 00 BB 00 BF 00 D0 00 0A 00 - т.е. не лучше

в WM_KEYDOWN приходит вообще куча всего, непонятно только, как это воспринять:
+
0090 00
0012 02
0060 02
0062 02
0063 02
0069 02
0012 02
0060 02
0061 02
0068 02
0067 02
0012 02
0060 02
0061 02
0069 02
0061 02
0012 02
0060 02
0062 02
0060 02
0068 02
0011 04
007B 04
0011 04
000D 04
0090 00
Это я сохраняю в FormKeyDown так:
FKeyLog := FKeyLog + IntToHex( Key, 4 ) + ' ' + IntToHex( Byte( Shift ), 2 ) + sLineBreak;


т.е. 26 нажатий, из которых в 1-м и в последнем клавиша 0x90, 4 непонятных нажатия с Ctrl в конце и перед этим 20 непонятных нажатий с Alt. Что это значит хотелось бы знать.

2-й день не могу победить. Есть у кого мысли? Спасибо.

К сообщению приложен файл. Размер - 4Kb
Ответ: JaDi, это не в тему о документации, по умолчанию он отсылает как раз через стандартные. А эти данные он чз Alt-нумпад отсылает, только неверно к сожалению.
Вопрос: Win-1251 в UTF8 в текстовый документ

Есть файл в win-1251, нужно загрузить его в memo/stringlist в кодировке UTF8
Delphi
1
2
3
4
5
6
7
8
9
var  s,sl :TStringList;
begin
S :=  TStringList.Create ;
sl :=  TStringList.Create ;
s.LoadFromFile('1.txt');
memo1.Font.Charset:= RUSSIAN_CHARSET;
memo1.Text := UTF8String(s.Text);
sl.Text:=s.Text;
sl.SaveToFile('file.txt', TEncoding.UTF8);
Это не работает
Как сделать правильно?

Добавлено через 7 минут
Вот изначальная кодировка

А такая нужна
Ответ: Кодировка исходного файла дос
Delphi
1
2
3
4
5
6
7
procedure TForm1.Button1Click(Sender: TObject);
 
begin
 
  Memo1.Lines.LoadFromFile('c:\1.txt', TEncoding.GetEncoding(866));
  Memo1.Lines.SaveToFile('E:\1_1.txt', TEncoding.UTF8);
end;
Вопрос: TStringList.SaveToFile(..., , TEncoding.UTF8); + без BOM

в общем надо в UTF8 записать файл, но только без BOM-заголовка (фигов веб шоб он сгорел, задолбалы войны с кодировками уже...)

я в кодировках не особо спец, может у кого есть решение? или знает как без БОМ-ка записать?
Ответ: В C++ Builder 2010 есть такая фича
Memo1->Lines->WriteBOM=false;
Memo1->Lines->SaveToFile(FileName, TEncoding::UTF8);

Думаю, в Delphi тоже должно быть