Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.11.20;
Скачать: CL | DM;

Вниз

txt фаил в unicode кодировке!!! Как правильно считать ???   Найти похожие ветки 

 
Dankin   (2005-10-20 03:04) [0]

Есть вот такая проблема. Есть текстовый фаил в unicode rjlbhjdrt (написан и сохранен как unicode в блокноте). Предположем там есть французкие или немецкие национальные буквы )))
Тык вот в чем вопрос, как считат из этого файла все строки правильно, если считываю простым ридом то скажем вместо строки "test" получаю "юя", не говоря уже об более экзотических символах... Хотя разумеется в ANSI все было впорядке. Переделывать текст в базу, нет ни времени ни целесообразности, а очень надо считывать юникод текст и показать его (с сохранением всех символов) в, скажем Label. Сам Label понимающий уникод вроде как нашол...
Помогите плиз, ну оооочччееенннь надо! Заранее огромное спасибо! )))


 
Джо ©   (2005-10-20 03:14) [1]

См. раздел стандартной справки Character set conversions и обратите внимание на функции WideCharToString и прочие похожие.


 
Dankin   (2005-10-20 03:24) [2]

Как раз сейчас это делаю. Чего то не получается. Во первых вопрос номер раз, в какую переменную (какой тип) нужно ридить строку из файла, в string или widestring. И если в widestring, to как ее вести дальше??? 8-\


 
Джо ©   (2005-10-20 03:29) [3]


> to как ее вести дальше??? 8-\

Это как перевести на русский?


 
Dankin   (2005-10-20 03:40) [4]

Ну в смысле, чего с ней дальше сделать чтоб все получилось )))

вот такой тестовый кусочек (если его конечно можно так назвать), при выполнении приводит прогу к ошибке!!!

var
 Form1: TForm1;
 f:text;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
s:pwidechar;
ss:string;
begin
assignfile(f,"test.txt");
reset(f);
read(f,ss);
stringtowidechar(ss,s,10);
closefile(f);
ss:=wideCharToString(s);
showmessage(ss);
end;

Причем ошибка вылетает как при выполнении Showmessage, так и при попытке пихнуть строку в TNTLABEL!
Ну и соответственно ошибка гласит:
Project raised exception class EAccessViolation with message ""Access violetion at address 0041DDA7 in module ..." Read of address 044F045E... ну и т.д. !!!
Чегойто я непонимаю чего я изначально не так делаю???!


 
Джо ©   (2005-10-20 03:45) [5]

Совершенно естественно, что вылетает ошибка. PWideChar - это просто указатель на область памяти. А памяти-то ты под нее и не выделил.

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


 
Dankin   (2005-10-20 03:49) [6]

Так, при замене
stringtowidechar(ss,s,10);
на
stringtowidechar(ss,s,1);
showmessage стал выдавать ?B??, и это при том что
в файле просто надпись test!!! Да и глупо получается, сначала
считывать строку потом кидать ее в pwidechar а потом обратно
в строку!!! Значит нужно изначально читать как pwidechar!
Но тогда при компиляции выдается Illegal type in Read/Readln statement.
И на этом все останавливается, так как же правильно делать?!!!
Хелп плиз...


 
Набережных С. ©   (2005-10-20 08:47) [7]

Схема примерно такая:

function ReadWideCharFile(const FileName: string): WideString;
var
 FS: TFileStream;
 Sz: integer;
begin
 FS:=TFileStream.Create(FileName, fmOpenRead);
 try
   Sz:=FS.Size;
   if Sz > 0 then
   begin
     SetLength(Result, Sz shr 1);
     FS.ReadBuffer(Result[1], Sz);
   end;
 finally
   FS.Free;
 end;
end;

Но такая реализация может быть неоптимальной при больших размерах файла.


 
jack128 ©   (2005-10-20 10:35) [8]

Набережных С. ©   (20.10.05 8:47) [7]
var
FS: TFileStream;
Sz: integer;
begin
FS:=TFileStream.Create(FileName, fmOpenRead);
try
  Sz:=FS.Size - 2;
  if Sz > 0 then
  begin
    SetLength(Result, Sz shr 1);
    FS.Seek(2, 0); // первые два байта в юникодовском файле долны быть #$FF#$FE
    FS.ReadBuffer(Result[1], Sz);
  end;
finally
  FS.Free;
end;
end;


 
Игорь Шевченко ©   (2005-10-20 11:03) [9]


> первые два байта в юникодовском файле долны быть #$FF#$FE


Не обязательно


 
Dankin   (2005-10-20 11:40) [10]

Угу, сейчас буду пробовать, спасибо огромное. Я так понимаю содержимое файла целиком забивается в буфер, или нет???
А как при такой схеме скажем перекидать все строки файла в memo или listbox?! разуемеется адаптированный к unicode т.е. tnt )))


 
Dankin   (2005-10-20 15:42) [11]

Да, этот код безуловно работает!А как же сделать чтение всех строк, т.е. к примеру вывод строк в memo?


 
Набережных С. ©   (2005-10-20 16:52) [12]


> Dankin   (20.10.05 15:42) [11]

Memo.lines.text:=ReadWideCharFile(...)


 
KorvinOE ©   (2005-11-03 12:35) [13]


> Набережных С. ©   (20.10.05 16:52) [12]

Это не поможет, т.к. unicode может включать в себя символы конца строки. И эти символы могут распологаться в любом месте строки, а в Мемо.Тхт записуется только до первого такого символа. Надо unicode преобразовать в Ansi. Как же это сделать?


 
Набережных С. ©   (2005-11-03 16:57) [14]


> KorvinOE ©   (03.11.05 12:35) [13]
>
Если имеется в виду символы разделения строк(#13, #10#13), то Memo.Lines.Text их прекрасно обработает и разобьет по ним на строки.
Если подразумевается символ #0, то нормальный текстовый файл не должен их содержать. Но если все же есть то придется искать поработать руками...короче, проще показать:

var
 s: string;
 SL: TStrings;
 i: integer;
begin
 s:=ReadWideCharFile(...);
 Memo1.Lines.Clear;

 if s = "" then Exit;

 SL:=TStringList.Create;
 try

   i:=0;
   repeat
     Inc(i);
     SL.Text:=PChar(@s[i]);
     Memo1.Lines.AddStrings(SL);
     i:=PosEx(#0, s, i);
   until i = 0;

 finally
   SL.Free;
 end;
end;



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

Текущий архив: 2005.11.20;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.06 c
9-1120370383
Tratata
2005-07-03 09:59
2005.11.20
Книга по 3Д


2-1131210089
Starcom
2005-11-05 20:01
2005.11.20
Ропрос про чтение записи из сист. реестра?


14-1130122249
Troyan.DownLoader
2005-10-24 06:50
2005.11.20
Хацкер я или не хацкер !!!


2-1130924775
Cvin
2005-11-02 12:46
2005.11.20
Минимизировать форму на панель задач


2-1130855393
KorvinOE
2005-11-01 17:29
2005.11.20
WideString -> String