powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Вывод в Memo японских иероглифов (932-я кодовая таблица)
25 сообщений из 70, страница 1 из 3
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570653
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Столкнулся с проблемой вывода в Memo японских иероглифов.

Имеем японскую фразу " こんにちは " (по русски - " Добрый день ").
К сожалению форум не позволил мне вывести эти символы, поэтому вывожу графику:

В кодовой таблице " SHIFTJIS " ( 932 ) это будет " 82B182F182C982BF82CD " (Hex).

На Форме находятся кнопка " Button " и " Memo ", в свойствах шрифта которого выбрана Charset=" SHIFTJIS_CHARSET ".
Процедура обработки нажатия кнопки:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
//==============================================================================
procedure TMainForm.ButtonClick(Sender: TObject);
var
i: Integer;
const
Bytes: array[0..9] of byte = ($82, $B1, $82, $F1, $82, $C9, $82, $BF, $82, $CD);
begin
     Memo.Lines.Add('"Добрый день" по японски: "');
     for i := 0 to 9 do
          begin
               Memo.Lines[Memo.Lines.Count-1]:=
                    Memo.Lines[Memo.Lines.Count-1] + AnsiChar(Bytes[i]);
          end;
     Memo.Lines[Memo.Lines.Count-1]:=
          Memo.Lines[Memo.Lines.Count-1] + '"';
end;
//==============================================================================


На выходе имеем вот такой результат:



Подскажите плизз - как решить задачку?

P . S . И еще попутный вопрос - как добавить в Дэлфи кодовую таблицу 20932 ?
(Что бы ее можно было для выбрать в свойстве Font.Charset для Memo !)
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570654
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

всё замечательно расписано, кроме главных вводных: версия среды и версия операционки.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570655
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaonBellic,
всё замечательно расписано, кроме главных вводных: версия среды и версия операционки.
Пардон, еще же подумал, что надо бы сделать!..))

- Windows 7 6.1 (Build 7601: Service Pack 1), 32-bit, включена поддержка Японского языка.
- Delphi® XE3 Version 17.0.4625.53395.

P . S . я понял так, что свое сообщение я уже не могу подправить после опубликования?
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570657
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Без unicode-строки текст в TMemo для указанного примера в любом случае будет искажен - неправильно будут отображаться либо русские символы, либо японские. Соответственно коды букв должны быть 2х байтные (Word), а не Byte
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570659
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asutp2Без unicode-строки текст в TMemo для указанного примера в любом случае будет искажен - неправильно будут отображаться либо русские символы, либо японские. Соответственно коды букв должны быть 2х байтные (Word), а не Byte
Дело в том что приведенный пример кода максимально приближен к Реальному проекту , а в нем идет побайтовое чтение из реального файла и вывод в Memo !
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570662
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще одна проблема - при чтении из файла среди "двухбайтовых" иероглифов могут встретиться "однобайтные" английские символы!
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570664
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

так не получится. нужно собрать нормальную юникодовую строку и затем её добавлять в memo.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570665
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как вариант - прочитать сразу как строку. смысл файл читать побайтно?
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570666
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

операционной системе фиолетово, как хранятся символы у тебя в файлах, и твой же пример этот факт демонстрируется во всей красе :)

Для решения проблемы используй unicode-строки, без уникода русские и японские символы одновременно в ansi отображаться не будут. исходные файлы нужно предварительно преобразовывать.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570667
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaonкак вариант - прочитать сразу как строку. смысл файл читать побайтно?
Я подумаю над этим, но ввиду необходимости вылавливания Упр.Символов в строке (А они там порой попадаются) - приходится читать побайтно!
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570670
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asutp2Bellic,
Для решения проблемы используй unicode-строки, без уникода русские и японские символы одновременно в ansi отображаться не будут.
А Русских символов в файлах вообще нет!
Там Английские и Японские! + Упр.Символы
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570672
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

без разницы, хоть китайские . управляющие символы можно вполне зафильтровать в строке.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570675
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaonBellic,
без разницы, хоть китайские . управляющие символы можно вполне зафильтровать в строке.
Есть ли вариант - доработать указанный выше код, что бы увидеть Иероглифы?
я еще слабо разбираюсь в Юникоде!
Можете реально код подправленный привести?
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570677
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

например так:

Код: pascal
1.
Memo.Lines.LoadFromFile('1.txt', TEncoding.UTF8);


Если данные сохранить в файл в utf8. Если кодировка другая - то поменяй на нужную.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570680
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
судя по этому:

авторпри чтении из файла среди "двухбайтовых" иероглифов могут встретиться "однобайтные" английские символы!

у тебя utf8 скорее всего.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570681
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaonBellic,
например так:
Код: pascal
1.
Memo.Lines.LoadFromFile('1.txt', TEncoding.UTF8);


Если данные сохранить в файл в utf8. Если кодировка другая - то поменяй на нужную.
Исходный файл - вообще не Текстовый!
Это двоичный файл прошивки для CPU в котором встречаются текстовые блоки на Английском, Японском и смешанном - ENG+JPN.
Поэтому преобразовать его не получится!
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570682
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще, общая идея такая:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  j: RawByteString; // этот тип не зависит от дефолтной кодировки OS
const
  Bytes: array[0..9] of byte = ($82, $B1, $82, $F1, $82, $C9, $82, $BF, $82, $CD);
begin
     Memo.Lines.Add('"Добрый день" по японски: "');
     for i := 0 to 9 do
          begin
            j := j + AnsiChar(Bytes[i]);
          end;
     SetCodePage(j, 932, False); // указываем кодировку исходных данных
     Memo.Lines[Memo.Lines.Count-1]:=
       Memo.Lines[Memo.Lines.Count-1] + string(j); // тут дельфи неявно перекодирует j в юникод 
     Memo.Lines[Memo.Lines.Count-1]:=
          Memo.Lines[Memo.Lines.Count-1] + '"';
end;


Но имей в виду, что за конструкции типа "j := j + AnsiChar(Bytes[i]);" в цикле надо бить палками, потому что это дико неэффективно, как по скорости, так и по выделению памяти. Так что этот говнокод - только для примера решения твоей проблемы.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570683
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл добавить
Код: pascal
1.
j := '';

в самом начале процедуры, редактировать нельзя :(
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570685
либо так
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Либо таким методом, через TEncoding. Причем ты можешь обоими методами перекодировать и английские символы.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
b: TEncoding;
t: TBytes;
const
Bytes: array[0..9] of byte = ($82, $B1, $82, $F1, $82, $C9, $82, $BF, $82, $CD);
begin
     Memo1.Lines.Add('"Добрый день" по японски: "');
     b:= TEncoding.GetEncoding(932);
     SetLength(t, Length(Bytes));
     Move(Bytes[0], t[0], Length(Bytes));
     Memo1.Lines[Memo1.Lines.Count-1]:=
                    Memo1.Lines[Memo1.Lines.Count-1] + b.GetString(t);
     Memo1.Lines[Memo1.Lines.Count-1]:=
          Memo1.Lines[Memo1.Lines.Count-1] + '"';
end;
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570688
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо большое! - По разбираюсь пока с Кодами..)
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570704
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Второй вариант мне больше понравился!
Попробовал вариант с текстом ENG + JPN :
Код: pascal
1.
2.
Bytes: array[0..24] of Byte = ($4C,$41,$4E,$90,$DA,$91,$B1,$8B,$40,$8A,$ED,$83,
     $6F,$81,$5B,$83,$57,$83,$87,$83,$93,$8F,$EE,$95,$F1);


Класс!!!

Осталось решить - как при выводе на лету заменить внутри байт $ 0A на $ 40 (символ ' @ '), если таковой встретится!?
Например если:
Код: pascal
1.
2.
Bytes: array[0..25] of Byte = ($4C,$41,$4E,$0A,$90,$DA,$91,$B1,$8B,$40,$8A,$ED,$83,
     $6F,$81,$5B,$83,$57,$83,$87,$83,$93,$8F,$EE,$95,$F1);
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570731
Dunkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ещё вариант:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
type
  JapanString = type AnsiString(932);

procedure TForm1.ButtonClick(Sender: TObject);
var
  i: Integer;
  j: JapanString;
const
  Bytes: array[0..9] of byte = ($82, $B1, $82, $F1, $82, $C9, $82, $BF, $82, $CD);
begin
  Memo.Clear;
  Memo.Lines.Add('"Добрый день" по японски: "');
  j := PAnsiChar(@Bytes[0]);
  Memo.Lines[Memo.Lines.Count-1]:=
    Memo.Lines[Memo.Lines.Count-1] + string(j);
  Memo.Lines[Memo.Lines.Count-1]:=
    Memo.Lines[Memo.Lines.Count-1] + '"';
end;


Во втором варианте утечка памяти - все TEncoding с нестандартными кодировками нужно прибивать.

StringReplace для замены "на лету", но лучше не "на лету".
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570770
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DunkinЕщё вариант:
Код: pascal
1.
2.
3.
4.
5.
6.
const
  Bytes: array[0..9] of byte = ($82, $B1, $82, $F1, $82, $C9, $82, $BF, $82, $CD);
begin
.....
  j := PAnsiChar(@Bytes[0]);
.....



Так, как исходный массив не заканчивается на $00, то эта конструкция будет работать только пока память после него случайно забита нулями. Как только там появятся какие-то другие значения - в тексте будет мусор и может случиться AV.
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39570788
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BellicDelphi® XE3 Version 17.0.4625.53395

Delphi 2009 и выше (т.е. в т.ч. и Delphi XE3) относятся к Unicode IDE. Это означает, что любые текстовые данные для вывода должны быть представлены в Unicode (UTF-16). Если ваши текстовые данные находятся в другом формате - их нужно предварительно преобразовать.

Bellicв свойствах шрифта которого выбрана Charset="SHIFTJIS_CHARSET"

Не нужно это делать. В Unicode вы не работаете с кодовыми страницами.

BellicИ еще попутный вопрос - как добавить в Дэлфи кодовую таблицу 20932?

Кодовая страница 20932 является частью Unicode. Она уже есть и используется. Не нужно её выбирать. И, кстати, по-моему, у вас данные - в 932, не в 20932.

Bellicв нем идет побайтовое чтение из реального файла

Читайте в RawByteString:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
var 
  JS: RawByteString; // 932
  S: String; // UTF-16
begin
  SetLength(JS, ваша_длина);
  SetCodePage(JS, 932, False); // укажем, что в JS будут данные в кодировке 932
  читаете_в_JS; // Move, ReadBuffer, ReadFile и т.д., например: Move(Bytes[0], Pointer(JS)^, Length(Bytes));
  S := String(S); // необязательно, только для удобства отладки
  Memo1.Text := S;
end;



Или, если кодировка фиксирована, то можно так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
type
  String932 = AnsiString(932);
var 
  JS: String932; // 932
begin
  SetLength(JS, ваша_длина);
  читаете_в_JS;
  Memo1.Text := String(S);
end;



Можно и через TEncoding, то смысла большого нет, больно громоздко для вашей задачи.

BellicК сожалению форум не позволил мне вывести эти символы

И ровно так же может случиться и в Delphi приложении. Чтобы пользователь успешно увидел правильный текст, нужно два компонента:
- Текст должен быть представлен без потерь в подходящей для вывода кодировке - это мы сделали выше
- В используемом шрифте должны быть отрисованы иероглифы, а не заглушки

По шрифтам больше информации - тут: http://www.transl-gunsmoker.ru/2009/05/blog-post_3589.html

Кратко:
- Если у вас выбран шрифт по умолчанию (Tahoma), то система сама выберет подходящий шрифт (если он вообще есть в системе) - т.н. "Font Fallback".
- Для старых систем лучше таскать шрифт с собой, поскольку в системе он может быть не установлен. Например, Arial Unicode MS.

BellicОсталось решить - как при выводе на лету заменить внутри байт $0A на $40(символ '@'), если таковой встретится!?

Управляющие символы преобразуются без изменений. Просто сконвертируйте в String и сделайте StringReplace (ну или циклом for).
...
Рейтинг: 0 / 0
Вывод в Memo японских иероглифов (932-я кодовая таблица)
    #39571130
Dunkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

Пф-ф. ТС наверняка в состоянии написать через Move. В реальной жизни вряд ли будет через статический массив.

При приведении PAnsiChar(TBytes) (оба типа managed, приводятся "на прямую") для строки будет выставлен размер TBytes?
...
Рейтинг: 0 / 0
25 сообщений из 70, страница 1 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Вывод в Memo японских иероглифов (932-я кодовая таблица)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]