Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.02.2011, 12:15   #1
Yiguoliang
 
Регистрация: 01.02.2011
Сообщений: 6
Смех Китайский в Delphi

Здравствуйте! Есть проблема, текстовый файл формата txt, в нём записан текст, часть которого на китайском, считываю его построчно пока не закончится в строковую переменную s, в этом же цикле, в зависимости от условий изменяю строку s и записываю в другой файл. Как сделать так, чтобы Delphi воспринимал китайский текст? Мало того, что при считывании в строковую переменную текст на китайском превращается в бред, так еще и в самом исходном файле, после того, как с него считала программа текст становится бредом.
Yiguoliang вне форума Ответить с цитированием
Старый 01.02.2011, 12:45   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Цитата:
формата txt
Нет такого формата. Текст, скорей всего, в UTF8. Вот и читайте его как UTF8.

Цитата:
в самом исходном файле, после того, как с него считала программа текст становится бредом
Ну вы поняли.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.02.2011, 13:19   #3
Yiguoliang
 
Регистрация: 01.02.2011
Сообщений: 6
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
Текст, скорей всего, в UTF8. Вот и читайте его как UTF8.
Можно поподробнее? Как читать текст в UTF8?
Yiguoliang вне форума Ответить с цитированием
Старый 01.02.2011, 13:34   #4
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
Нет такого формата. Текст, скорей всего, в UTF8. Вот и читайте его как UTF8.
Да нет, есть у китайцев своя какая-то кодировка, не имеющая отношения к UTF. Типа GB2312 и всякое такое. Вот например исходный текст может выглядеть так:

Код:
// ЙиЦГ¶Ф»°їтµДД¬ИПЕдЦГОДјюID
void SetMsgBoxID(RESID* msg_box_config_id)
{
    *msg_box_config_id = ID_DEF_MSG_BOX_BLACK;
}

// КЗ·сПФКѕЎ°ёсКЅ»ЇNAND FLASHЎ±µД¶Ф»°їтЈ¬·µ»ШTRUEФКРнПФКѕ
// µ±ПµНі·ўПЦДъµДNand FlashОДјюПµНі»№Г»УРЅЁБўµДК±єтЈ¬»бµчУГґЛєЇКэ
// НЁіЈЈ¬Ц»УРі§јТ№аЧ°іМРтєуЈ¬іМРтµЪТ»ґОФЛРРК±Ј¬ІЕ»біцПЦґЛМбКѕ
BOOL BootOpt_ShowFormatFlashDlg(void)
{
    return TRUE;
}
А вообще должен выглядеть так:

Код:
// 设置对话框的默认配置文件ID
void SetMsgBoxID(RESID* msg_box_config_id)
{
    *msg_box_config_id = ID_DEF_MSG_BOX_BLACK;
}

// 是否显示“格式化NAND FLASH”的对话框,返回TRUE允许显示
// 当系统发现您的Nand Flash文件系统还没有建立的时候,会调用此函数
// 通常,只有厂家灌装程序后,程序第一次运行时,才会出现此提示
BOOL BootOpt_ShowFormatFlashDlg(void)
{
    return TRUE;
}
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 01.02.2011, 13:37   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Читать как поток байт, другое дело, как потом с этой строкой работать.
Можно перевести её в wide/unicodesting через Utf8ToUnicode() или через UTF8ToString(), если у вас Дельфи посвежее. И работать как с обычной юникодной строкой. Перед записью можно опять в UTF8 завернуть.

Цитата:
считываю его построчно
Тут тоже вопросы будут, как вы конец строки проверяете, как в s добавляете прочитанную строку.. Проще, имхо, как поток байт считать.

Опять же, точно надо узнать, что там внутри файла. Если начинается с $EF $BB $BF, то это UTF8. Если с $FF, $FE, то UTF16 (little endian) а если $FE, $FF, то UTF16 (big endian).

Это если руками. А если Дельфи 2009 или свежее, там стринглист вроде сам должен разобраться что к чему, но на 100% я не уверен.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.02.2011, 13:48   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

veniside, +1


тут у нас на форуме есть гуру Delphi - GunSmoker.
В частности, он является Большим докой в кодировках...

и вот, весьма рекомендую статью с его блога:
Работа с текстовыми файлами в любой кодировке из Delphi до 2009 (использоание TEncoding)
Цитата:
Как должно быть известно любому программисту, не существует такой вещи как "просто текстовый файл". Если вы не знаете, в какой кодировке хранится строка, вы не только не сможете её показать, но даже определить, где она заканчивается.
....
Serge_Bliznykov вне форума Ответить с цитированием
Старый 01.02.2011, 13:50   #7
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Цитата:
Сообщение от Tronix Посмотреть сообщение
Типа GB2312 и всякое такое
Ну если настолько с файлом не повезло, то после чтения можно эту ахинею перевести в UTF16 через WideCharToMultiByte(), задав CP936 или что-то подобное.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.02.2011, 17:41   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Вы пример файла покажите сначала.

P.S.
Цитата:
и вот, весьма рекомендую статью с его блога:
Работа с текстовыми файлами в любой кодировке из Delphi до 2009 (использоание TEncoding)
Та статья говорит про использование ANSI-строк. Что неприменимо в данном случае. Тут надо определиться с кодировкой и загружать в WideString. Но ссылка про "не существует такой вещи как "просто текстовый файл"" - очень верная, да.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.

Последний раз редактировалось GunSmoker; 01.02.2011 в 17:46.
GunSmoker вне форума Ответить с цитированием
Старый 01.02.2011, 20:01   #9
Yiguoliang
 
Регистрация: 01.02.2011
Сообщений: 6
По умолчанию

вот пример кода
Код:
program Project_Doc;

{$APPTYPE CONSOLE}

uses
  StringListUnicodeSupport;
  var
    f, f1: textfile;
    s, s1, s2: widestring;
begin
  assign(f, '1.txt');
  assign(f1, '2.txt');
  reset(f);
  rewrite(f1);
  s1 := #9 + '[m1]';
  s2 := '[/m]';
  while not eof(f) do
  begin
    readln(f, s);
    if (s[1] = #9) and (s[2] = '\') and (s[3] = '[') and (s[4] = '[') then
    begin
      delete(s,1,1);
      s := s1 + s;
      s := s + s2;
      writeln(f1, s);
      writeln(s);
    end
    else
    begin
      writeln(f1, s);
      writeln(s);
    end;
  end;
  close(f);
  close(f1);
end.
Вложения
Тип файла: txt 1.txt (2.4 Кб, 131 просмотров)
Yiguoliang вне форума Ответить с цитированием
Старый 01.02.2011, 21:10   #10
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Это файл в UTF-8 с BOM.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Китайский или Анлийский miscreant Свободное общение 30 22.01.2011 17:42
Rad Studio 2011 XE: новое в Delphi, C++ Builder, RadPHP и Delphi Prism savva-paladin Софт 18 02.10.2010 20:24
Delphi. Как нарисовать в Delphi два движущиеся шара с определенной скоростью? redred Общие вопросы Delphi 10 11.12.2007 10:43
Как открыть БД, написанную в Delphi если нf другой машине Delphi нет? dagarik БД в Delphi 7 22.10.2007 17:54