Delphi изменить кодировку файла
← →
juice © ( 2006-12-01 16:14 ) [0]
Я задавал тут этот вопрос но ответа так и не получил, ветка куда-то пропала. Проблема следующая:
при запуске моей программы на других машинах где на панели управления, Язык и региональные стандарты, Региональные параметры, Языковые стандарты и форматы установлено в "Английский(США)" вместо надписей выводятся вопросительные знаки. При смене этого параметра на "Русский" все становиться нормально. Мне тут советовали поставить "Русский" в "Язык программ, не поддерживающих Юникод" - так он там и стоит. Да и вообще, по логике вещей проблема должна быть в моей программе а не в настройках системы, ведь другие программы с латинскими символами отображаются нормально. Ничего особенного в моей прожекте тоже нет - попробовал создал новый проект, положил на форму стандартный лейбл - все те же знаки вопроса.
Dmitrij_K ( 2006-12-01 16:21 ) [1]
SetThreadLocale пробывал?
← →Juice © ( 2006-12-01 16:43 ) [2]
GetThreadLocale и там и там выдает 1033, значит не в этом проблема.
← →Германн © ( 2006-12-01 16:53 ) [3]
> juice © (01.12.06 16:14)
RUSSIAN_CHARSET у фонта стоИт?
Juice © ( 2006-12-01 17:28 ) [4]
> RUSSIAN_CHARSET у фонта стоИт?
Да
Loginov Dmitry © ( 2006-12-02 12:49 ) [5]
А шрифты стандартные? (Штифт: MS Sans Serif. Размеры: 10, 12, 14, 18. Стиль: обычный)
← →Juice © ( 2006-12-04 11:16 ) [6]
Да :
object Label1: TLabel
Left = 160
Top = 120
Width = 35
Height = 13
Caption = "привет"
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = "MS Sans Serif"
Font.Style = []
ParentFont = False
end
Anatoly Podgoretsky © ( 2006-12-04 11:22 ) [7]
> Juice (04.12.2006 11:16:06) [6]
Замени "MS Sans Serif" на Юникод шрифт
← →Max Zyuzin © ( 2006-12-04 11:48 ) [8]
>juice © (01.12.06 16:14)
Вопрос такой а у вас что стоит в Control Panel -> Regional and Language Options -> Anvanced -> Language for non-Unicode programs?
Juice © ( 2006-12-04 12:09 ) [9]
> Замени "MS Sans Serif" на Юникод шрифт
Не помогает
> Вопрос такой а у вас что стоит в Control Panel -> Regional
> and Language Options -> Anvanced -> Language for non-Unicode
> programs?
"Русский"
Juice © ( 2006-12-04 12:28 ) [10]
Слудующий эксперимент прошел успешно:
SET
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\1252 = с_1251, и перезагрузиться.
Только как мне теперь это использовать ? Менять этот пераметр перед первым запуском программы не есть хорошо, как заставить саму программу работать правильно ? Помогите разобраться, просто я вообще не улавливаю сути операции замены 1252(чего это номер?) на 1251
← →Anatoly Podgoretsky © ( 2006-12-04 12:36 ) [11]
> Juice (04.12.2006 12:28:10) [10]
Если боишься потерять свое рабочее место, то никому про это не говори.
← →Juice © ( 2006-12-04 13:04 ) [12]
> Anatoly Podgoretsky © (04.12.06 12:36) [11]
Ну тогда обьясните почему программа на машине где стоит английская локаль пытается взять 1252 кодовую страницу а на машине с русской 1251 ?
В настройках проекта стоит Language, LocaleId = $0419(Русский), в справке написано следующее :
The Language indicates which Code Page the users system will require to run the application, that is, it indicates which language the application displays. Choose the desired language from the drop-down list. The hex value of the selected locale appears above the drop-down box.
Note: You can only choose a language that is listed in the Control Panel Regional Settings dialog of your computer. Some versions of the Windows operating system do not include support for all languages (such as Far Eastern languages), and you may need to install the appropriate Language Pack before you can use those languages.
← →Anatoly Podgoretsky © ( 2006-12-04 13:53 ) [13]
> Juice (04.12.2006 13:04:12) [12]
> Ну тогда обьясните почему программа на машине где стоит английская локаль пытается взять 1252 кодовую страницу а на машине с русской 1251 ?
А чего тут объяснять, неверно написаная программа.
← →Juice © ( 2006-12-04 14:17 ) [14]
> А чего тут объяснять, неверно написаная программа
Ошибаетесь, программа таковой быть не может т.к. не содержит ни единой строчки кода :
File -> New -> Application, Drag&Drop TLabel, Label1.Caption = "тест". Все. Попробуйте сами, D7.
Anatoly Podgoretsky © ( 2006-12-04 15:09 ) [15]
> Juice (04.12.2006 14:17:14) [14]
На слабо берешь?
Продолжай и много тебе это поможет?
← →Juice © ( 2006-12-04 15:45 ) [16]
> Anatoly Podgoretsky © (04.12.06 15:09) [15]
Не понял.
Juice © ( 2006-12-04 17:50 ) [17]
Вот еще наблюдение -
procedure TForm1.FormCreate(Sender: TObject);
begin
Label2.Caption := "тест";
end;
Срабатывает правильно. Т.е. присвоение в рантайме работает а контролы у которых текст установлен в designtime отображают ". "
Juice © ( 2006-12-04 18:50 ) [18]
И еще наблюдение :
если переключить на машине где билдится проект локаль на английскую, открыть в делфи проект - увидим на формах вместо всех компонентов знаки вопросов. Теперь заново переопределив надписи (напр. кэпшены для TLabel) и сделав билд приложение будет нормально себя показывать на других машинах с английской локалью ! Казалось бы проблема решена, но . Теперь глюки вместо текста при запуске приложения на машинах где стоит английская локаль ! :) Подчеркиваю еще раз - проблема только с текстом который установлен свойствам компонентов в designtime, когда идет присвоение через код (label1.Caption="тест") все нормально. Кстати, аналогичное VCL-приложение созданное при помощи борланд студии отобраает текст нормально под всеми локалями. Наверное причина в самой Delphi 7 или ее настройках, только каких ?
Juice © ( 2006-12-05 11:06 ) [19]
Кто-то может обьяснить что нужно сделать чтобы приложение можно было запускать на машинах с разными локалями и не возникало проблем с отображением текстовых данных что хранятся в ресурсах?
← →Juice © ( 2006-12-05 12:33 ) [20]
Может перенести ветку обратно в "Основная" ?
← →Barloggg ( 2006-12-05 16:44 ) [21]
это разные винды.
дома ХР, на работе 98.
под 98 на кнопочках на форме писал по русски.
Пришел домой под ХР, чего-то дописал, скомпилил, принес на работу: и тут сабж!
что называется подкрался. и в исходниках тоже самое. а дома я плотно поработал.
я так понял что под ХР Дельфи (энтерпризе) русский шрифт обрабатывает как юникод, а под 98 Дельфи (триал) как ASCII.
Я малость прибалдел и переписал все кнопки на английском, а в onCreate ручками сделал переименование.
Дорого, конечно, но зато как сердито!
Barloggg ( 2006-12-05 16:46 ) [22]
точнее гоню. скомпиленный дома вариант везде выглядит нормально, а открытые и перекомпиленные сырцы на работе уже с вопросительными знаками. вот так-то.
← →Juice © ( 2006-12-05 17:17 ) [23]
Я вообще уже не знаю что делать, ну что тут еще можно сказать ?
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption := "тест";
Label2.Caption := "ANSI code-page = " + IntToStr(GetACP);
Label3.Caption := "OEM code-page = " + IntToStr(GetOEMCP);
end;
При тестировании приложения на обеих машинах на экране видим :
Label1 = тест
Label2 = ANSI code-page = 1251
Label3 = OEM code-page = 866
. что свидетельствует о том, что язык программ не использующих Юникод на обеих машинах выставлен одинаково и все должно быть ОК ! Но почему только строки которые хранятся в ресурсах отображаются неправильно ? И почему подмена параметра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\1252 на 1251 решает проблему?
Я вижу только одну причину - RTL Delphi какого-то черта оперируя с ресурсами определяет кодовую страницу согласно языковым стандартам и форматам а не кодовой странице установленной в системе. Почему . А главное как изменить такое поведение ?
← →Juice © ( 2006-12-05 17:26 ) [24]
Как я уже говорил, в студии такой проблемы нет. Но это понятно - я вычитал что она по умолчанию работает с Юникод-строками.
Но вот что еще выяснилось: создав аналогичное "чистое" приложение но в Delphi 5 этой проблемы не возникло . Хотя она явно не в Юникоде кодирует ресурсы. Короче, проблема явно в самой Делфи 7, причем явно не в моей - пробовал на двух машинах. Что скажите ?
Juice © ( 2006-12-07 15:50 ) [25]
В сети на форумах я находил аналогичные вопросы но нигде ответа так и не было. Может кому-то еще пригодится решение этой проблемы. По непонятным МНЕ причинам Delphi 7 извлекает строки из ресурсов беручи не кодовую страницу установленную в системе а основываясь на локали. Например при активной локали "Английский(США)" Delphi берет кодовую страницу 1252, в то время как в системе активна например 1251. Я решил проблему указанием нужной локали перед созданием форм, т.е. после Application.Initialize вызываю SetThreadLocale где в качестве аргумента подаю номер той локали в которая была активна при разработке приложения. Вот так.
Здравствуйте у меня потребность в том, чтобы считать из файла данные и записать в другой с другой кодировкой. Я считываю из файла с кодировкой ANSI и преобразую в UTF8 с использованием Функции AnsiToUTF8, русские символы превращаются во что то непонятное. Как можно это пофиксить?
Смена кодировки текста
Здравствуйте. Прошу подсказать, можно ли менять кодировку текста (в RichEdit, допустим) «на лету».
Смена кодировки на UTF-8 (XE8)
На форме имеется компонент едит с редактируемым пользователем тексом. По нажатию кнопки текст из.
Смена кодировки
Здравствуйте дорогие пользователи форума. У меня такая проблема, вообщем в переменной pass типа.
Смена кодировки XML файла
У меня XML документ содержит русские буквы, поэтому encoding должен быть 1251. Но в документах, с.
Таймер используется т.к файл постоянно изменяется. И из него берутся данные, которые записываются в файл расчистанный на кодировку UTF8 и очищает с другой кодировкой.
Если я опущу преобразование типов, то он мне файл поменяет в ANSI. Или не так?
У меня есть текстовый файл который фиксирует значение введенные в чат игры. Если что то изменяется в ней, то сразу же заносится в этот файл.
В Delphi же работа идет всегда с кодировкой UTF-8, а она дает ANSI, поэтому.
Насчет таймера, мне проще чтобы он добавлял каждые 10 секунд, чем копировать. Я составляю чатлог за весь день. А потом в любой момент обратиться к нему и узнать сколько там элементов нужных мне находятся.
В RAD Studio, начиная с самых первых его версий, методы LoadFromFile и SaveToFile класса TStringList являются перегруженными и имеют вторым параметром именно кодировку файла (класс TEncoding). Вот его и используйте.
Да, в Дельфи 7 этого нет. Но писать приложение для работы с юникодом в неюникодной версии Дельфи - то еще извращение.
Добавлено через 21 секунду
Constcat, вопрос прочитайте! Нет, Д7 не умеет работать с юникодом (если только при помощи сторонних модулей и компонент, но это настолько не характерно, что это можно не учитывать вообще). Но при чем тут Д7?
Не вижу смысла в этом вопросе, но отвечу - да, но не нативно. В умелых руках и член - балалайка. ©
И, таки я настаиваю - похороните уже Д7, её жизненный цикл давно завершён, поэтому работа с ней сильно добавляет проблем.
Нет, Д7 не умеет работать с юникодом (если только при помощи сторонних модулей и компонент, но это настолько не характерно, что это можно не учитывать вообще). Но при чем тут Д7?
Ну, я, как бы споткнулся о противоречия. ТС, судя по всему, пишет на D7 и говорит, что Delphi не умеет работать с юникодом. Подразумевая, как я понимаю, Delphi 7. Ниже опытные форумчане утверждают, что это неправда. И они же подтверждают, что Delphi 7 таки не знает юникод. Вот и решил разобраться, т.к., сам пользуюсь D7
Добавлено через 3 минуты
И, таки я настаиваю - похороните уже Д7, её жизненный цикл давно завершён, поэтому работа с ней сильно добавляет проблем.
Не понимаю, откуда столько эмоций? Кому D7 доставляет проблемы? Под свои задачи, не требующие кроссплатформенности и пр. юникода, D7 - просто супер. И exe'шниники делает маленькие и быстрые. Напомню, что еще вовсю крутится парк машин, на которых XP.
Не нравится D7 - никто же не заставляет помогать тем, кто пишет на D7. Откуда проблемы?
Вообще, нигде не было информации о том, что ТС пользуется D7. Единственно, я это упомянул на случай, чтобы вопросов не возникало по поводу методов класса TStringList. И вопрос ТС-а про юникод Выглядел вот так:
Прогресс на месте не стоит, понимаешь? Намеренно юзать IDE 20-летней давности - это шиза.
Лично я пытаюсь помочь пересесть с D7 на новую IDE, видя, как чувак мучается (например, с юникодом). На WinXP программы, собранные современными компайлерами, тоже будут работать, если очень надо. Однако, в большинстве случаев, люди юзают Д7 на Windows 10, потому что им лениво адаптироваться под DXE.
Я юзаю D7 намеренно. Мой основной инструмент - Visual Studio/XCode, C++/Objective C/Python. D7 - это хобби, приятная для души ностальгия.
Студенты, например, должны использовать D7, потому что методички и преподаватели. С концептом "шиза" и "пересаживайтесь на новую IDE" тебя просто не поймут.
Не говоря уже о том, что Delphi, как инструмент, больше для любителей и энтузиастом, чем для промышленного производства, с учетом современных технологий и требований.
Так что мое мнение - пусть каждый сидит кто на чем хочет. :)
Оно того не стоит. Пусть мои ехе-шники будут побольше, зато я буду юзать юникод, дженерики, x64-компилятор и прочие фишки DXE, упрощающие и ускоряющие мне работу.Студенты, например, должны использовать D7, потому что методички и преподаватели. С концептом "шиза" и "пересаживайтесь на новую IDE" тебя просто не поймут.
Не говоря уже о том, что Delphi, как инструмент, больше для любителей и энтузиастом, чем для промышленного производства, с учетом современных технологий и требований.
Ну я хз, 20 лет на ней работаю и очень неплохо зарабатываю. У нас на заводе главный критерий - скорость разработки, т.к. сроки - "всегда вчера". Только delphi позволяет такое.
Оно того не стоит. Пусть мои ехе-шники будут побольше, зато я буду юзать юникод, дженерики, x64-компилятор и прочие фишки DXE, упрощающие и ускоряющие мне работу.
Дженерики - попытка допрыгнуть до C++. И вообще, последние тенденции развития Delphi выдают комплексы по отношению к C-подобным языкам. Может, даже когда-то и множественное наследование прикрутят.
Или возможность объявить объект в стеке.
У нас на заводе главный критерий - скорость разработки, т.к. сроки - "всегда вчера". Только delphi позволяет такое.
Смена кодировки текстового файла
при нажатии на кнопку необходимо сменить кодировку текстового файла с 866(OEM - русская) на.
Смена кодировки отдаваемого файла (csv)
Сайт работает в utf-8, везде и указано Задача: вывод таблицы MySQL в файл .csv для дальнейшей.
Смена кодировки
Здравствуйте подскажите как можно из jTextField в переменную типа String с заменой кодировкой в utf8
Смена кодировки
У меня выгрузка документа происходит так: File.WriteAllText(@"C:\Выгрузка\name.csv".
Смена кодировки
Помогите доработать функцию. // Перекодирование function cp1251_to_utf8 ($txt) < $in_arr.
. when altering one's mind becomes as easy as programming a computer, what does it mean to be human.
6 Answers 6
The Utf8Encode function takes a WideString string as parameter and returns a Utf-8 string.
The OP tagged the question as delphi-7. In Delphi 7, strings as ANSU by default, so the strings existing in TStringList are also ANSI. Are you sure this will work?
@AlexSC yes (I assume that the files have been created using the same default ANSI code page which is used by the Delphi program)
Take a look at GpTextStream which looks like it works with Delphi 7. It has the ability to read/write unicode files in older versions of Delphi (although does work with Delphi 2009) and should help with your conversion.
Please read the whole answer before you start coding.
The proper answer to question - and it is not the easy one - basically consist of tree steps:
- You have to determine the ANSI code page used on your computer. You can achieve this goal by using the GetACP() function from Windows API. (Important: you have to retrieve the codepage as soon as possible after the file name retrieval, because it can be changed by the user.)
- You must convert your ANSI string to Unicode by calling MultiByteToWideChar() Windows API function with the correct CodePage parameter (retrieved in the previous step). After this step you have an UTF-16 string (practically a WideString) containing the file name list.
- You have to convert the Unicode string to UTF-8 using UTF8Encode() or the WideCharToMultiByte() Windows API. This function will return an UTF-8 string you needed.
However this solution will return an UTF-8 string containing the input ANSI string, this probably is not the best way to solve your problems, since the file names may already be corrupted when the ANSI functions returned them, so proper file names are not guaranteed.
The proper solution to your problem is ways more complicated:
If you want to be sure that your file name list is exactly clean, you have to make sure it won't get converted to ANSI at all. You can do this by explicitly using the "W" version of the file handling API's. In this case - of course - you can not use TFileStream and other ANSI file handling objects, but the Windows API calls directly.
It is not that hard, but if you already have a complex framework built on e.g. TFileStream it could be a bit of a pain in the @ss. In this case the best solution is to create a TStream descendant that uses the appropriate API's.
I hope my answer helps you or anyone who has to deal with the same problem. (I had to not so long ago.)
← →Мишаня7-8 ( 2011-12-05 02:52 ) [0]
Привет мастера! Нужно сохранить текстовый файл с данными в кодировке ANSI as UTF-8. Юзаю такой код:
AssignFile(F,"myfile.txt");
Rewrite(F);
WriteLn(F,"Example");
CloseFile(F);
получаю текстовый файл в кодировке ANSI. Что делаю не так?
Германн © ( 2011-12-05 03:00 ) [1]
> получаю текстовый файл в кодировке ANSI. Что делаю не так?
Всё.
Мишаня7-8 ( 2011-12-05 03:04 ) [2]
Как надо? Помогите пожалуйста.
← →mike ( 2011-12-05 03:19 ) [3]
Сначала пойми задачу. Ибо "с данными в кодировке ANSI as UTF-8" - это бред.
← →KilkennyCat © ( 2011-12-05 03:39 ) [4]
> Нужно сохранить текстовый файл
выше приведенный код этого не делает, он создает новый файл.
исходя из этого, есть предположение, о неверной формулировке вопроса.
например: нужно сохранить данные в текстовый файл.
Медвежонок Пятачок © ( 2011-12-05 11:50 ) [10]
если для примера, то лови ответ для примера:
в твоем коде данные в файл пишутся не в утф-8 и поэтому внутри файла не утф-8 данные.
megavoid © ( 2011-12-05 12:22 ) [11]
var
t: TStringlist;
begin
t := tstringlist.create;
try
t.add("utf8line");
t.savetofile("file.txt", TEncoding.UTF8);
finally
t.free;
end;
end;
d7
← →Мишаня7-8 ( 2011-12-05 12:38 ) [13]
>megavoid (Embarcadero Delphi 2010) Спасибо! Буду пробовать.
← →Мишаня7-8 ( 2011-12-05 13:26 ) [14]
>OW В утф.txt всеравно ANSI :(
>megavoid Сохраняет в UTF но з BOM, а нужно без иначе неверно распознает мобила
procedure StringSave(const Filename: TFileName; const Data: UTF8String);
var
FS: TFileStream;
begin
FS := TFileStream.Create(FileName, fmCreate);
try
FS.Write(Pointer(Data)^, Length(Data));
finally
FS.Free;
end;
end;
var
t:TStringlist;
begin
t := tstringlist.create;
try
t.add("BEGIN:VCARD");
t.add("VERSION:2.1");
t.add("N;CHARSET=UTF-8;ENCODING=8BIT:дядя Вася");
t.add("TEL;PREF;VOICE;ENCODING=8BIT:0957676345345");
t.add("END:VCARD");
StringSave("дядя Вася.vcf", UTF8Encode(t.Text));
finally
t.free;
end;
Можт кому пригодится ;)
← →OW © ( 2011-12-05 14:18 ) [19]
> Мишаня7-8 (05.12.11 13:26) [14]
>
> >OW В утф.txt всеравно ANSI :(
у меня в UTF-8 без BOM сохраняет
30 апреля 2010 г.
Работа с текстовыми файлами в любой кодировке из Delphi до 2009
Как должно быть известно любому программисту, не существует такой вещи как "просто текстовый файл". Если вы не знаете, в какой кодировке хранится строка, вы не только не сможете её показать, но даже определить, где она заканчивается.
Мир вокруг нас уже давно не ограничивается ANSI, а уж тем более ASCII. На фоне этого ваши древние ANSI-программы выглядят не очень-то хорошо. Потому что они молчаливо игнорируют существование альтернативных кодировок вообще. Для них существует только текущая кодовая страница ANSI, не больше и не меньше.
Хотя самое нормальное решение включает в себя переход на Delphi 2010, часто вас и пользователей устраивает ваше ANSI-приложение, если бы. оно работало бы с любыми текстовыми файлами. Как это достигается? Ну, в начале текстового файла вставляется метка BOM (Byte Order Mask), указывающая на кодировку файла. Это означает, что если вы хотите загрузить произвольный текстовый файл, то вам нужно прочитать несколько байт в начале файла, после чего определить формат файла и преобразовать его в нужный вам - это довольно много работы, не так ли?
Как это реализуется в Delphi? В Delphi 2009 и выше у вас появляется класс TEncoding, позволяющий работать с различными кодировками. Класс TStrings (и TStringList) используют TEncoding для определения кодировки файла и всех преобразований.
Было бы неплохо заиметь такую штуку, скажем в Delphi 7 или Delphi 2007? К счастью, это очень просто сделать (эй, это заняло примерно 8 минут моего времени, включая проверку). Нужно просто вытащить из Delphi 2010 код TEncoding и новые методы LoadFromFile(Stream)/SaveToFile(Stream).
Представляю вашему вниманию два модуля: Encoding.pas - здесь сидит новый класс TEncoding - штука, полезная сама по себе, даже если вы не используете её для работы с текстовыми файлами.
Второй модуль, StringListUnicodeSupport.pas методом Geo добавляет в обычный TStringList поддержку произвольной кодировки, а также перегруженные варианты методов загрузки и сохранения, позволяющие указать кодировку явно (SaveToFile/Stream сохраняют в ANSI, если вам нужна другая кодировка, вы должны указать её вторым параметром).
Вам достаточно подключить StringListUnicodeSupport в uses и вы волшебным образом получаете возможность работы с любыми текстовыми файлами:
Как пользователи динозаврических Delphi вы, вероятно, не знакомы с TEncoding и перегруженным вариантом методов TStrings. Что ж, к счастью, вы можете воспользоваться online-справкой: TEncoding, использование TEncoging, LoadFromFile, SaveToFile.
I written a program with Delphi 7 which searches *.srt files on a hard drive. This program lists the path and name of these files in a memo. Now I need convert these files from ANSI to UTF-8, but I haven't succeeded.
@Miles: Windows use "ANSI" to means whatever your locale is. It would be SJIS for japanese windows user; GB2312 for S-Chinese windows user, etc.
Читайте также: