Delphi5 ja UTF-8

HighwayPatrol

Miten D5:lla saa kirjoitettu merkistön UTF-8 mukaisia tiedostoja?

13

1100

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • ASCII - koodaus

      Käsittääkseni Delphi 5 käyttää 8-bittistä windowsin merkkikoodausta. Kyseinen koodaus pohjautuu ASCII-koodaukseen. UTF-8 koodaus käyttää vaihtuvan pituista koodausta mutta sekin pohjautuu ASCII-koodaukseen. Eli kummankin koodauksen pohjalla on ASCII-koodaus.

      Katso ascii taulukko
      http://wiki.lazarus.freepascal.org/ASCII

      Tämä tarkoittaa sitä että 127 "alinta" merkkiä vastaavat toisiaan.

      Joudut muuttamaan vain merkit jotka ovat arvoltaan yli 127:n

      if ord(muunnettavat_merkit[merkin_paikka]) > 127 then

      Eli jos vastaan tulee 8-bittisen merkistön
      - Ä niin sen arvo korvautuu kahdella tavulla $C3 ja $84 ($ merkitsee heksa esitystä) eli desimaalisena 195 ja 132
      - Å $C3 ja $85 eli 195 ja 133
      - Ö $C3 ja $96 eli 195 ja 150
      - ä $C3 ja $A4 eli 195 ja 164
      - å $C3 ja $A5 eli 195 ja 165
      - ö $C3 ja $B6 eli 195 ja 182

      Kuten huomasit niin UTF-8 koodaus vie enemmän tilaa kuin 8-bittinen koodaus kun käytössä on muita kuin ASCII merkkejä. UTF-8 etuna on se että sillä pystytään esittämään kaikki merkit.

      • eurolla

        Euron merkki vaatii jo kolme tavua UTF-8 koodauksessa
        $E2 $82 $AC on desimaalisena 226, 130 ja 172


    • KAlle vaan

      > Miten D5:lla saa kirjoitettu merkistön UTF-8 mukaisia tiedostoja?

      Vähän turhan ylimalkainen oli kysymyksesi. Kannattaisi kertoa _tarkalleen_ että millaista operaatiota olet yrittelemässä. Useinhan nämä liittyvät mm. XML:ään tai johonkin muuhun specifiseen probleemaan, kenties kiinan Kanji-merkistöjen esitykseen jne.

      Sait jo yhden vinkin millä handlata simppeline suomalaisten ääkkösmerkkien korvaaminen UTF-vastineilla. Mutta ei tällainen koodaus vaikka johonkin tekstitiedostoon vielä jätä tietoa että tämä tekstitiedosto muuten nyt on sitten UTF-8 koodattua tiedostoa.
      Esim.HTML:ssä ja XML:ssä headerit kertovat kulloinkin käytetyn koodaustavan.

      Katsele vaikka onko tästä 20 USD hintaisesta toolsetistä mitään apuja ongelmaasi.
      http://www.delphipages.com/comp/diunicode_3_2-5050.html

      Ja ensi kerralla KERRO PALJON TARKEMMIN mitä oikein olet yrittämässä tehdä.

    • HighwayPatrol

      Tarve olisi tulostaa tiedostoksi sepa-maksuaineisto, joka lähetetään pankkiohjelmalla maksettavaksi. Laitan tämän viestin alle esimerkin viitteellisestä maksusta (kysymyksessä on kuitenkin viestillinen maksuaineisto).

      Netistä löysin tällaisen esimerkin:

      http://www.delphipages.com/forum/showthread.php?t=200627

      const
      Utf8ByteOrderMark=#$EF#$BB#$BF;
      procedure WriteWideString(FilePath:string;x:WideString);
      var
      f:TFileStream;
      begin
      f:=TFileStream.Create(FilePath,fmCreate);
      try
      f.Write(Utf8ByteOrderMark,3);
      f.Write(x[1],Length(x)*2);
      finally
      f.Free;
      end;
      end;

      • HighwayPatrol

        Esimerkin lähde: https://www.op.fi/media/liitteet?cid=150261694&srcpl=3.

        Esimerkki.


        OP-KESKUS LIITTYMÄKUVAUS 99
        Maksuliikepalvelut
        __________________________________________________
        OPK PIDÄTTÄÄ ITSELLÄÄN OKEUDEN MUUTOKSIIN
        10.3. Esimerkkisanomia
        10.3.1. SEPA-maksu viitteellä






        String
        2001-12-17T09:30:47.0Z
        false
        1
        100.5
        MIXD

        Aineiston tekijän nimi



        12354678901234567890
        TRF


        SEPA


        2009-05-13

        Maksajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI



        001234567





        FI9858499920000101




        OKOYFIHH


        SLEV


        9834894389743987


        NORM


        100.5



        NDEAFIHH



        Maksun saajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI




        FI2112345600000785






        SCOR

        00000000000000001245


      • HighwayPatrol
        HighwayPatrol kirjoitti:

        Esimerkin lähde: https://www.op.fi/media/liitteet?cid=150261694&srcpl=3.

        Esimerkki.


        OP-KESKUS LIITTYMÄKUVAUS 99
        Maksuliikepalvelut
        __________________________________________________
        OPK PIDÄTTÄÄ ITSELLÄÄN OKEUDEN MUUTOKSIIN
        10.3. Esimerkkisanomia
        10.3.1. SEPA-maksu viitteellä






        String
        2001-12-17T09:30:47.0Z
        false
        1
        100.5
        MIXD

        Aineiston tekijän nimi



        12354678901234567890
        TRF


        SEPA


        2009-05-13

        Maksajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI



        001234567





        FI9858499920000101




        OKOYFIHH


        SLEV


        9834894389743987


        NORM


        100.5



        NDEAFIHH



        Maksun saajan nimi

        Osoiterivi 1
        Osoiterivi 2
        FI




        FI2112345600000785






        SCOR

        00000000000000001245

        Op:n pdf:n sivulta 99 sivulle 101 löytyy tuo esimerkki.


      • snaju.2

        > Tarve olisi tulostaa tiedostoksi sepa-maksuaineisto, joka lähetetään pankkiohjelmalla
        > maksettavaksi. Laitan tämän viestin alle esimerkin viitteellisestä maksusta (kysymyksessä
        > on kuitenkin viestillinen maksuaineisto).

        Tuohan on normaalia ASCII-merkistöä sisältävä XML-tiedosto, ei siinä ole ainoatakaan 2:lla bytellä esitettyä UTF-merkkiä joukossa.

        Mitä tarkoitat "tulostaa tiedostoksi", kun tuohan on jo valmis XML-tiedosto, jonka pankkiohjelma vain kuskaa PC:ltä pankkiin.
        Tietenkin se XML-tiedosto voi olla yhtenä ainoana pötkönä, ilman ainoatakaan rivinvaihtomerkkejä, ja se näyttää aika vaikeaselkoiselta. Ja tämän mahdollisesti haluaisit pätkiä A4:lle mahtuviksi riveiksi?

        Vaikkapa IE-selain, tai tarkemmin selaimen sisäisesti kutsuma MSXML.DLL systeemitiedosto osaa avata tällaisen pötkörivisen XML-tiedostonkin, ja esittää sen ruudulla tuon OP-dokumentin esittämässä ihmisen luettavassa muodossa.

        Selostuksiasi en täysin tarkkaan ymmärrä, mutta saattaa olla että ongelmasi liittyvät XML-tiedostojen käsittelyyn, eivätkä niinkään UTF-tiedostojen luomiseen.

        EU:n SEPA-maksutiedostot on muutenkin määritelty niin, että vaikka otsikossa maailmanlaajuisen yhteensopivuuden vuoksi merkistönä mainitaan UTF-8, niin silti SEPA:ssa käytettävä merkistö on rajoitettu ISO-8859-15 merkkeihin. Joten ei sieltyä XML:stä mitään kummaa abyteristä merkistöä ole vastaan tulossa.


      • HighwayPatrol
        snaju.2 kirjoitti:

        > Tarve olisi tulostaa tiedostoksi sepa-maksuaineisto, joka lähetetään pankkiohjelmalla
        > maksettavaksi. Laitan tämän viestin alle esimerkin viitteellisestä maksusta (kysymyksessä
        > on kuitenkin viestillinen maksuaineisto).

        Tuohan on normaalia ASCII-merkistöä sisältävä XML-tiedosto, ei siinä ole ainoatakaan 2:lla bytellä esitettyä UTF-merkkiä joukossa.

        Mitä tarkoitat "tulostaa tiedostoksi", kun tuohan on jo valmis XML-tiedosto, jonka pankkiohjelma vain kuskaa PC:ltä pankkiin.
        Tietenkin se XML-tiedosto voi olla yhtenä ainoana pötkönä, ilman ainoatakaan rivinvaihtomerkkejä, ja se näyttää aika vaikeaselkoiselta. Ja tämän mahdollisesti haluaisit pätkiä A4:lle mahtuviksi riveiksi?

        Vaikkapa IE-selain, tai tarkemmin selaimen sisäisesti kutsuma MSXML.DLL systeemitiedosto osaa avata tällaisen pötkörivisen XML-tiedostonkin, ja esittää sen ruudulla tuon OP-dokumentin esittämässä ihmisen luettavassa muodossa.

        Selostuksiasi en täysin tarkkaan ymmärrä, mutta saattaa olla että ongelmasi liittyvät XML-tiedostojen käsittelyyn, eivätkä niinkään UTF-tiedostojen luomiseen.

        EU:n SEPA-maksutiedostot on muutenkin määritelty niin, että vaikka otsikossa maailmanlaajuisen yhteensopivuuden vuoksi merkistönä mainitaan UTF-8, niin silti SEPA:ssa käytettävä merkistö on rajoitettu ISO-8859-15 merkkeihin. Joten ei sieltyä XML:stä mitään kummaa abyteristä merkistöä ole vastaan tulossa.

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.


      • snaju.2
        HighwayPatrol kirjoitti:

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        > Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko
        > ääkkösistä ongelmaa.

        Kunhan ISO-8859-15 merkistöä laittelet, lähinnä ääkkösien osalta, etkä sekoa DOS-ajan ääkkösalueelle, niin Sepan XML-tiedoston tosiaan ihan täysin pure-Asciita.

        > Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        Eikä ole, kun asciita ne Sepan XML:t kuuluu olla. Ulkomaille siirtyvät Sepat enkoodataan omassa pankissasi ennen jatkosiirtoa, jolloin ääkköset korvataan "¨??" tyyppsillä notaatioilla joita HTML:ssäkin käytetään.


      • Kalle vaan
        HighwayPatrol kirjoitti:

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        "Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä
        ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na."

        Kannattaa puhua oikeilal termeillä, ei tuo mitään TULOSTAMISTA ole! Vaan ohjelmastasi käsin TALLETAT joksikin tiedostoksi, jotakin ohjelmasi dataa.

        Sinänsä LMP tiedostot ja SEPA tiedostot ovat ihan täsmälleen samanlaisella merkkituuballa tehty molemmat. Tässä kohdin nyt ei ole yhtään mitään uutta keksittävänä.

        Senkuin talletaa Delphistä Ascii-tiedostoksi ihan samoilla menetelmillä kuin on tehnyt on tehnyt Lmp-tiedostojakin. Notepadissa niitä tuotoksiaan voi sitten katsella.

        Uudemmat Notepadit tosin saattavat fuskata, ne yrittävät ymmärtää liikaa ja saattavat tehdä ruudulla näytettäville ääkköstyypin specialmerkeille jotakin mielestään tarpeellisia muunnoksia. Mutta jos testimielessä kertaalleen avaat tuotoksesi vaikka vanhassa MS-DOS:in EDIT-editorissa, tai vaikka Delphin omassa IDE:ssäkin, tms., niin ne ovat siitä hyviä että ne eivät tulkitse mitään, vaan näyttävät kaiken lahjomattomana ulos.


      • Delphikoodari..
        HighwayPatrol kirjoitti:

        Nyt tulostan ohjelmasta suoraan LMP-muotoisen tekstitiedoston, jonka lähetän pankkiohjelmalla eteenpäin. Tarkoitus olisi siis muuttaa lähtevä aineisto Sepa-muotoiseksi. Ei kai tagien tulostaminen koodista ole vaikeaa. Ongelmaksi voivat muodostua ääkköset esimerkiksi maksajan tai saajan nimessä.

        Osaan siis tulostaa ascii-muotoisen tekstitiedoston. Sitä en tiedä, tuleeko ääkkösistä ongelmaa. Oletan kuitenkin, että olisi parempi tulostaa UTF-8:na.

        Unohtakaa kaikki vanhat paskat, ASCII-merkistöt. UTF-8 on yhteensopiva ASCII:n kanssa ja tästä ylimenevä osuus on sitten Unicodea. UTF-8 on täysin riittävä kaikille merkeille.


      • delphiguru

        VÄÄRIN tehty !!!

        tuo 3-tavuinen os UTF-8 -enkoodattu BOM (Byte Order Mark).

        MUTTA:

        WideString käyttää UTF16LE -enkoodattua Unicodea.

        Siksipä, jos kirjoitat itse merkkijonon näin:

        const
        Utf8ByteOrderMark=#$EF#$BB#$BF;
        procedure WriteWideString(FilePath:string;x:WideString);
        var
        f:TFileStream;
        begin
        f:=TFileStream.Create(FilePath,fmCreate);
        try
        f.Write(Utf8ByteOrderMark,3);
        f.Write(x[1],Length(x)*2);
        finally
        f.Free;
        end;
        end;

        niin luonnollisesti silloin tuon BOM -merkin pitää olla enkoodattu UTF16LE -formaatissa, EIKÄ utf-8 formaatissa !

        Jos sellaisenaan käytät ylläolevaa koodia, niin huomaat että jos avaat tiedoston Windowsin NOTEPADilla (suom: muistio), silloin näkyy pelkkää roskaa.

        Syy: Alussa olevan BOM:in formaatti ei vastaa itse tietosisällön formaattia.

        Tee vaikkapa NOTEPADilla tiedosto, jossa on vain 1 merkki: "A". (ilman lainausmerkkejä).

        Tallenna se nimellä "koe1.txt" muodossa "Unicode" (Microsoftin kielenkäytössä
        Unicode = UTF-16LE).

        Sitten avaa tekstitiedosto "koe1.txt" debug.exe:llä näin:

        debug koe1.exe

        anna komento r (näyttää rekisterit)

        anna komento d (näyttää tiedoston 256 ensimmäistä tavua, tai koko tiedoston ja perässä satunnaista dataa 256 tavuun asti, jos tiedosto on alle 256 tavua).

        katso heksadesimaalidatasta 2 ensimmäistä tavua (koska UTF-16LE -muodossa BOM -merkki vie 2 tavua, kuten kaikki muutkin BMP:hen kuuluvat merkit).

        nuo 2 ensimmäistä tavua ovat BOM -merkki UTF-16 -esitysmuodossa, ja Delphi -koodissa tulee korvata näillä ylläoleva virheellinen:

        const
        Utf8ByteOrderMark=#$EF#$BB#$BF;

        Tuo ylläoleva ilmeisesti OLISI oikein, jos data olisi UTF-8 -formaatissa, ks. UTF8String sekä AnsiToUTF8 ja UTF8ToAnsi -funktiot.

        Mutta WideStringin esitysmuoto on UTF-16LE, eikä UTF-8.

        BMP = Basic Multilingual Page = ensimmäiset noin 63000 merkkiä.

        Teoreettinen maksimi olisi 65536, mutta

        a) osa koodeista on erikoiskäytössä kuten esim. LOW and HIGH surrogates; näiden (käytetään AINA parina) avulla esitetään muut kuin BMP:hen kuuluvat merkit.

        b) osa koodeista on eri syistä pysyvästi varattu, eli niitä ei käytetä. Esim: BOM:n byteswapattu esitys on tällainen se on pysyvästi kielletty, jotta ei syntyisi sekaannusta oikean BOM:in kanssa.

        Eli jos lukiessasi UTF-16 -enkoodattua tiedostoa alussa on byteswapattu BOM, silloin endianness on väärin, ja sinun täytyy silloin lukea data 2 tavun yksiköissä (Delphissä WORD), ja byteswapata kukin WORD.

        esim: $FFFE -> $FEFF.


    • Delphikoodari..

      Löytyy täältä! Itse koodailen edelleen Delphi 2006:lla, joka ei ole "Unicode" tuettu, mutta täältä löytyy kirjastot millä handlaat Unicoden (UTF-8) esim.

      Olen koodannut sovellusta, jonka pitää käsitellä venäjänkielisiä kyriillisiä merkkejä. Käytä vain Delphissä WideString muuttujia merkkijonoille ja linkin työkalut hoitaa loput :)

      http://fundementals.sourceforge.net/unicode.html

      Jos tarvitset Unicode-komponentteja Delphiin, eli komponentit jotka tukee unicodea, asenna TNT-komponentit, pitäisi onnistua vaikka kiinalaiset merkit :)

      http://www.google.com/search?client=safari&rls=en&q=delphi tnt-control&ie=UTF-8&oe=UTF-8

    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Nainen kokki autossa kammottavan kuoleman sähköauto-Teslan syttyessä tuleen.

      https://www.is.fi/autot/art-2000011652873.html Näin vaarallisia sähköautopalot voivat olla.
      Maailman menoa
      74
      5009
    2. Persuja ei aluevaltuustoissa näy

      Ei tunnu persuja paljon paikalliset asiat kiinnostavan, vaan ainoastaan ulkomaalaiset, joku Israel ja Trumpin fanitus.
      Maailman menoa
      15
      3398
    3. Päivän Riikka: Uudenkaupungin autotehdas hiljeni

      Näin ne 100 000 uutta pysyvää ei-tempputyötä yksityiselle sektorille tämän hallituksen ansiosta syntyy. Työntekijöille j
      Maailman menoa
      24
      2690
    4. Kerro kaivattusi nimi tai nimikirjaimet

      🌠 Tähdenlento! Kirjoittamalla kaivattusi nimen tai nimikirjaimet tähän, saattaa toiveesi toteutua.
      Ikävä
      57
      1747
    5. Miksi pitäisit enemmän

      Minusta kuin siitä toisesta?
      Ikävä
      47
      1566
    6. Tämmönen höpsö

      Höpönassu mä olen. En mikään erikoinen…hölötän välillä ihan levottomia. Tykkäisit varmasti jos olisin siellä sun vieress
      Suhteet
      44
      1346
    7. Mitä meidän välillä

      Tulee tapahtumaan vai tuleeko mitään?
      Ikävä
      94
      1342
    8. Alkuvuodesta poistuu työttömyyskorvaus kaikilta joilla on säästössä rahaa

      Tippuu korvaukselta iso määrä työttömiä.
      Maailman menoa
      231
      1206
    9. Hiljaisuus

      Tarkoittaa välinpitämättömyyttä, henkistä väkivaltaa ja kiusaamista. Olet valinnut hiljaisuuden.
      Ikävä
      71
      1025
    10. IS Viikonloppu 29.-30.11.2025

      Antti Skytältä 3-tasoinen ristikko. Pääkuvassa on harhauttava elementti, mikä saattaa hidastaa myös muiden kuin minun ra
      Sanaristikot
      53
      902
    Aihe