Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.03.03;
Скачать: [xml.tar.bz2];

Вниз

Как перекодировать текст из Windows кодировки в Dos?   Найти похожие ветки 

 
Mishenka   (2004-02-19 14:41) [0]

Как перекодировать текст из Windows кодировки в Dos?
Делаю с помощью CharToOem, так он выдаёт ошибку EAccessViolation.
В чм может быть проблема?


 
Тимохов   (2004-02-19 14:43) [1]

код


 
zamkom   (2004-02-19 14:48) [2]

Вот тебе код как использовать CharToOem
CharToOem(@S[1], @S[1]);
где S : String;


 
Тимохов   (2004-02-19 14:51) [3]

@S[1] эквивалентно pchar(s)


 
zamkom   (2004-02-19 14:54) [4]

Тимохов © (19.02.04 14:51) [3]
Если заменить @S[1] на pchar(s) появляется ошибка.


 
Тимохов   (2004-02-19 14:59) [5]


> zamkom © (19.02.04 14:54) [4]

Т.е. вы оспариваете 3?


 
zamkom   (2004-02-19 15:02) [6]

Тимохов © (19.02.04 14:59) [5]
Я не оспариваю, я констатирую факт. :)


 
Mishenka   (2004-02-19 15:06) [7]

Вот код:


var F:TextFile;
P:PChar;

....

AssignFile(F,"Fi.dat");
Rewrite(F);
CharToOem(PChar("Оператор:"+Edit3.Text),P);
WriteLn(F,P);
CharToOem(PChar("Руководитель:"+Edit4.Text),P);
WriteLn(F,P);
CloseFile(F);


 
Тимохов   (2004-02-19 15:08) [8]

И что - он работает?
под p память выделяется?


 
Тимохов   (2004-02-19 15:09) [9]


> zamkom © (19.02.04 15:02) [6]

Интересно, правда есть ошибка.
Зато вот так все норамально

setlength(s1, length(s));
CharToOem(pchar(S), pchar(S1));

Интересно почему
CharToOem(pchar(S), pchar(S));
не работает?


 
Игорь Шевченко   (2004-02-19 15:11) [10]

function StrToOem(const AnsiStr: string): string;
begin
SetLength(Result, Length(AnsiStr));
if Length(Result) > 0 then
CharToOemBuff(PChar(AnsiStr), PChar(Result), Length(Result));
end;


 
MBo   (2004-02-19 15:15) [11]

>Тимохов
А если строка не константная? :)


 
Mishenka   (2004-02-19 15:18) [12]

В том-то и дело, что нихрена не работает. В чём трабл?


 
Тимохов   (2004-02-19 15:23) [13]


> В том-то и дело, что нихрена не работает. В чём трабл?

под p память наверное забыл выделить.


> MBo © (19.02.04 15:15) [11]


procecure p;
var
s: string;
begin
s := "дима";
chartooem(@s[1], @s[1]); // работает
chartooem(pchar(s), pchar(s)); // не работает
end;

интересно почему.

Примерно понятно, что здесь дело в константной строке. Только не очень понятно как именно это влияет.


 
Verg   (2004-02-19 15:33) [14]

Так , давай по пунктам
Строка - константа

> chartooem(@s[1], @s[1]); // работает

S[1] - заставляет компилер предварительно образовать отдельную копию (UniquString)


> chartooem(pchar(s), pchar(s)); // не работает


pchar(S)
Передает просто адрес строки символов без изменения.
Теперь задумайтес - где размещает компилер(а точнее линкер) Делфи константные строки?


 
Тимохов   (2004-02-19 15:37) [15]


> Verg © (19.02.04 15:33) [14]


> S[1] - заставляет компилер предварительно образовать отдельную
> копию (UniquString)

Эта фраза меня смущает? Скорее всего вы правы.
Не знал, что при обращении к символу компилятор догадается сделать копию.
Хотелось бы узнать где в хелпе это написано.


 
Игорь Шевченко   (2004-02-19 15:37) [16]


> где размещает компилер(а точнее линкер) Делфи константные
> строки


compiler.

Известно где - там, где их ближе всего с точки зрения процессора достать - в сегменте кода рядышком.


 
MBo   (2004-02-19 15:41) [17]

Трассировка показывает, что @s[1] приводит к вызову UniqueStringA, чего не делается при простом кастинге.
Для константной строки делается копия - в примере адрес меняется. А с кастингом к PChar он по-прежнему указывает на область памяти, предназначенную для констант.

