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

Вниз

Преобразование в DOS   Найти похожие ветки 

 
Zamik   (2004-01-14 10:08) [0]

Люди помогите начинающем.
Нужно писать в файлик строки в DOS формате.
Пожалуйста пример кода.


 
[lamer]Barmaglot   (2004-01-14 10:11) [1]

Из кодировки виндовс в кодировку Dos перекодируется с помощью функции - CharToOem или CharToOemBuff.


 
YuRock   (2004-01-14 10:13) [2]


var
S: String;
begin
...
CharToOem(PChar(S), PChar(S));
...
end;


Можно так например..


 
Zamik   (2004-01-14 10:51) [3]

При использовании
YuRock © (14.01.04 10:13) [2]
Delphi выдает ошибку:
Access violation at address 77D34CBD in module "user32.dll"
Помогите погибаю.


 
alex_***   (2004-01-14 10:55) [4]

если хочешь чтоб быстро помогали - приводи source


 
BiN   (2004-01-14 10:57) [5]

Zamik © (14.01.04 10:51) [3]

function W2DOS(const Buf:string):string;
begin
SetLength(Result, Length(Buf);
CharToOemBuf(Pchar(Buf), @Result[1], Length(Buf));
end;


 
Zamik   (2004-01-14 10:59) [6]

есть вот такой код

procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
begin
s:="получилось?";
CharToOem(PChar(S), PChar(S));
end;

при исполнении вот этой строки
CharToOem(PChar(S), PChar(S));
выдает
Access violation at address 77D34CBD in module "user32.dll"
Не знаю что и думать. Помогите мастера.


 
PVOzerski   (2004-01-14 11:05) [7]

А вот так работает:
CharToOem(PChar(@S[1]), PChar(@S[1]));
А почему не работает CharToOem(PChar(S), PChar(S)); - в самом деле, интересно...


 
[lamer]Barmaglot   (2004-01-14 11:10) [8]

тогда уж либо
CharToOem(PChar(S[1]), PChar(S[1]));
либо
CharToOem(@S[1], @S[1]);

Все просто сама строка начинается с места S[1], до этого момента идет описание структуры, которое преобразованию естественно не подлежит...


 
Zamik   (2004-01-14 11:13) [9]

Всем спасибо Все прекрасно работает.


 
alex_***   (2004-01-14 11:16) [10]

[8] - Ты хочешь сказать что PChar(S) не даст адрес первого элемента строки?


 
PVOzerski   (2004-01-14 11:26) [11]

<[8] - Ты хочешь сказать что PChar(S) не даст адрес первого элемента строки?
Вот это-то и интересно. Я до сих пор думал так же. Но вот тестик.
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
begin
s:="Фигня";
Edit1.Text:=IntToHex(longint(pChar(s)),0)+" "+IntToHex(longint(@s[1]),0);
end;
И результат:
426BEC BF3430


 
[lamer]Barmaglot   (2004-01-14 11:27) [12]

Нет он конечно даст, но это будет указатель на структуру, то есть не на то место где у тебя хранится строка...


 
PVOzerski   (2004-01-14 11:29) [13]

Кажется, разобрался: это опять шутки оптимизатора.
В следующем примере адреса имели честь совпасть.
procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
begin
s:=Edit1.Text;
Edit1.Text:=IntToHex(longint(pChar(s)),0)+" "+IntToHex(longint(@s[1]),0);
end;
А разница в том, что в 1-м моем примере строковой переменной присваивалась константа, а во 2-м - не константа.


 
Андрей Сенченко   (2004-01-14 11:31) [14]

PVOzerski © (14.01.04 11:05) [7]

А почему не работает CharToOem(PChar(S), PChar(S)); - в самом деле, интересно...

Уже натыкался на это не раз. И даже здесь это обсуждали около месяца назад.
В итоге вот такая функция вроде как решает проблемы

Function WinToDos (stWin : string) : string;
var
stDOS : pchar;
begin
getmem(stDOS,1048);
CharToOem(pchar(stWIN),stDOS);
WinToDos := string(stDOS);
freemem(stDOS);
end;


 
alex_***   (2004-01-14 11:34) [15]

Оптимизатор must die - проблем больше чем пользы ))
[12] - сам себе противоречишь. Адрес первого эл-та - это адрес првого эл-та, а не адрес структуры описания.


 
[lamer]Barmaglot   (2004-01-14 11:39) [16]

Кто тебе сказал, что PChar возвращает указатель на первый элемент? Первый элемент в строке (s[0]) это насколько я помню длина строки...


 
alex_***   (2004-01-14 11:43) [17]

>Первый элемент в строке (s[0]) это насколько я помню длина строки... - для ShortString


 
BiN   (2004-01-14 11:44) [18]

lamer]Barmaglot © (14.01.04 11:39) [16]
...было раньше


 
alex_***   (2004-01-14 11:46) [19]

sorry... первый эл-т строки начинается с первой позиции s[1].
А s[0] - компилер будет ругаться.


 
[lamer]Barmaglot   (2004-01-14 11:54) [20]

для длинных строк тоже самое (может только в Delphi 6 изменили?). Для проверки запусти этот код...


procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
p: pInteger;
begin
s:="lamer";
p:=@s[1];
dec(p,1);
Edit1.text:=inttostr(p^);
end;


 
alex_***   (2004-01-14 12:09) [21]

ну и что.. . Первым элементом является s[1] и PChar(s) укажет на него.
попробуй
ShowMessage(String( PChar(s) ));


 
YuRock   (2004-01-14 12:51) [22]

> А почему не работает CharToOem(PChar(S), PChar(S)); - в самом деле, интересно...

Может потому, что S описано как const, т.е. менять его нельзя?


 
AKul   (2004-01-14 12:52) [23]

В типе String (в Delphi) индекс может изменяться от 1 и выше.
Элемент с индексом 0 не существует. Поэтому @S==@S[1]!;

Я тут провел маленькое исследование, если кому интересно:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
S: String;
begin
s:="получилось?";
CharToOem(PChar(S), PChar(S));
end;

не работает по следующей причине:
Как известно, строковые константы Delphi располагает в секции кода, которая обычно имеет флаг ReadOnly.
При компиляции строки s:="получилось?"; Delphi генерирует код вида @s:=@"получилось?", т.е. s указывает на участок памяти, расположенный в секции кода (не записываемый). При попытке записи по @s функцией CharToOEM и возникает ошибка.

При:
CharToOem(PChar(@S[1]), PChar(@S[1]));
компилятор передает указатель на динамически созданную копию строки S.


 
AKul   (2004-01-14 13:08) [24]

Да, забыл сказать, что исследование проводил на коде, сгенерированом Delphi 5. Может новые версии делают по другому (хотя наврядли).


 
PVOzerski   (2004-01-14 14:17) [25]

2AKul:
почти со всем согласен, кроме одного.
>При:
> CharToOem(PChar(@S[1]), PChar(@S[1]));
>компилятор передает указатель на динамически созданную копию строки S.

А вот не должно быть такого, поскольку здесь совершенно "тупой" typecast. Можно вообще написать CharToOem(@S[1],@S[1]);, и это будет работать. IMHO, здесь имеет место быть другое, а именно, по наличию адресного оператора на этапе компиляции определяется, что тело строки нельзя делать read-only. Или что-то подобное.


 
AKul   (2004-01-14 14:53) [26]

to PVOzerski © (14.01.04 14:17) [25]:
Согласен, что не должно быть такого, но то что я писал - это не предположение, а то что я "вытянул" из продизассемблированного кода.
При этом "тупом" преобразовании типа Delphi вызывает функцию UniqueString, в которой происходит вызов функции NewAnsiString. Полученный указатель и передается в функцию CharToOEM.
Если не веришь - проверь.


 
PVOzerski   (2004-01-14 15:37) [27]

>Если не веришь - проверь
Пожалуй, поверю: дизассемблировать лень :^) Однако всё это впечатляет. Самое удивительное, в таком разе, что при преобразовании pchar(string) аналогичных действий не производится.


 
VMcL   (2004-01-14 15:52) [28]

>>Zamik © (14.01.04 10:59) [6]
>есть вот такой код

>procedure TForm1.Button1Click(Sender: TObject);
>var
>S: String;
>begin
>s:="получилось?";
>CharToOem(PChar(S), PChar(S));
>end;
>
>при исполнении вот этой строки
>CharToOem(PChar(S), PChar(S));
>выдает
>Access violation at address 77D34CBD in module "user32.dll"
>Не знаю что и думать. Помогите мастера.

Надоело уже объяснять, может этот "прикол" в FAQ занести?
"s" указывает на конст. строку, а она, скорее всего, находится в области памяти с защитой от записи (что-то типа PAGE_READ).

Следует писать как-нибудь так:

function OemToAnsi(const S: String): String;
begin
SetLength(Result, Length(S));
CharToOem(PChar(S), PChar(Result));
end;


 
VMcL   (2004-01-14 15:53) [29]

Sorry, function AnsiToOem(const S: String): String;


 
AKul   (2004-01-14 16:03) [30]

to PVOzerski © (14.01.04 15:37) [27]:
при компиляции PChar(S) генерируется следующий код:
Вызывается процедура LStrToPChar, которая возвращает переданный ей указатель без изменений (@S), если он не равен нулю (nil). В случае nil возвращается указатель на пустую строку, расположенную также в секции кода.



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

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

Наверх





Память: 0.51 MB
Время: 0.005 c
6-83225
S@shka
2003-11-23 01:51
2004.01.26
POP3


1-83145
MakNik
2004-01-15 09:14
2004.01.26
Как вытянуть некоторые значения с формы, которая вызвала данную?


1-83176
GooD-NTS
2004-01-14 23:48
2004.01.26
Атрибуты файлов


9-83085
loto
2003-05-29 18:33
2004.01.26
(OpenGL) модули математических действий с матрицами


7-83293
Незнайка
2003-08-28 16:35
2004.01.26
Простейшая запись на DVD+RW. Приперло :(





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский