PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Расскажите про ковыряние в памяти UTF8


Расскажите про ковыряние в памяти UTF8

Сообщений 1 страница 5 из 5

1

я чего-то не понимаю, может, кто-то объяснит , что я делаю не так.
Вообщем, есть файлв формате UTF8, пусть его содержимое будет таким

содержимое файла utf8.txt

001p02.Yяя]
Это просто текст!

Я его успешно считываю и загоняю в память. а потом оттуда пытаюсь посимвольно извлечь буковки и нифига у меня это не получается. Вообще никак. Почему?

Код:
Filename$="c:\utf8.txt" ; если файл разместить на диске С , то для 10 винды нужно поставить галочку в свойствах компилятора Администраторский режим
LengthFile.q = FileSize(Filename$)
*UTF8=AllocateMemory(LengthFile):
If OpenFile(0, Filename$)
ReadData(0, *UTF8, LengthFile)
CloseFile(0)  ; файл в памяти
ShowMemoryViewer(*UTF8, LengthFile) ; здесь все видно, если выбрать смотреть в UTF8
 i=3 ;первые 3 байта это указатель на UTF8, начинаем читать с 4-го байта, UTF8 имеет либо 1 байт на символ, либо 2
   While i<LengthFile ;LengthFile ; найдем перевод каретки
      ;c$=PeekS(*UTF8+i,1, #PB_UTF8) ; все равно фигня получается
      symbol.c=PeekC(*UTF8+i)  
       Debug "i="+Str(i)+"  "+Str(symbol) +"  "+"символ="+Chr(symbol) ; не то, как получить реальные символы?
     i+2 ; как понять, сколько байт брать для символа в UTF8?
   Wend
 Else 
   Debug "Не открывается файл, вероятно, нужен установить администраторский режим."
 EndIf   
   FreeMemory(*UTF8)

Отредактировано Goga (12.12.2021 15:15:34)

0

2

https://ru.wikipedia.org/wiki/UTF-8

UTF-8 (от англ. Unicode Transformation Format, 8-bit — «формат преобразования Юникода, 8-бит») — распространённый стандарт кодирования символов, позволяющий более компактно хранить и передавать символы Юникода, используя переменное количество байт (от 1 до 4)

Перекодируйте текст в ascii или юникод (UTF-16) и будет проще разделять текст на символы.

0

3

Петр, подскажите пожалуйста, как это сделать? Есть какая-то функция или что-то надо писать отдельно? (сорри. этот вопрос пока не изучал)

0

4

справка раздел строки, там есть
но можно нарваться, в utf8 есть символы которых нет в  ascii
незнаю как тут сделана перекодировка, редактор акелла предупреждает при перекодировке
о каждом таком символе

изврат конечно, но работает
если есть пустые строки то не очень понятно что дебуг показывает, думать надо как это игнорить, как отлавливать 0D0A

Код:
   
*buf=AllocateMemory(8)
   c$=PeekS(*UTF8+i,1, #PB_UTF8) ; все равно фигня получается
;Debug c$     
*buf=PokeS(*utf8, c$, 1, #PB_UTF8)
Debug c$+" "+*buf
;symbol.c=PeekC(*UTF8+i)  
      ; Debug "i="+Str(i)+"  "+Str(symbol) +"  "+"символ="+Chr(symbol) ; не то, как получить реальные символы?
     i+*buf ; как понять, сколько байт брать для символа в UTF8?
   Wend

чисто из любопытства, а какие символы кодируются 3-4 байта, русские двумя

0

5

Что то раньше делал может поможет?
Сейчас пока некогда разбираться.

Код:
Procedure.s UTF16_TO_UTF8(s.s);
  If s=""
    ProcedureReturn #NULL$
  EndIf
  Protected u.s=LSet(s,Len(s)*2,"")
 PokeS(@u,s,-1,#PB_UTF8)
 ProcedureReturn u
EndProcedure
Procedure.s UTF16_UTF8(stroka.s,a.a);
  ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  ;создать буфер для приёма 
  If a=3
    stroka=LSet(stroka,Len(stroka),"")
  ElseIf a=4 
    stroka=LSet(stroka,Len(stroka),"")
  EndIf
  ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  !push eax
  !push ebx
  !push esi
  !push edi
  ;
  !mov dword esi,[p.v_stroka+16]
  !mov dword edi,[p.v_stroka+16]
  !rr:
  !CMP word[esi],0h
  !je ddd
  !cmp word[esi],127
  !Ja gyh
  !
  !mov byte al,[esi]
  !mov byte[edi],al
  !add esi,2
  !add edi,1
  !jmp rr
  !gyh:
  !cmp word[esi],2047;до 10000h 3-х байтный utf-8
  !Ja sdd
  !mov word ax,[esi]
  !mov word bx,ax
  !shr ax,6;cdvig na 6 v pravo
  !or byte al,192;C0h
  ;==========;типа обнулить 6-7 бит
  ;!shl bl,2
  ;!shr bl,2
  ;===========================
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !mov byte ah,bl
  !mov word[edi],ax
  !add esi,2
  !add edi,2
  !jmp rr
  
  !sdd:
  !cmp dword[esi],65535;10000h это уже 4-х байтный utf-8
  !Ja sddf
  !
  ;
  !;3-х байтный utf-8 символ с число юникода >2047
  !mov word ax,[esi]
  !mov word bx,ax
  !
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !mov word[edi+2],bx
  ;
  !mov word bx,ax
  !shr ax,12
  !or byte al,224
  ;
  !shr bx,6
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  !mov byte ah,bl
  ;
  !mov word[edi],ax
  !add esi,2
  !add edi,3
  !jmp rr
  ;
  !sddf:
  ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  ;4-х байтный utf-8 символ с числом юникода от 10000h до 200000h(2097152)
  !mov byte bl,[esi]
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !mov byte[edi+3],bl
  !mov word bx,[esi]
  !shr bx,6
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !mov byte[edi+2],bl
  ;
  !mov dword ebx,[esi]
  !shr ebx,12
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !mov dword eax,[esi]
  !shr eax,18
  !or byte al,240;f0h
  !mov byte ah,bl;2-й байт
  !mov word[edi],ax
  !add esi,2
  !add edi,4
  !jmp rr
  ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  !ddd:
  !mov byte[edi],0h
  ;
  !pop edi
  !pop esi
  !pop ebx
  !pop eax
  ;
  ProcedureReturn stroka
EndProcedure
Procedure$ CHR_UTF8(Nomer.i);
  Protected stroka.s=#NULL$
  stroka=LSet(stroka,2,"")
  ;
  !push eax
  !push ebx
  !push edi
  ;
  !mov dword eax,[p.v_Nomer+12]
  !mov dword edi,[p.v_stroka+12]
  ;
  !CMP dword eax,0h
  !je dddw
  !cmp dword eax,127
  !Ja gyhw
  !
  ;//////////////////////////
  ;до (127),1 байтный utf-8
  !mov byte[edi],al
  !jmp dddw
  ;/////////////////////////
  !gyhw:
  !cmp dword eax,2047;от 800h до 10000h 3-х байтный utf-8
  !Ja sddw
  ;
  ;//////////////////////////////////
  ;от 127 до 800h 2-х байтный utf-8
  !mov byte bl,al
  ;===типа обнулить 6-7 бит
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;===========================
  !shr ax,6
  !or byte al,192;C0h 
  ;==========;
  !mov byte ah,bl
  !mov word[edi],ax
  !jmp dddw
  ;////////////////////////////////
  !sddw:
  !cmp dword eax,65535;>10000h это уже 4-х байтный utf-8
  !Ja sddfw
  !
  ;//////////////////////////////////////////////////////
  ;3-х байтный utf-8 символ с числом юникода от 800h до 10000h
  !mov byte bl,al
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !mov byte[edi+2],bl
  ;
  !mov word bx,ax
  !shr bx,6
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !shr ax,12
  !or byte al,224
  ;
  !mov byte ah,bl;2-й байт
  !mov word[edi],ax
  !jmp dddw
  ;
  !sddfw:
  ;//////////////////////////////////////////
  ;4-х байтный utf-8 символ с числом юникода от 10000h до 200000h(2097152)
  !mov byte bl,al
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !mov byte[edi+3],bl
  !mov word bx,ax
  !shr bx,6
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  !mov byte[edi+2],bl
  ;
  !mov dword ebx,eax
  !shr ebx,12
  ;!shl bl,2
  ;!shr bl,2
  ;!add byte bl,128;80h поставить 7 бит
  !And byte bl,63;обнулить 5 начальных битов
  !or byte bl,128;поставить 7 бит
  ;
  !shr eax,18
  !or byte al,240;f0h
  !mov byte ah,bl;2-й байт
  !mov word[edi],ax
  ;////////////////////////////////
  !dddw:
  !pop edi
  !pop ebx
  !pop eax
  ;
  ProcedureReturn stroka
EndProcedure
Procedure.i UTF8_MAXBAIT(*s);НОРМ
  !push eax
  !push esi
  !mov esi,[p.p_s+8]
  !xor eax,eax
  !uu:
  !cmp byte[esi],0h
  !jz ecssit
  !cmp byte[esi],127
  !ja gg
  !cmp eax,1
  !ja yy
  !mov eax,1
  !yy:
  !add esi,1
  ;Debug 1
  !jmp uu
  ;
  !gg:
  !cmp byte[esi],223
  !ja hh 
  ;2
  !cmp eax,2
  !ja kk
  !mov eax,2
  !kk:
  !add esi,2
  ;Debug 2
  !jmp uu
  !
  ;
  !hh:;>3
  !cmp byte[esi],239
  !ja ddh
  ;3
  !cmp eax,3
  !ja kw
  !mov eax,3
  !kw:
  !add esi,3
  ;Debug 3
  !jmp uu
  ;
  !ddh:
  !cmp byte[esi],247
  !ja ffm
  ;4
  !cmp eax,4
  !ja kr
  !mov eax,4
  !kr:
  !add esi,4
  ;Debug 4
  !jmp uu
  ;
  !ffm:
  !cmp byte[esi],251
  !ja ffd
  ;5
  !cmp eax,5
  !ja krt
  !mov eax,5
  !krt:
  !add esi,5
  ;Debug 5
  !jmp uu
  ;
  !ffd:
  !cmp byte[esi],253
  !ja ffdt
  ;6
  !cmp eax,6
  !ja krtt
  !mov eax,6
  !krtt:
  !add esi,6
  !jmp uu
  ;
  !ffdt:
  !cmp byte[esi],254
  !ja ffdtr
  ;7
  !cmp eax,7
  !ja krttr
  !mov eax,7
  !krttr:
  !add esi,7
  !jmp uu
  ;
  !ffdtr:
  ;8
  !cmp eax,8
  !ja krttrg
  !mov eax,8
  !krttrg:
  !add esi,8
  !jmp uu
  ;
  !ecssit:
  !pop esi
  !pop eax
  ;
  ProcedureReturn
EndProcedure

Эту процедуру UTF8_MAXBAIT переделать есле без цикла на все байты строки то можно выпрагнуть с количеством байт на символ.

Отредактировано Sergeihik (26.12.2021 17:56:43)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Расскажите про ковыряние в памяти UTF8