Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

UTF-8 [D7, XP]


ford ©   (2009-11-27 13:27:00) 

Здравствуйте!
как на дельфи автоматически определить, что текст в кодировке UTF-8 ?
в инете нашел что есть такая славная функция
как function DetectUTF8Encoding(const s : UTF8String): TEncodeType;
в модуле WideStrUtils.pas

но в своем Delphi 7
я такого модуля не нашел :(


Евгений471   (2009-12-14 17:24:00) [1]


> лень писать $80 вместо StrToInt64('0x80') ?

яж указал, как есть в исходном - так и написал, кого не устроит вариант - поправить недолго.


clickmaker   (2009-12-14 15:20:00) [2]

лень писать $80 вместо StrToInt64('0x80') ?


Евгений471   (2009-12-14 14:57:00) [3]


> > (b and StrToInt64('0xc0')) = StrToInt64('0x80')что это?
> ?

> StrToInt64('0x80')
числа в 16-ти ричной системе - коды символов.
просто перевел код с C  на pascal без изминений, лень было писать коды символов в оригенальном значении.

вот этот код:

BOOL IsUTF8(LPBYTE pbBuff, LONG cb)
{
BOOL fASCII;
int i, nb, curr;
BYTE b;

BOOL result = FALSE;
if (cb == 0) return result;

fASCII = TRUE;
curr = 0;
while (curr < cb)
{
nb = 0;
b = pbBuff[curr];
if ((b & 0x80) != 0)
{
 fASCII = FALSE;
 if ((b & 0xc0) == 0x80) return result;
 else if ((b & 0xe0) == 0xc0) nb = 1;
 else if ((b & 0xf0) == 0xe0) nb = 2;
 else if ((b & 0xf8) == 0xf0) nb = 3;
 else if ((b & 0xfc) == 0xf8) nb = 4;
 else if ((b & 0xfe) == 0xfc) nb = 5;
 else return result;

 if (curr + nb >= cb) return result;

 for (i = 1; i


clickmaker   (2009-12-14 11:43:00) [4]

> (b and StrToInt64('0xc0')) = StrToInt64('0x80')

что это??


Евгений471   (2009-12-14 11:37:00) [5]


> while (curr < cb) {  nb = 0;  b = pbBuff[curr];  if ((b
> & 0x80) != 0)  {   fASCII = FALSE;   if ((b & 0xc0) == 0x80)
> return result;   else if ((b & 0xe0) == 0xc0) nb = 1;   else
> if ((b & 0xf0) == 0xe0) nb = 2;   else if ((b & 0xf8) ==
> 0xf0) nb = 3;   else if ((b & 0xfc) == 0xf8) nb = 4;   else
> if ((b & 0xfe) == 0xfc) nb = 5;   else return result;   if
> (curr + nb >= cb) return result;   for (i = 1; i i++)   {    if ((pbBuff[i + curr] & 0xC0) != 0x80) return
> result;   }  }  curr += nb + 1; } result = !fASCII;


на pascal

function TEncodeClass.FromString(const index: integer;
 const s: string): char;
begin
if (index length(s)) then
begin
 Result := #0;
 exit;
end;
Result := s[index];
end;

function TEncodeClass.IsUtf8(const s: string; const cb:cardinal): boolean;
var
 fASCII:boolean;
 i, nb, curr:integer;
 b:byte;
begin
Result := false;
if cb= cb then exit;
  for i := 1 to nb do
  if (ord(FromString(i+curr,s)) and StrToInt64('0xC0')) StrToInt64('0x80') then exit;
 end;
 inc(curr,nb+1);
end;
Result := not fASCII;
end;


Омлет   (2009-11-30 18:20:00) [6]

> [7] ford ©   (27.11.09 16:04)
> для больших текстов не подходит но для маленьких вполне

Бери маленький кусок большого текста.


ford   (2009-11-27 16:04:00) [7]


> Решение в лоб.

прикольное решение
для больших текстов не подходит но для маленьких вполне :)


> clickmaker ©   (27.11.09 14:31) [6]


спасибо, теперь понятно что там делается :)


clickmaker   (2009-11-27 14:31:00) [8]

> [4] ford ©   (27.11.09 14:10)
> а пояснить логику можно??

логика там несложная.
в утф-8 каждый символ может занимать от 1 до 6 байт. Если значение байта лежит за пределами кодировки ascii ((b & 0x80) != 0), то проверяем значение на совпадение с некими масками, которые с достаточной долей вероятности говорят о том, что это утф.
При этом в каждом байте также установлены биты, которые говорят, что этот байт не является последним (nb = 1...nb = 5).


Медвежонок Пятачок   (2009-11-27 14:17:00) [9]

Решение в лоб.

var s : string;
begin
s := 'мама мыла раму';
//s := AnsiToUtf8(s);
if AnsiToUtf8(Utf8ToAnsi(s)) <> s then ShowMessage('Либо не в утф, либо нет не-анси символов')


ford   (2009-11-27 14:10:00) [10]

а пояснить логику можно??


clickmaker   (2009-11-27 13:49:00) [11]

на паскаль сам переводи

BOOL IsUTF8(LPBYTE pbBuff, LONG cb)
{
BOOL fASCII;
int i, nb, curr;
BYTE b;

BOOL result = FALSE;
if (cb == 0) return result;

fASCII = TRUE;
curr = 0;
while (curr < cb)
{
 nb = 0;
 b = pbBuff[curr];
 if ((b & 0x80) != 0)
 {
  fASCII = FALSE;
  if ((b & 0xc0) == 0x80) return result;
  else if ((b & 0xe0) == 0xc0) nb = 1;
  else if ((b & 0xf0) == 0xe0) nb = 2;
  else if ((b & 0xf8) == 0xf0) nb = 3;
  else if ((b & 0xfc) == 0xf8) nb = 4;
  else if ((b & 0xfe) == 0xfc) nb = 5;
  else return result;

  if (curr + nb >= cb) return result;

  for (i = 1; i


ford   (2009-11-27 13:47:00) [12]

ну почему никак ....
я вот написал такую функцию
Function UTF8Check(src:TStrings):Boolean;
var i,j,RCount,ACount:Integer;
   s:String;
Begin
RCount:=0; ACount:=0;
for i:=0 to src.Count-1 do
 Begin
  s:=src[i];
  for j:=1 to Length(s) do
   Begin
    Inc(ACount);
    if (Ord(s[j])>=192) and (Ord(s[j])<=255) Then Inc(RCount);
   End;
 end;
if ((rCount*100)/acount)<20 Then result:=true
Else result:=false;
End;


в принципе определяется что там UTF8
хотя конечно это не 100%
но работает

а вот подскажите, я поставил менее 20% должны встречаться русские букавки :) честно, поставил от балды, может кто подскажет какой процент наличия русских букв относительно всего текста может с более менее нормальной долей вероятности сказать что этот текст в utf8 ?
понятно что моя функция на тексте
"privet vasya" выдаст что это UTF8 :( может что то еще нужно проверять не просто что это английские буквы а еще и что много "P" и "?" ?


Игорь Шевченко   (2009-11-27 13:36:00) [13]


> как на дельфи автоматически определить, что текст в кодировке
> UTF-8


никак


Наверх

Титульная страница Поиск, карта сайта Написать письмо