Keresés
Hírlevél
 
Kiemelt témák
»Hogy viszonyul ehhez a család?
»Legjobb metodika emberi relációk tárolására
»A programozó hibája, hogy törik a programját?
»Jogosultság kezelés mezőszinten
Állás/munka
»Wordpress szakértőt keresünk
»Kamu álláshirdetők listája
»Front-end fejlesztő / Sitebuilder
»DataStore Developer
»PHP programozó, webfejlesztő munkát keres
» több téma
Tudástár
?HTML-ben a Flash átméretezés torzul
Eredeti mezőnevek lekérdezése
?Input mezőből visszakapott adat probléma
Oldalon keresés 8x írja ki az eredményt
?XML-ből sok szövegmező
TinyMCE és az ékezetek
?Rengeteg hasonló kép betöltése gyorsan (PHP)
Ékezetes kar. nem minden táblában jól
?Shelltreeview gond
Grafikon rajzolás probléma
?Onclick= php függvény
?Egyenes megrajzolása
?Access-ből adott xml fájl kinyerése
Listázás időpont szerint
Exportálás változó könyvtárba
» több téma
Társalgó
»A programozásból jól meg lehet élni?
»MFC tanulás
»Könyvet adok-veszek
»Hogy viszonyul ehhez a család?
»Nintendo wii
»Letölthető az új Rad Studio XE és Delphi XE
»Weblap véleményezés
»Játékmotor elmélet
»Informatikai bulvárlap
»Delphi-ről C++-ra váltás
» több téma
ASP  |  C#  |  C++  |  CSS  |  Delphi  |  Flash  |  HTML  |  Java  |  JavaScript  |  Pascal  |  Perl  |  PHP  |  Python  |  Visual Basic  |  Visual C++  |    »    

Tudástár

»

Free pascal unicode stringek

»

Free pascal unicode stringek

nyitotta: keljfeljancsi, idő: 2010.03.11., moderátor: netangel
  Értesítés változás esetén Felvétel kedvencekhez Küldés emailben Nyomtatható verzió

Kategóriák:Programozási nyelvek » Pascal

Sorrend:
Időzóna:
Blokkméret:
Hogyan oldhatom meg az karaktersorozat ékezettelenítését free pascal-ban?
Íme a kód, csak épp a közepében lévő pozícióegyeztetés elhasal azon, hogy a az angol és a magyar változó nem egyforma hosszú.

szebb kód itt

function ekezettelen(szoveg:string):string;
 var magyar,angol: string;
 f,m: Byte;
 begin
  m:=0;
  magyar:='áéíóöőúüűÁÉÍÓÖŐÚÜŰ';
  angol:= 'aeiooouuuAEIOOOUUU';
  for f:=1 to length(szoveg) do begin
    m:=pos(szoveg[f],magyar);
    if (m<>0) then szoveg[f]:=angol[m];
    m:=0;
  end;
  ekezettelen:=szoveg;
 end;
begin
 write(ekezettelen('Árvíztűrő tükörfúrógép'));
end.
Akkor ne UTF-8-ban kódolj.
Talán az egyik legegyszerűbb módszer az ha végigjárjuk az egész paraméterként átadott stringet és azt vizsgálgatjuk hogy a keresett magánhangzók megtalálhatóak e benne.

(*áéíóöőúüűÁÉÍÓÖŐÚÜŰ*)
program ekezetlen;
uses crt;

function ekezetnelkuli(szoveg:string):string;
var i:byte;
begin
   for i:=1 to length(szoveg) do begin
       case szoveg[i] of
            'á':szoveg[i]:='a';
            'Á':szoveg[i]:='A';
            'é':szoveg[i]:='e';
            'É':szoveg[i]:='E';
            'í':szoveg[i]:='i';
            'Í':szoveg[i]:='I';
            'ó':szoveg[i]:='o';
            'Ó':szoveg[i]:='O';
            'ö':szoveg[i]:='o';
            'Ö':szoveg[i]:='O';
            'ő':szoveg[i]:='o';
            'Ő':szoveg[i]:='O';
            'ú':szoveg[i]:='u';
            'Ú':szoveg[i]:='U';
            'ü':szoveg[i]:='u';
            'Ü':szoveg[i]:='U';
            'ű':szoveg[i]:='u';
            'Ű':szoveg[i]:='U';
       end;(*case*)
   end;(*for*)
   ekezetnelkuli:=szoveg;
end;(*ekezetnelkuli*)


begin (*main*)
  clrscr;
  write(ekezetnelkuli('Árvíztűrő tükörfúrógép'));
  while not keypressed do continue;
end.  (*main*)
Hallgass NevemTevé-re, és az Unicode-os műveleteknél használd a WideChar ill. WideString típusokat amelyek 16 bites karakterekkel dolgoznak.

Ezenkívűl nézd át legalább vázlatosan az UTF-8 kódolást (azaz, hogy miként kódolják a 16 bites Unicode-ot 8 biten), és akkor megérted, hogy miért nem működik a megoldásod a String típusra. Ugyanis a FreePascal-nak fogalma sincs, hogy abban UTF-8 kódolású adat van, még akkor sem ha az AnsiString-et használod, vagy még az UTF8String típusnál sem. Ezeket alapból 1 bájtos karakterekkel kezeli. Így működik akár a Pos, akár a karakter kiemelés, akár a case. Ha simán szövegkonstanst rakunk beléjük, akkor a Windows alapértelmezett kódlapjával (latin2) dolgozik az ékezetes karaktereknél (ezt jelenti az Ansi), és nem Unicode-ban, ill. nem UTF8-ban.

Tehát jegyezzük meg: Unicode-ot használó programunkban 3 féle kódolással találkozhatunk:

1: WideChar, WideString típusok: Ezek a műveletvégzéshez kellenek. Ezekkel jól működik mind a Pos (van ilyen formája!), mind a case, és a karakter kiválasztás tömbelem szerűen, de 16 bites értékekkel dolgozunk!

2: UTF-8 kódolás: ilyen adatok tárolhatók a bájtelemű string típusokban, de bizonyos műveletek a Pascal-ban nem várt eredményt adnak, mivel egyes karakterek 2 v. több bájton tárolódnak, s a Pascal erről mit se tud. A 16 bites és az UTF8 közötti átkódolást az UTF8Decode() ill. az UTF8Encode() végzi. Ezt a típust spórolás esetén használjuk, vagy ha a bemenő vagy kimenenő adataunk ilyen formátumúak. Az értékadáson kívül ne nagyon végezzünk velük más műveletet (bár az összehasonlítás jól megy a 16 bites értékkel összefüggésben!).

3: Ansi, azaz a Windows alapértelmezett kódlapja - nálunk legtöbbször Latin2 (=ISO8859-2): Ebben csak a 0-127-ig lévő értékek azonosak az UTF8-cal. A többi - közöttük az ékezetesek is - nem azonosak az UTF8 kétbájtos értékeivel illetve az Unicode 16 bites értékekkel se (Latin1 esetén más a helyzet). Sajnos a programszövegünkben lévő ékezetes karakterlánc konstansaink ebben jelennek meg, tehát használatuk majdnem elkerülhetetlen. Az átalakítás ebből (v. ebbe) az AnsiToUTF8() ill. UTF8ToAnsi() fügvényekkel lehetséges. Elvileg a Windows beállítható UTF-8 alapértelmezett karakterkészletre, s ekkor az utóbbi 2 fgv. nem kell, de ebben, és az ezzel járó komlpikációkkal nincs tapasztalatom. Valójában nagy hiányosság, hogy a programszövegünkben Unicode kódolású (16 bites) karakterlánc konstanst olvasható módon nem tudunk megadni - függetlenül a Windows kódlaptól.

A leírtakból kitalálható, hogy az előzőekben olvasható programkódoknak működniük kellene a programba beírt szövegre, de mind hibásan működik az UTF8-ban megadott értékekre. Ha az átkódolandó szöveg UTF8-ban jön, akkor végig kell csinálni a 16 bites mizériát! Ugyanakkor a "magyar" nevű karakterláncba bele kell varázsolnod a magyar ékezetes karakterek Unicode értékeit (vagy FlamingClaw válaszában a case konstansait kell Unicode értékekre cserélni)!
Az alábbi kóddal meg lehet csinálni amit szeretnél, de még a program forráskódjának karakterkódolása is számít.

program ekezettelenit;

{$mode objfpc}{$H+}

uses SysUtils,Classes;

const
   Ekezetes : array[0..17] of String=('Á','É','Í','Ó','Ö','Ő','Ú','Ü','Ű',
                                      'á','é','í','ó','ö','ő','ú','ü','ű');
  Ekezetmentes : array[0..17] of String=('A','E','I','O','O','O','U','U','U',
                                         'a','e','i','o','o','o','u','u','u');
function StringsReplace(STRBe : String):String;
var
  i : longint;
begin
  For i:=0 to 17 do
    STRBe:=StringReplace(STRBe,Ekezetes[i],Ekezetmentes[i],[rfReplaceAll]);
  Result:=STRBe;
end;

var
  Sbe : TStringList;
  TxtPath,Ski : String;
  i : longint;

begin
  WriteLn('Kerem az ekezeteket tartalmazo szovegfajl eleresi utjat: ');
  ReadLn(TxtPath);
  if not FileExists(TxtPath) then
  begin
    WriteLn('A fajl nem letezik: ',TxtPath);
    WriteLn('A program futasa veget ert!');
    halt(1);
  end;
  Sbe:=TStringList.Create;
  SBe.LoadFromFile(TxtPath);
//  Ski:=StringsReplace(AnsitoUtf8(Sbe.Text));
  Ski:=StringsReplace(Sbe.Text);
  WriteLn('A beirt szoveg ekezetmentesen: ');
  WriteLn(Ski);
  SBe.Free;
end. 

Egy másik megoldás, amit FlamingClaw is javasolt valahogy így néz ki nálam (bár ezt már egyszer bemásoltam itt a prog.hu-n):

program noekezet;
var f1,f2:text;
    c : char;
    tbf1,tbf2 : array[1..1048576] of byte;
begin
  if paramcount<2 then
  begin
    writeln('A programhasználata:');
    writeln('     noekezet fájl1 fájl2');
    writeln('ahol a fájl1 az a fájl amit át akarunk alakítani');
    writeln('a fájl2 pedig kimeneti fájl amibe az ékezetmentes szöveg kerül');
    halt;
  end;
 
  Assign(f1,Paramstr(1));
  Assign(f2,Paramstr(2));
  settextbuf(f1,tbf1);
  settextbuf(f2,tbf2);
 
  {$i-}
  Reset(f1);
  {$i+}
  if IOREsult<>0 then
  begin
    writeln('A fájl nem nyitható meg : ',Paramstr(1));
    halt;
  end;

  {$i-}
  Rewrite(f2);
  {$i+}
  if IOREsult<>0 then
  begin
    writeln('A fájl nem nyitható meg : ',Paramstr(2));
    halt;
  end;

  While not Eof(f1) do
  begin
    read(f1,c);
   
    if (ord(c)=195) or (ord(c)=197) then
    begin
      read(f1,c);
      case ord(c) of
        161 : c:='a';
        129 : c:='A';
        169 : c:='e';
        137 : c:='E';
        173 : c:='i';
        141 : c:='I';
        179 : c:='o';
        147 : c:='O';
        182 : c:='o';
        150 : c:='O';
        145 : c:='o';
        144 : c:='O';
        186 : c:='u';
        154 : c:='U';
        188 : c:='u';
        156 : c:='U';
        177 : c:='u';
        176 : c:='U';
      end;
    end
    else
      case ord(c) of
        225 : c:='a';
        193 : c:='A';
        233 : c:='e';
        201 : c:='E';
        237 : c:='i';
        205 : c:='I';
        243 : c:='o';
        211 : c:='O';
        246 : c:='o';
        214 : c:='O';
        245 : c:='o';
        213 : c:='O';
        250 : c:='u';
        218 : c:='U';
        252 : c:='u';
        220 : c:='U';
        251 : c:='u';
        219 : c:='U';
      end;
    write(f2,c);
  end;
  close(f1);
  close(f2);
end.
Nos remélem segít valamit :).
Belépés
E-mail cím:
Jelszó:

RSS források
-Hírek
-Cikkek
-Fórumok
-Állás/munka
Top pontgyűjtők
»Micu1.030
»Interlock280
»mezofi150
»Pitta_100
»Frostech0100
»szbzs.2100
»Hack100
»Riha60
»Akhiles50
»mrchandra50
Top wikieditorok
»Sting
»Doi
»FlamingClaw
»Argathron
»Csaboka2
»Vodka
»Joexy
»Ivn
»Balucinho
»Kelemzol
» ugrás a wikire
A nap kifejezései
»Algoritmus
»Hogyan kezdjem el
»Perl
» ugrás a wikire
Hírek
»Megérkezett a PostgreSQL 9.0 kiadásra jelölt változata
»Letölthető az új Rad Studio XE és Delphi XE
»Function-X digitális művészeti találkozó és demoscene party
»Webfejlesztőknek szóló közösségi oldalt indított a Microsoft
»Letölthető a hardvergyorsított Chrome 7 első fejlesztői kiadása
» több hír
PC Fórum hírek
»Itt az első kép az AMD nyolcmagos processzoráról
»"Szuperdizájnos" érintő-egeret mutatott be a Microsoft
»Szabadalmaztatta a számítógép kikapcsolását a Microsoft
»Vírusriadót váltott ki a webezőknél a Google
»Ingyen iWiW-ezhetnek mobiljaikról a T-Mobile-osok
»Automatikusan kiválogatja legfontosabb leveleink a Google
»OOo4Kids - ingyenes Office csomag gyerekeknek
»Új, gyorsabb Core i3 és Pentium processzorokat jelentett be az Intel
Tagi blogok
»PSP
»Első Programozó
»USB
»PHP, mint sablonmotor egyszerűen