[SOLVED] Кодировка в GUI и Console приложениях.

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

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

[SOLVED] Кодировка в GUI и Console приложениях.

Сообщение yus » 01.09.2018 10:12:18

Добрый день, коллеги!

Столкнулся со следующей проблемой и из-за недостатка знаний не могу понять как ее решить, хочется чтоб Console реализация работала так же как и GUI реализация с UTF8.

Выглядит это так (для примера все упрощено).
Имеется текстовый JSON файл в UTF8 кодировке с которым я работаю

GUI реализация с одной кнопочкой на форме.
Код: Выделить всё
unit umain;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, fpjson, jsonparser, googlecalendar;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  s: TStringList;
  j: TJSONData;
  evt: TEvents;

begin
  // читаю из файла
  s := TStringList.Create;
  s.LoadFromFile('../test.json');

  // перевожу в JSON
  j := GetJSON(s.Text);
  FreeAndNil(s);

  // создаю объект списка событий (класс из GoogleCalendar)
  evt := TEvents.Create();
  evt.LoadFromJSON(TJSONObject(j));

  // Сохраняю в файл из GUI версии, сохраняется в UTF8
  s := TStringList.Create;
  s.Text := evt.items[0].summary;
  s.SaveToFile('../res_gui.txt');
  FreeAndNil(s);
end;

end.



Console реализация
Код: Выделить всё
program uconsole;

{$mode objfpc}{$H+}


uses {$IFDEF UNIX} {$IFDEF UseCThreads}
  cthreads, {$ENDIF} {$ENDIF}
  Classes,
  fpjson,
  jsonparser,
  SysUtils,
  googlecalendar { you can add units after this };

var
  s: TStringList;
  j: TJSONData;
  evt: TEvents;

begin
  // читаю из файла
  s := TStringList.Create;
  s.LoadFromFile('../test.json');

  // перевожу в JSON
  j := GetJSON(s.Text);
  FreeAndNil(s);

  // создаю объект списка событий (из GoogleCalendar)
  evt := TEvents.Create();
  evt.LoadFromJSON(TJSONObject(j));

  // Сохраняю в файл из Console версии сохраняется в Ansi
  s := TStringList.Create;
  s.Text := evt.items[0].summary;
  s.SaveToFile('../res_console.txt');
  FreeAndNil(s);
end.


Вопрос! Почему одна и та-же реализация из под GUI сохраняет значение, которое я получил у объекта evt, в UTF8, а консольная реализация выполняя тот же самый код получает его в Ansi?
Сохранение в файл показывает что в случае с GUI это UTF8 строка, а в случае с Console версией это Ansi строка.

Добавление в консольную реализацию {$Codepage UTF8} не помогает.

OS: Windows 7 SP1 RU. (под Linux не пробовал)
Lazarus: 1.8.4. SVN: 57972.

В архиве прикладываю исходники GUI и Console реализации с демо JSON файлом.

Спасибо.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось yus 01.09.2018 11:47:26, всего редактировалось 1 раз.
yus
новенький
 
Сообщения: 23
Зарегистрирован: 29.03.2015 14:29:29
Откуда: Томск

Re: Кодировка в GUI и Console приложениях.

Сообщение SSerge » 01.09.2018 11:12:50

yus писал(а):Сохранение в файл показывает что в случае с GUI это UTF8 строка, а в случае с Console версией это Ansi строка.

Вообще-то не показывает. У вас при сохранении внутренними средствами библиотек скорее всего производится перекодировка в то, что указано кодовой страницей RTL по умолчанию. В лазарусе (GUI) там принудительно выставлено UTF8. В "голом" FPC - автоопределение, т.е. будет взята основная кодовая страница операционной системы или среды окружения.

https://www.freepascal.org/docs-html/rt ... pport.html
- там в первом раздельчике ряд системных переменных, определяющих кодировку. Стоит посмотреть на них под лазарусом и в консольном проекте сделать также. Скорее всего, этого будет достаточно.
SSerge
энтузиаст
 
Сообщения: 842
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Кодировка в GUI и Console приложениях.

Сообщение yus » 01.09.2018 11:32:03

Спасибо! я погляжу в этом направлении.
Я так же подозреваю что это связано с некими настройками.


SSerge писал(а):Вообще-то не показывает.

Но для консольной версии если сделать так
Код: Выделить всё
  str : string
...
   str := evt.items[0].summary;

то дебагер для консольной версии показывает значение переменной str = ????? а GUI версия читабельное значение.

Добавлено спустя 12 минут 19 секунд:
SSerge писал(а):https://www.freepascal.org/docs-html/rt ... pport.html
- там в первом раздельчике ряд системных переменных, определяющих кодировку. Стоит посмотреть на них под лазарусом и в консольном проекте сделать также. Скорее всего, этого будет достаточно.


Да тут сразу видно отличия.

для GUI версии
DefaultSystemCodePage = 65001
для Console версии
DefaultSystemCodePage = 1251

Если в консольной версии DefaultSystemCodePage присвоить 65001 то начинает работать так как я хочу.

Теперь пытаюсь понять откуда мне взять это число 65001 в консольной версии :)

Добавлено спустя 2 минуты 10 секунд:
Нашел CP_UTF8 = 65001;
Спасибо за ответы.
yus
новенький
 
Сообщения: 23
Зарегистрирован: 29.03.2015 14:29:29
Откуда: Томск


Вернуться в Lazarus

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

Сейчас этот форум просматривают: MailRu[bot] и гости: 8

Рейтинг@Mail.ru