procedure TForm1.Button2Click(Sender: TObject);
var s:string;
p:Pchar;
begin
s:="фффффффф";
//s:=StringOfChar("ф",8);
Memo1.Lines.Add(IntToHex(Integer(S),8));
p:=@s[1];
Memo1.Lines.Add(IntToHex(Integer(p),8));


 
Тимохов   (2004-02-19 15:42) [18]


> Игорь Шевченко © (19.02.04 15:37) [16]

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

Вопрос в другом, где описан этот

> S[1] - заставляет компилер предварительно образовать отдельную
> копию (UniquString)

факт?


 
Тимохов   (2004-02-19 15:43) [19]


> MBo © (19.02.04 15:41) [17]

Трассировка, как последнее средство.
По опыту общения с дельфей знаю, что в основном все хитрые приблуды описаны в ееной справке.

Интересно документированная ли это особенность?


 
AKul   (2004-02-19 15:48) [20]


> Игорь Шевченко © (19.02.04 15:37) [16]

> Известно где - там, где их ближе всего с точки зрения процессора
> достать - в сегменте кода рядышком.

Процессору все-равно где они расположены. Ему одинаково их доставать из любого адреса. Организация памяти в Windows"е является FLAT-моделью. Да и нет такого понятия, как сегмент кода, есть страницы памяти с флагом ReadOnly. Вот как раз для секции кода PE-файла загрузчик и устанавливает такой атрибут.
А размещает он их там потому, что присваиваемая строка - это константа и меняться она не будет. Да и нересурсоемко размещать константные значения в памяти имеющей атрибуты как для чтения, так и для записи.


 
Verg   (2004-02-19 15:50) [21]


> [19] Тимохов © (19.02.04 15:43)


примерно тут:

When indexing is used to change the value of a single character in a string, a copy of the string is made if—but only if—its reference count is greater than one. This is called copy-on-write semantics.


 
Тимохов   (2004-02-19 15:56) [22]


> When indexing is used to change the value of a single character
> in a string, a

Это я знаю.
ИМХО отлюда обсуждаемый вопрос не следует.
ИМХО changin это когда s[1] := "aaa";
Здесь же не все так очевидно для компилятора.
Думаю, что если компилятор способен так умно разобрать, то что я хочу сделать, он просто достоин восхищения. :))))


 
Verg   (2004-02-19 15:57) [23]

Из того, что объяснения самых "страшных и невероятных" ошибок обычно находятся в конце глав хелпов, можно сделать выводы о том, КАК мы читаем эти хелпы. :)))


 
Игорь Шевченко   (2004-02-19 15:57) [24]

AKul © (19.02.04 15:48)

Процессору-таки не все равно, откуда их доставать. Почему рядышком - чтобы не было page faults лишних.


 
Amoeba   (2004-02-19 16:02) [25]

Это работающий код (из RxLib, модуль StrUtils.pas):

function StrToOem(const AnsiStr: string): string;
begin
SetLength(Result, Length(AnsiStr));
if Length(Result) > 0 then
CharToOemBuff(PChar(AnsiStr), PChar(Result), Length(Result));
end;


 
Тимохов   (2004-02-19 16:04) [26]


> Verg © (19.02.04 15:57) [23]

Не очень понятно кому это вы. :)))))
Все же считаю, что ответ о нахождении в документации явного упоминания данной фичи не получен. Уверен, что в хелпе ответа не будет - я его в общем-то весьма хорошо знаю.

(Занесем на подкорку, как особенность дельфи в данном вопросе)


 
Verg   (2004-02-19 16:08) [27]


> Тимохов © (19.02.04 15:56)


Когда мы говорим @S[1] или передаем S[1] в качестве var в процедуру, то откуда компилеру знать, что это не есть тот самый случай "is used to change"?

Подумайте еще раз об этом и без горячки....

PS ИМХО Вы лезете "в бутылку"


 
Тимохов   (2004-02-19 16:10) [28]


> Verg © (19.02.04 16:08) [27]

Согласен со всем.
Лишний раз убеждаюсь, что дельфи умный компилятор.
С моей стороны тема закрыта.


 
AKul   (2004-02-19 16:14) [29]


> Игорь Шевченко © (19.02.04 15:57) [24]
> Процессору-таки не все равно, откуда их доставать. Почему
> рядышком - чтобы не было page faults лишних.


Вы чего??? :(
Процессору абсолютно все равно! А тем более расположены данные "рядышком" с кодом или нет (да и какой смысл у этой фразы???). "Данные" и "код" - это понятия для Вас, для меня; а для процессора: на какой адрес указывает CS:EIP - это и есть текущая инструкция (код), будь для Вас она хоть строкой.


 
Amoeba   (2004-02-19 16:19) [30]

Ну все, о вопросе забыли и началась "битва титанов"...


 
Игорь Шевченко   (2004-02-19 16:28) [31]

AKul © (19.02.04 16:14)

Боремся за чистоту высказываний. Процессору, да, разумеется все равно. Сколько времени будет потрачено на доставание нужного кода ему тоже все равно. Сколько при этом может произойти всяких побочных действий ему тоже все равно. А компилятор все равно старается размещать константы ближе к тому месту, где они используются.


 
AKul   (2004-02-19 16:33) [32]


> Amoeba © (19.02.04 16:19) [30]

Вы правы...

> Mishenka (19.02.04 15:06) [7]
Как адрес строки-приемника Вы передаете неинициализированный указатель P

Исправте так:

var F:TextFile;
S:string
....

AssignFile(F,"Fi.dat");
Rewrite(F);
S:="Оператор:"+Edit3.Text;
CharToOem(pchar(S),pchar(S));
WriteLn(F,S);
S:="Руководитель:"+Edit4.Text;
CharToOem(PChar(S),PChar(S));
WriteLn(F,S);
CloseFile(F);

Sorry, если где-нибудь ошибся в синтаксисе, исправлял тут...


 
Андрей Сенченко   (2004-02-19 16:39) [33]

AKul © (19.02.04 16:33) [32]

Около месяца назад здесь было обсуждение по поводу того, что CharToOem(PChar(S),PChar(S));
Может приводить к ошибкам.

Посмотрите - может еще не стерлось.
Насколько я помню, пришли к тому что нужно все-таки делать это разными переменными с выделением памяти под вторую.


 
default   (2004-02-19 16:41) [34]

Игорь Шевченко © (19.02.04 16:28) [31]
" А компилятор все равно старается размещать константы ближе к тому месту, где они используются."
а у этой фразы какой смысл?


 
Игорь Шевченко   (2004-02-19 16:42) [35]

default © (19.02.04 16:41)

Быстрее доступ к данным.


 
AKul   (2004-02-19 16:44) [36]


> Игорь Шевченко © (19.02.04 16:28) [31]
> компилятор все равно старается размещать константы ближе
> к тому месту, где они используются.

Потому что так ему проще!
Зачем расчитывать сколько будут занимать места строковые константы всех процедур в сумме, где-то их запоминать, а потом где-то размещать, если можно спокойно, компилируя текущую процедуру, тут же разместить ее данные.

Да и к тому же, если их разместить далеко от кода, в котором они используются, большая вероятность того, что они могут быть скинут в swap-файл, чем если они будут находится в странице памяти выполняющегося в данный момент кода!
Вот поэтому они распологаются рядом с кодом.


 
AKul   (2004-02-19 16:48) [37]


> Андрей Сенченко © (19.02.04 16:39) [33]
>
> Около месяца назад здесь было обсуждение по поводу того,
> что CharToOem(PChar(S),PChar(S));
> Может приводить к ошибкам.
> Посмотрите - может еще не стерлось

Помню, я сам на него отвечал.
Но в приведеном мною коде в посте [32] не будет ошибки.
Хотите знать почему, - сами посморите на то, куда меня послали...


 
Игорь Шевченко   (2004-02-19 16:50) [38]


> большая вероятность того, что они могут быть скинут в swap-файл,
> чем если они будут находится в странице памяти выполняющегося
> в данный момент кода!


Вот тут мы об одном и том же.


> Потому что так ему проще!


Неа:) Проще ему, как раз, все данные собрать в одном месте. Как изменяемые, так и не изменяемые.


 
default   (2004-02-19 16:50) [39]

Игорь Шевченко © (19.02.04 16:42) [35]
имели ввиду swap-файл говоря о скорости?


 
zamkom   (2004-02-19 16:50) [40]

Андрей Сенченко © (19.02.04 16:39) [33]
Да примерно месяц назад было обсуждение по данному вопросу.
Автором был я. :-)
Поэтому и привел код
zamkom © (19.02.04 14:48) [2]



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.03.03;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.007 c
14-6201
Cosinus
2004-02-11 18:27
2004.03.03
Интересно, это когда-нибудь надоест ? :))))


14-6193
phantom2040
2004-02-12 10:44
2004.03.03
Организация сети


1-6056
DmitryNekl
2004-02-18 21:39
2004.03.03
Массив элементов TStringList


1-6087
Тимохов
2004-02-19 12:24
2004.03.03
Вопрос по OLE


1-6073
N@$H
2004-02-21 14:31
2004.03.03
Свой task bar





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский