![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Перекодировка файла DOS в Win1251 [D6, WinXP]
galexis © (2004-08-09 17:23:00)Открываю файл как AssignFile(F, FileEdit.Text);
Reset(F);
while not eof(f) do
begin
Readln(F, S);
end;
файл ASCII, а надо win1251
И ведь знаю что легко и не раз делал, но замкнуло и все тут. И найти не могу. Помогите пожалуйста
Sandman25 (2004-08-10 09:11:00) [1][10] VMcL © (09.08.04 18:04)
[11] Мастер © (09.08.04 18:13)
Век живи - век учись.
Спасибо!
Anatoly Podgoretsky (2004-08-10 09:11:00) [2]Из всех предложеных вариантов, только вариант 2 от VMcL © (10.08.04 07:22) [34] будет безболезненый, остальные варианты страдают той или другой степень ошибок/проблем. Единственно, что надо сделать это только сменить имя функции, поскольку в Вин АПИ такое имя уже существует и могут быть из за этого проблемы.
VMcL (2004-08-10 07:22:00) [3]По сабджу.
function OEMToAnsi(const S: String): String;
begin
SetLength(Result, Length(S));
OEMToChar(PChar(S), PChar(Pointer(Result)));
end;
или
function OEMToAnsi(const S: String): String;
var
Len: Integer;
begin
Len := Length(S);
SetLength(Result, Len);
if Len > 0 then
OEMToChar(PChar(S), PChar(Result));
end;
Проблема заключается в том, что internal функция LStrToPChar при преобразовании пустой строки [PChar(Result)] возвращает не nil, а указатель на символ #0, который находится в области памяти с запретом на запись. Функция OEMToChar, видя что ей передали не nil пытается записать по адресу PChar(Result) ноль, чтобы "вернуть" пустую строку и, конечно, возникает AV.
Если строку преобразовывать с помошью Pointer(Result), то пустая строка преобразуется в nil и всё ОК.
Замечание. Исследование проводилось на D6.
P.S. Вот код LStrToPChar:
function _LStrToPChar(const s: AnsiString): PChar;
asm
TEST EAX, EAX
JE @@handle0
RET
@@zeroByte:
DB 0
@@handle0:
MOV EAX, offset @@zeroByte // !!!
end;
Proshka (2004-08-10 03:19:00) [4]а-а-а понял в
DosToWinнадо юзатьOemToChar
у вас опечатка а я тупо скопировал :)
Proshka (2004-08-10 01:30:00) [5]голяк :no: я путался по разному изголяться но у меня из строки
0 ЏђЋѓђЂЊЊЂ/ adem ;
получается только:
0 _________/ adem ;
а должно быть
0 ПРОГРАММА/ adem ;
вот
может есть какие идеи а
Alx2 (2004-08-09 20:29:00) [6]>Proshka (09.08.04 20:14)
Функицю перепиши по-другому:
Function DosToWin (Const stDOS : string) : string;
begin
Result := stDos;
if Result <>'' then CharToOem(PChar(Result),PChar(Result))
end;
Мастер (2004-08-09 20:20:00) [7]>Proshka (09.08.04 20:14) [29]
Не используй при вызове переменную класса.
Proshka (2004-08-09 20:14:00) [8]ребят я наверно протупил гдето, но у меня в этой строчке
"RichEdit2.Lines.Add (DosToWin(RichEdit1.Lines.Strings[i]))"
постоянно насилуют Аксеса. Обидно что изза меня хороший парень страдает. помогите пожалуста понять почему так.
Андрей Сенченко (2004-08-09 20:03:00) [9]Модераторам просьба - удалите мой вариант. ибо нефиг тут некорректному коду делать
Alx2 (2004-08-09 19:57:00) [10]>Андрей Сенченко © (09.08.04 19:54) [25]
Для строк - не определяет. Потому-что, например, неизвестно сколько ты в этот результат зальешь данных. В итоге ты передаешь функции API "битую ссылку". Эта функция считает, что ты позаботился о месте для размещения данных и заполняет их "не глядя". Нужно выполнить требование, чтобы Result имел длину не менее первого аргумента. Тут либо SetLength, либо еще чего наподобие :)
Андрей Сенченко (2004-08-09 19:57:00) [11]всё. ... извините, что ввел в заблуждение ... там функция в этом синтаксисе перекрыта была другой, объявленной напрямую в юните.
Действительно AV вышибает.
Андрей Сенченко (2004-08-09 19:54:00) [12]Мастер © (09.08.04 19:49) [22]
не память а адрес в памяти - так наверное ?
Alx2 © (09.08.04 19:50) [23]
странно что работает в этом случае ... то есть сам по себе запуск функции еще не определяет физического адреса для ее результата ?
Alx2 (2004-08-09 19:52:00) [13]>Андрей Сенченко © (09.08.04 19:47)
Я схватил AV на твоей реализации в примере: ShowMessage(WinToDos('Helo'));
Alx2 (2004-08-09 19:50:00) [14]>Андрей Сенченко © (09.08.04 19:47) [21]
Function DosToWin (stDOS : string) : string;
begin
if stDOS <>'' then CharToOem(PChar(stDos),PChar(Result)) // вот с этого места: Result здесь не проинициилизирован. Куда будет сыпаться содержимое stDos? Туда, куда указывает result. А указывать он пока может куда угодно.
else Result := '';
end;
Мастер (2004-08-09 19:49:00) [15]>Андрей Сенченко © (09.08.04 19:43) [19]
Function DosToWin (stDOS : string) : string;
begin
if stDOS <>'' then CharToOem(PChar(stDos),PChar(Result))
else Result := '';
end;
Под Result необходимо выделить память...
Андрей Сенченко (2004-08-09 19:47:00) [16]В итоге сразу AV поймаешь :)
Да вот что интересно то ... только что протестировал в реальной программе и не поймал ...
Входной файл имел вот такую вот структуру
REQUEST=SALE
ID=
CASHCODE=999
SHIFT=0
SCODE=9999
DATE= 9/08/2004
TIME=19:45
CHECKNUM=2
CARDNO=00100112882
CARDTYPE=SH
SUM1=30
SUM2=305
SUM=305
SUMTYPE=1
DISCTYPE=
DISCABS=0
DISCPERC=0
DOCNUM=
ERRORCODE=
MESSAGE=
CDEPT=1
VCODE=1
T=1,1,000001 ,"Товар в ассортименте ",1.000,30,30,30,1,0,1 ,0
T=2,10,000010 ,"Обои в ассортименте ",1.000,0,25,25,2,2,1 ,0
T=3,50,000050 ,"Смесители в ассортименте ",1.000,0,250,250,2,2,1 ,0
Перекодируются только строки, начинающиеся на T=
Alx2 (2004-08-09 19:46:00) [17]>Андрей Сенченко © (09.08.04 19:43) [19]
Твой последний вариант тоже не рабочий.
Андрей Сенченко (2004-08-09 19:43:00) [18]
// Иначе будет мусор
в последнем варианте его быть не должно по идее ... вот только если если по этому адресу была переменная большей длины - не знаю что произойдет.
Alx2 (2004-08-09 19:42:00) [19]>Андрей Сенченко © (09.08.04 19:41) [17]
Опять нет инициализации для result. В итоге сразу AV поймаешь :)
Андрей Сенченко (2004-08-09 19:41:00) [20]Вот так в итоге ...
Function DosToWin (stDOS : string) : string;
begin
if stDOS <>'' then CharToOem(PChar(stDos),PChar(Result))
else Result := '';
end;
Function WinToDos (stWin : string) : string;
begin
if stWin <>'' then CharToOem(PChar(stWin),PChar(Result))
else Result := '';
end;
а вот насколько это быстрее - не на чем оценить