![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() помогите с такой задачей. есть юникод файл (UCS-2 Little Endian),с длинной символа 4 байта. нужно перекодировать в анси чтоб загрузить его в мемо,поредактировать и соханить обратно в юникод.
к сожалению в инете нашел только пример для двухбайтных,а мне 4 нужно. в архиве такая программа,с двухбайтной длинной.и два файла один который мне нужен (имя 4.тхт) и второй который прогамма делает (2.тхт). может кто сможет что переделать? или подскажет как что |
#2
|
||||
|
||||
![]() Дай текст в UCS2 (4-байта).
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#3
|
|||
|
|||
![]() Цитата:
|
#4
|
||||
|
||||
![]() Там обычная UTF16LE строка (2-х байтовая). Кодируется стандартно. Вот в 2.txt строка не самая стандартная - без заголовка.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 11.08.2011 в 23:50. |
#5
|
||||
|
||||
![]() Я пользовался этим:
Код:
unit convert; interface const UTF16BE = $FFFE; UTF16LE = $FEFF; function DetectUTF16LEBOM(const P: PChar; const Size: Integer): Boolean; function DetectUTF16BEBOM(const P: PChar; const Size: Integer): Boolean; function UTF16ToUTF8(const S : WideString; Count : Integer; var utf : Boolean; Swap : Boolean = False) : AnsiString; implementation //---------------------------------------------------------- type UCS2 = Word; UCS4 = Cardinal; const MaximumUCS4 : UCS4 = $7FFFFFFF; ReplacementCharacter : UCS4 = $0000FFFD; function DetectUTF16LEBOM(const P: PChar; const Size: Integer): Boolean; begin Result := Assigned(P) and (Size >= Sizeof(WideChar)) and (PWideChar(P)^ = WideChar(UTF16LE)); end; function DetectUTF16BEBOM(const P: PChar; const Size: Integer): Boolean; begin Result := Assigned(P) and (Size >= Sizeof(WideChar)) and (PWideChar(P)^ = WideChar(UTF16BE)); end; function SwapUTF16Endian(const P : Cardinal) : Cardinal; begin Result := ((Ord(P) and $FF) shl 8) or (Ord(P) shr 8); end; function ConvertSurrogate(S1, S2 : UCS2) : UCS4; // Converts a pair of high and low surrogate into the corresponding UCS4 character. const SurrogateOffset = ($D800 shl 10) + $DC00 - $10000; begin Result := Word(S1) shl 10 + Word(S2) - SurrogateOffset; end; function UTF16ToUTF8(const S : WideString; Count : Integer; var utf : Boolean; Swap : Boolean = False) : AnsiString; // Converts the given Unicode text (which may contain surrogates) into // the UTF-8 encoding used for the HTML clipboard format. const FirstByteMark: array[0..6] of Byte = ($00, $00, $C0, $E0, $F0, $F8, $FC); var Ch : UCS4; I, J, T : Integer; BytesToWrite : Cardinal; begin Result := ''; utf := True; if (Count = 0) then Exit; begin // Make room for the result. Assume worst case, there are only short texts to convert. SetLength(Result, 6 * Count); T := 1; I := 1; BytesToWrite := 0; while I <= Count do begin Ch := UCS4(S[i]); if Swap then // for UTF16BE Ch := SwapUTF16Endian(Ch); if (Hi(Ch) = 0) and (Lo(Ch) >= $C0) then // for wild (mad) record with codepage cp1251 begin BytesToWrite := 1; Result[T] := AnsiChar(Lo(Ch)); inc(T, BytesToWrite); inc(I); utf := False; Continue; end else begin if (Ch and $FFFFF800) = $D800 then // Is the character a surrogate? begin inc(I); // Check the following char whether it forms a valid surrogate pair with the first character. if (I <= Count) and ((UCS4(S[i]) and $FFFFFC00) = $DC00) then Ch := ConvertSurrogate(UCS2(Ch), UCS2(S[i])) else // Skip invalid surrogate value. Continue; end; if Ch < $80 then BytesToWrite := 1 else if Ch < $800 then BytesToWrite := 2 else if Ch < $10000 then BytesToWrite := 3 else if Ch < $200000 then BytesToWrite := 4 else if Ch < $4000000 then BytesToWrite := 5 else if Ch <= MaximumUCS4 then BytesToWrite := 6 else begin BytesToWrite := 2; Ch := ReplacementCharacter; end; end; for J := BytesToWrite downto 2 do begin Result[T + J - 1] := AnsiChar((Ch or $80) and $BF); Ch := Ch shr 6; end; Result[T] := AnsiChar(Ch or FirstByteMark[BytesToWrite]); inc(T, BytesToWrite); inc(I); end; SetLength(Result, T - 1); // set to actual length end; end; end. Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#6
|
|||
|
|||
![]() Цитата:
А вот этот файл, |
#7
|
||||
|
||||
![]() То же самое, UTF16LE строка (2-х байтовая).
В 2.txt unicode, но встречается такой формат гораздо реже. Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 12.08.2011 в 00:15. |
#8
|
||||
|
||||
![]() Snake22, как я понял, ваша программа нормально считывает файл 2.txt, но "глючит" с файлом 4.txt, и поэтому вы решили спросить совета тут? Все дело в том, что в файле 2.txt нет сигнатуры (или как там она называется), а в 4.txt - она есть, а считывание информации из файла идет с 0, другими словами, при считывании инфы из 2 в строку идет юникодовый текст (с ним проблем нет), а вот из 4 - сигнатура и только после нее текст (а вот тут и возникает проблема). Вам нужно перед WideCharLenToString убрать из начала строки сигнатуру, если она есть.
А тов. angvelem правильно сказал, оба текста в кодировке UTF16LE, только один без сигнатуры. Кстати, для сохранения юникодовой информации в файл сначала нужно записать сигнатуру, а потом текст. Поверьте, так будет лучше для всех.) По аналогии с вашей программой: Код:
var s: string; ... s:= #FF#FE; BlockWrite(f, PChar(s)^, 2); И еще заметил: Код:
BlockWrite(f, PWideChar(WStr)^, Length(WStr)); Начинающий программист уверен, что в 1 килобайте 1000 байт.
Законченный программист уверен, что в 1 километре 1024 метра. Последний раз редактировалось Karsh, 12.08.2011 в 01:06. |
#9
|
|||
|
|||
![]() Ладно,может будет сохранять в нужном формате.подскажите как это реализовать?
Я так понял представленный юнит конвертирует в ютф8? А чтоб сохранить,обратно в юникод как? (извиняюсь если где туплю,не оч разбираюсь) |
#10
|
||||
|
||||
![]() Вот тебе архив со всем подряд на эту тему, ковыряй.
unicode Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 12.08.2011 в 01:22. Причина: Не загромождать форум архивами |
#11
|
||||
|
||||
![]() Цитата:
Цитата:
Код:
BlockWrite(f, PWideChar(WStr)^, Length(WStr)); Цитата:
Начинающий программист уверен, что в 1 килобайте 1000 байт.
Законченный программист уверен, что в 1 километре 1024 метра. Последний раз редактировалось Karsh, 12.08.2011 в 01:17. |
#12
|
|||
|
|||
![]() Цитата:
![]() s:= #FF#FE; BlockWrite(f, PChar(s)^, 2); мой дельфи не понял что такое #FF#FE ,пришлось числами писать, и еще где цифра 2, заменил ее на 1,а то перед текстом пробел появлялся.теперь всё норм ![]() |
#13
|
||||
|
||||
![]() Цитата:
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |