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

Вниз

Перекодировка файла DOS в Win1251   Найти похожие ветки 

 
galexis ©   (2004-08-09 17:23) [0]

Открываю файл как AssignFile(F, FileEdit.Text);
                Reset(F);
                while not eof(f) do
                begin
                Readln(F, S);
                end;
файл ASCII, а надо win1251
И ведь знаю что легко и не раз делал, но замкнуло и все тут. И найти не могу. Помогите пожалуйста


 
Sandman25 ©   (2004-08-09 17:24) [1]

OemToChar


 
VMcL ©   (2004-08-09 17:25) [2]

>>galexis ©  (09.08.04 17:23)

OemToChar(), CharToOem().


 
galexis ©   (2004-08-09 17:36) [3]

Только не бейте,

а как строку S перекодировать?


 
VMcL ©   (2004-08-09 17:38) [4]

>>galexis ©  (09.08.04 17:36) [3]

Нет слов, одни выражения.
FAQ: http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988619604&n=19


 
Sandman25 ©   (2004-08-09 17:39) [5]

SetLength(S2, Length(S1));
OemToChar(PChar(S1), PChar(S2));


 
wnew ©   (2004-08-09 17:48) [6]

The OemToCharBuff function translates a specified number of characters in a string from the OEM-defined character set into either an ANSI or a wide-character string. (OEM stands for original equipment manufacturer.) This function supersedes the OemToAnsiBuff function.

BOOL OemToCharBuff(

   LPCSTR lpszSrc, // pointer to string to translate
   LPTSTR lpszDst, // pointer to buffer for translated string  
   DWORD cchDstLength  // size of buffer
  );


Parameters

lpszSrc

Points to a buffer containing one or more characters from the OEM-defined character set.

lpszDst

Points to the buffer for the translated string. If the OemToCharBuff function is being used as an ANSI function, the string can be translated in place by setting the lpszDst parameter to the same address as the lpszSrc parameter. This cannot be done if the OemToCharBuff function is being used as a wide-character function.

cchDstLength

Specifies the number of characters to translate in the buffer identified by the lpszSrc parameter.



Return Values

The return value is always nonzero.


 
Мастер ©   (2004-08-09 17:52) [7]


> VMcL ©   (09.08.04 17:38) [4]
> >>galexis ©  (09.08.04 17:36) [3]
>
> Нет слов, одни выражения.
> FAQ: http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988619604&n=19


В FAQ ошибка.
Правильно будет так:

function Win2Dos(const aStr: String): String;
begin
 Result := aStr;
 if Result="" then Exit;
 CharToOem(PChar(Result),PChar(Result));
end;

function Dos2Win(const aStr: String): String;
begin
 Result := aStr;
 if Result="" then Exit;
 OemToChar(PChar(Result),PChar(Result));
end;


 
galexis ©   (2004-08-09 17:55) [8]

Всем спасибо! Все получилось!


 
Sandman25 ©   (2004-08-09 17:55) [9]

[7] Мастер ©   (09.08.04 17:52)

Тогда уже так:

if Length(Result) = 0 then exit;

Все-таки быстрее, чем строки сравнивать


 
VMcL ©   (2004-08-09 18:04) [10]

>>Sandman25 ©  (09.08.04 17:55) [9]

Почти монопенисуально. Можешь посмотреть CPU Window.


 
Мастер ©   (2004-08-09 18:13) [11]

>Sandman25 ©   (09.08.04 17:55) [9]
>VMcL ©   (09.08.04 18:04) [10]

И даже медленнее за счет лишнего вызова LStrLen.


 
Андрей Сенченко ©   (2004-08-09 19:26) [12]

>> Мастер ©   (09.08.04 17:52) [7]

а если так ?

function Win2Dos(const aStr: String): String;
begin
 if aStr <>"" then CharToOem(PChar(Result),PChar(Result));
 else Result := aStr;

end;

function Dos2Win(const aStr: String): String;
begin
 if aStr <>""then OemToChar(PChar(Result),PChar(Result));
 else Result := aStr;
end;


 
Alx2 ©   (2004-08-09 19:32) [13]

>Андрей Сенченко ©   (09.08.04 19:26) [12]
Забыл Result := aStr вначале каждой функции. Тогда работать будет и "else" не нужен.


 
Андрей Сенченко ©   (2004-08-09 19:33) [14]

символы ; перед else наглядно демонстрируют, что самому было лень Delphi загружать :)


 
Андрей Сенченко ©   (2004-08-09 19:35) [15]

Alx2 ©   (09.08.04 19:32) [13]

Нет .. именно это и имелось в виду - сразу пойти на более часто встречающийся вариант ( то ес есть непустую строку ) и сэкомить тем самым время выполнения одной операции присвоения.


 
Alx2 ©   (2004-08-09 19:38) [16]

>Андрей Сенченко ©   (09.08.04 19:35) [15]
Я имел в виду следущее:
begin
 Result := aStr; // Инициализация для Result.
                         // Иначе будет  мусор
if aStr <>"" then CharToOem(PChar(Result),PChar(Result));
else Result := aStr; // тогда это не надо.


 
Андрей Сенченко ©   (2004-08-09 19:41) [17]

Вот так в итоге ...

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;


а вот насколько это быстрее - не на чем оценить


 
Alx2 ©   (2004-08-09 19:42) [18]

>Андрей Сенченко ©   (09.08.04 19:41) [17]
Опять нет инициализации для result. В итоге сразу AV поймаешь :)


 
Андрей Сенченко ©   (2004-08-09 19:43) [19]

// Иначе будет  мусор

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


 
Alx2 ©   (2004-08-09 19:46) [20]

>Андрей Сенченко ©   (09.08.04 19:43) [19]
Твой последний вариант тоже не рабочий.


 
Андрей Сенченко ©   (2004-08-09 19:47) [21]

В итоге сразу 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=


 
Мастер ©   (2004-08-09 19:49) [22]

>Андрей Сенченко ©   (09.08.04 19:43) [19]

Function DosToWin (stDOS : string) : string;
begin
if stDOS <>"" then CharToOem(PChar(stDos),PChar(Result))
else Result := "";
end;


Под Result необходимо выделить память...


 
Alx2 ©   (2004-08-09 19:50) [23]

>Андрей Сенченко ©   (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;


 
Alx2 ©   (2004-08-09 19:52) [24]

>Андрей Сенченко ©   (09.08.04 19:47)
Я схватил AV на твоей реализации в примере:  ShowMessage(WinToDos("Helo"));


 
Андрей Сенченко ©   (2004-08-09 19:54) [25]

Мастер ©   (09.08.04 19:49) [22]

не память а адрес в памяти - так наверное ?

Alx2 ©   (09.08.04 19:50) [23]

странно что работает в этом случае ... то есть сам по себе запуск функции еще не определяет физического адреса для ее результата ?


 
Андрей Сенченко ©   (2004-08-09 19:57) [26]

всё. ... извините, что ввел в заблуждение ... там функция в этом синтаксисе перекрыта была другой, объявленной напрямую в юните.
Действительно AV вышибает.


 
Alx2 ©   (2004-08-09 19:57) [27]

>Андрей Сенченко ©   (09.08.04 19:54) [25]
Для строк - не определяет. Потому-что, например, неизвестно сколько ты в этот результат зальешь данных. В итоге ты передаешь функции API "битую ссылку". Эта функция считает, что ты позаботился о месте для размещения данных и заполняет их "не глядя". Нужно выполнить требование, чтобы Result имел длину не менее первого аргумента. Тут либо SetLength, либо еще чего наподобие :)


 
Андрей Сенченко ©   (2004-08-09 20:03) [28]

Модераторам просьба - удалите мой вариант. ибо нефиг тут некорректному коду делать


 
Proshka   (2004-08-09 20:14) [29]

ребят я наверно протупил гдето, но у меня в этой строчке
"RichEdit2.Lines.Add (DosToWin(RichEdit1.Lines.Strings[i]))"
постоянно насилуют Аксеса. Обидно что изза меня хороший парень страдает. помогите пожалуста понять почему так.


 
Мастер ©   (2004-08-09 20:20) [30]

>Proshka   (09.08.04 20:14) [29]

Не используй при вызове переменную класса.


 
Alx2 ©   (2004-08-09 20:29) [31]

>Proshka   (09.08.04 20:14)
Функицю перепиши по-другому:

Function DosToWin (Const stDOS : string) : string;
begin
Result := stDos;
if Result <>"" then CharToOem(PChar(Result),PChar(Result))
end;


 
Proshka   (2004-08-10 01:30) [32]

голяк  :no: я путался по разному изголяться но у меня из строки
 0 ЏђЋѓђЂЊЊЂ/ adem    ;
получается только:
 0 _________/ adem    ;
а должно быть
 0 ПРОГРАММА/ adem    ;
вот
может есть какие идеи а


 
Proshka   (2004-08-10 03:19) [33]

а-а-а понял в
DosToWin надо юзать OemToChar
у вас опечатка а я тупо скопировал :)


 
VMcL ©   (2004-08-10 07:22) [34]

По сабджу.

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;


 
Anatoly Podgoretsky ©   (2004-08-10 09:11) [35]

Из всех предложеных вариантов, только вариант 2 от VMcL ©   (10.08.04 07:22) [34] будет безболезненый, остальные варианты страдают той или другой степень ошибок/проблем. Единственно, что надо сделать это только сменить имя функции, поскольку в Вин АПИ такое имя уже существует и могут быть из за этого проблемы.


 
Sandman25 ©   (2004-08-10 09:11) [36]

[10] VMcL ©   (09.08.04 18:04)
[11] Мастер ©   (09.08.04 18:13)

Век живи - век учись.
Спасибо!



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

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

Наверх





Память: 0.54 MB
Время: 0.037 c
1-1091171279
BRemB
2004-07-30 11:07
2004.08.22
Главное меню приложения


1-1092079629
k-sergey
2004-08-09 23:27
2004.08.22
как узнать запущен ли поток?


14-1091614672
Strumpf
2004-08-04 14:17
2004.08.22
Как приятно


3-1090962072
AlexG
2004-07-28 01:01
2004.08.22
Создание зависимых списков


3-1091186906
Pioneer
2004-07-30 15:28
2004.08.22
Компьютер виснет на большом отчете





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