Lazarus length() laskee merkkijonon pituuden väärin

Anonyymi

Lazaruksen versiossa 2.0.2 oleva Length() funktio laskee ääkkösiin ja öökkösiin päättyvät merkkijonot väärin. Tälle funktiolle ei taida olla olemassa korvaavaa funktiotakaan, joten pitäisi keksiä keino selvittää virheestä huolimatta merkkijonon todellinen pituus.

Esimerkkinä vaikka nämä kaksi sanaa, jotka Length() funktion mielestä on samapituisia:
aktiviteeteitta
aktiviteetillä

Asiaa selventävä kuva:
https://i.postimg.cc/8ztf6YtY/Pituus-Testi-161.png

9

225

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Anonyymi
    • Anonyymi

      Ei laske. Tuo system käännösyksikön length kertoo pituuden tavuina (esim. merkkijonon).
      Jos haluat tietää merkkien määrän niin käytä käännösyksikön LazUTF8 funktiota UTF8Length.

      Se miksi length laskee oikein joidenkin merkkien määrän johtuu siitä että kyseiset merkit ovat UTF-8:ssa ( http://wiki.freepascal.org/UTF-8/fi ) koodattu yksitavuiseksi eli ovat niin sanottuja ASCII merkkejä ( http://wiki.freepascal.org/ASCII/fi ).

      Eli funktio length kertoo (merkkijonossa) käytettävän muistin määrän ja funktio UTF8Length kertoo merkkijonon UTF-8 merkkien määrän. Muista lisätä LazUTF8 uses-lauseeseen!

      • Anonyymi

        KIITOS
        Onpa hyvä että löytyy Lazaruksen taitaja, tämä päästi minut pinteestä tällä kertaa.


      • Anonyymi

        Käyttämällä sisäisesti UTF-8 merkistöä niin (kuten Lazarus) se kuluttaa muistia vain puolta tai 3/4 vähemmän kuin jotkut muut ohjelmointikielet kun käytössä on englannin tai suomen kielinen sanasto.


      • Anonyymi
        Anonyymi kirjoitti:

        Käyttämällä sisäisesti UTF-8 merkistöä niin (kuten Lazarus) se kuluttaa muistia vain puolta tai 3/4 vähemmän kuin jotkut muut ohjelmointikielet kun käytössä on englannin tai suomen kielinen sanasto.

        suomen- ja englanninkielen tarpeisiin riittäisi Windows-1252 -merkkivalikoima, jonka etu on periaate: 1 merkki = 1 tavu.

        Jos kuitenkin halutaan merkkijärjestelmä, joka on kansainvälinen, eli kelpaa kaikkien kielten kirjoittamiseen ja myös vaikkapa sanakirjaohjelman tekemiseen (jossa pitää esitää 2 tai useampaa kieltä samanaikaisesti) niin silloin valinta on selvä: Unicode.

        Unicodessa mahdollisia merkkejä on melkein 17 * 65536 = 1114112 merkkiä teoreettisesti, mutta jotkut koodit on pysyvästi varattuja = ei merkkiä, joten todellisten mahdollisten merkkien määrä on hieman tuota teoreettista arvoa pienempi.

        Kaikki nämä ovat UNICODE:n esitystapoja:

        UTF-8
        UTF-16LE
        UTF-16BE
        UTF-32LE
        UTF-32BE
        UCS-2
        UCS-4

        näistä UCS-4 = UTF-32, mutta (LE/BE?) jätän lukijan selvitettäväksi.

        Sensijaan UCS-2 on osajoukko UTF-16:sta.

        Eli UCS-2 mahdollistaa vain koodit 0..65535 eli U 0000 .. U FFFF.
        Sensijaan UTF-16 mahdollistaa kaikki lailliset UNICODE-merkit.

        Microsoftin kielenkäytössä UNICODE = UTF-16LE, mutta Microsoftin ulkopuolisessa käytössä tuollainen kielenkäyttö on virheellistä, sillä UTF-16LE on vain yksi mahdollisista UNICODEn enkoodaustavoista.

        Freepascalissa ja Lazaruksessa yleisin UNICODEn esitystapa on UTF-8.

        Tuossa UTF-8:ssa siis ASCII -merkit (koodit 0..127) tallennetaan 1 tavulla, muut merkit kuluttavat tilaa 2..4 tavua.

        Windows API:ssahan UNICODE-merkistön käyttö tapahtuu pääosin UTF-16LE -enkoodaustavalla, mutta jotkut funktiot tukevat vain UCS-2 eli tällöin vain merkit 0..65535 ovat käytettävissä.

        Tästä siis todellakin seuraa se, että ä, ö, Ä, Ö kuluttavat 2 tavua UTF-8 enkoodaustavalla.

        Mainittakoon vielä:

        Windowsissa homma toimii oikein, kun UNICODE -koodattu tekstitiedosto alkaa AINA BOM -merkillä (Byte Order Mark), jos ei ala, niin Windows tulkitsee tiedoston olevan Windows-1252 -merkistöä käyttävä (suomen- ja englanninkielinen windows, toki vaikkapa venäjän- tai thaikielisessä windowsissa tuo oletus on jotain muuta kuin Windows-1252, eli se on paikalliseen venäläiseen tai thaimaalaiseen standardiin perustuva).

        Linux -maailman yksi suurimpia mokia on se, että linux kernel -kehittäjät kieltäytyivät muokkaamasta linux kerneliä siten, että kun komentoriviltä annetaan skriptitiedoston nimi, niin kieltäytyivät muokkaamasta ns. shebang -tunnistusta (esimerkki:

        #!/bin/bash
        ) siten, että se voisi olla myös:

        <UTF-8 -enkoodattu BOM>#!/bin/bash

        Jos noin olisi tehty, niin kaikki toimisi hienosti ja tuo "BOM pakollliseksi kaikkialla" ei aiheuttaisi mitään ongelmia missään!

        Mutta kun linux kernel -kehittäjät kieltäytyivät tästä, saatiin aikaiseksi iso yhteensopivuusongelma windows- ja linux -maailman välille:

        windowsissa tuon BOM on utf-8 -enkoodatussa tekstitiedostossa pakollinen tiedoston alussa, mutta linuxissa skriptitiedostoissa tuo tiedoston alussa oleva BOM on kielletty, koska sen käyttäminen johtaisi siihen, ettei linux kernel tunnista tiedostoa skriptiksi !

        Mutta, milloinkas linux-kehittäjät olisivat käyttäneet järkeä - linuxissa GPL -fanatismi (ja eräät muutkin fanatismit) ovat järjen käyttöä tärkeämpiä asioita.

        Ehkä tarkoitus onkin vieraannuttaa normaalikäyttäjät linuxista naurettavilla ja huonoilla teknisillä ratkaisuilla... miksikö? .... no siksi, että näin taataan windowsin valta-aseman säilyminen - windowsin laajamittaisesta vakoilusta huolimatta.

        Ei kukaan vakoilusta tykkää - mutta vielä vähemmän käyttäjät tykkäävät teknisestä hölmöilystä - jota tuon BOM:in tukemattomuus skriptitiedoston alussa edustaa,


      • Anonyymi
        Anonyymi kirjoitti:

        suomen- ja englanninkielen tarpeisiin riittäisi Windows-1252 -merkkivalikoima, jonka etu on periaate: 1 merkki = 1 tavu.

        Jos kuitenkin halutaan merkkijärjestelmä, joka on kansainvälinen, eli kelpaa kaikkien kielten kirjoittamiseen ja myös vaikkapa sanakirjaohjelman tekemiseen (jossa pitää esitää 2 tai useampaa kieltä samanaikaisesti) niin silloin valinta on selvä: Unicode.

        Unicodessa mahdollisia merkkejä on melkein 17 * 65536 = 1114112 merkkiä teoreettisesti, mutta jotkut koodit on pysyvästi varattuja = ei merkkiä, joten todellisten mahdollisten merkkien määrä on hieman tuota teoreettista arvoa pienempi.

        Kaikki nämä ovat UNICODE:n esitystapoja:

        UTF-8
        UTF-16LE
        UTF-16BE
        UTF-32LE
        UTF-32BE
        UCS-2
        UCS-4

        näistä UCS-4 = UTF-32, mutta (LE/BE?) jätän lukijan selvitettäväksi.

        Sensijaan UCS-2 on osajoukko UTF-16:sta.

        Eli UCS-2 mahdollistaa vain koodit 0..65535 eli U 0000 .. U FFFF.
        Sensijaan UTF-16 mahdollistaa kaikki lailliset UNICODE-merkit.

        Microsoftin kielenkäytössä UNICODE = UTF-16LE, mutta Microsoftin ulkopuolisessa käytössä tuollainen kielenkäyttö on virheellistä, sillä UTF-16LE on vain yksi mahdollisista UNICODEn enkoodaustavoista.

        Freepascalissa ja Lazaruksessa yleisin UNICODEn esitystapa on UTF-8.

        Tuossa UTF-8:ssa siis ASCII -merkit (koodit 0..127) tallennetaan 1 tavulla, muut merkit kuluttavat tilaa 2..4 tavua.

        Windows API:ssahan UNICODE-merkistön käyttö tapahtuu pääosin UTF-16LE -enkoodaustavalla, mutta jotkut funktiot tukevat vain UCS-2 eli tällöin vain merkit 0..65535 ovat käytettävissä.

        Tästä siis todellakin seuraa se, että ä, ö, Ä, Ö kuluttavat 2 tavua UTF-8 enkoodaustavalla.

        Mainittakoon vielä:

        Windowsissa homma toimii oikein, kun UNICODE -koodattu tekstitiedosto alkaa AINA BOM -merkillä (Byte Order Mark), jos ei ala, niin Windows tulkitsee tiedoston olevan Windows-1252 -merkistöä käyttävä (suomen- ja englanninkielinen windows, toki vaikkapa venäjän- tai thaikielisessä windowsissa tuo oletus on jotain muuta kuin Windows-1252, eli se on paikalliseen venäläiseen tai thaimaalaiseen standardiin perustuva).

        Linux -maailman yksi suurimpia mokia on se, että linux kernel -kehittäjät kieltäytyivät muokkaamasta linux kerneliä siten, että kun komentoriviltä annetaan skriptitiedoston nimi, niin kieltäytyivät muokkaamasta ns. shebang -tunnistusta (esimerkki:

        #!/bin/bash
        ) siten, että se voisi olla myös:

        <UTF-8 -enkoodattu BOM>#!/bin/bash

        Jos noin olisi tehty, niin kaikki toimisi hienosti ja tuo "BOM pakollliseksi kaikkialla" ei aiheuttaisi mitään ongelmia missään!

        Mutta kun linux kernel -kehittäjät kieltäytyivät tästä, saatiin aikaiseksi iso yhteensopivuusongelma windows- ja linux -maailman välille:

        windowsissa tuon BOM on utf-8 -enkoodatussa tekstitiedostossa pakollinen tiedoston alussa, mutta linuxissa skriptitiedostoissa tuo tiedoston alussa oleva BOM on kielletty, koska sen käyttäminen johtaisi siihen, ettei linux kernel tunnista tiedostoa skriptiksi !

        Mutta, milloinkas linux-kehittäjät olisivat käyttäneet järkeä - linuxissa GPL -fanatismi (ja eräät muutkin fanatismit) ovat järjen käyttöä tärkeämpiä asioita.

        Ehkä tarkoitus onkin vieraannuttaa normaalikäyttäjät linuxista naurettavilla ja huonoilla teknisillä ratkaisuilla... miksikö? .... no siksi, että näin taataan windowsin valta-aseman säilyminen - windowsin laajamittaisesta vakoilusta huolimatta.

        Ei kukaan vakoilusta tykkää - mutta vielä vähemmän käyttäjät tykkäävät teknisestä hölmöilystä - jota tuon BOM:in tukemattomuus skriptitiedoston alussa edustaa,

        Näkisin tuollaisen lisäyksen typeränä monestakin syystä. Turha alkaa riitelemään jo päätetystä asiasta. Nykykäytäntö on hyvä ja erittäin hyvin perusteltu.


      • Anonyymi
        Anonyymi kirjoitti:

        Näkisin tuollaisen lisäyksen typeränä monestakin syystä. Turha alkaa riitelemään jo päätetystä asiasta. Nykykäytäntö on hyvä ja erittäin hyvin perusteltu.

        Mikä järki skriptistä olisi tehdä kieli(locale) riippuvaista? Eikö sen tulisi toimia kuitenkin kaikissa ympäristöissä oletusarvoisesti? Käyttäjän locale-asetuksen voi sitten skriptistä tarkistaa ja toimia sen mukaisesti?
        Jos nyt kuitenkin haluttaisiin tehdä tällaisia tyhmyyksiä, niin oikea tapa olisi määritellä tiedostoattribuuttina chattr-komennolle, jolloin tiedoston meta-tiedoista saisi tietää koodauksen?


      • Anonyymi
        Anonyymi kirjoitti:

        Mikä järki skriptistä olisi tehdä kieli(locale) riippuvaista? Eikö sen tulisi toimia kuitenkin kaikissa ympäristöissä oletusarvoisesti? Käyttäjän locale-asetuksen voi sitten skriptistä tarkistaa ja toimia sen mukaisesti?
        Jos nyt kuitenkin haluttaisiin tehdä tällaisia tyhmyyksiä, niin oikea tapa olisi määritellä tiedostoattribuuttina chattr-komennolle, jolloin tiedoston meta-tiedoista saisi tietää koodauksen?

        Skriptin alku:
        #!/bin/bash
        LC_CTYPE=en_US.utf8
        -tähän asti kaikki merkit ovat laillisia utf-8 enkoodattuja, mutta myös ASCII-enkoodattuja, koodaukset overlappaa mukavasti
        -tästä eteenpäin locale-asetus on haluttu ja toiminta kuten halusit, kunhan asetettava locale on asennettu?
        Muuten tulee virhe:
        warning: setlocale: LC_CTYPE: cannot change locale (en_US): File not found
        Eli toiminta on jo olemassa ilman että skriptin alun koodia tarvitsee muuttaa millään tavalla.


      • Anonyymi
        Anonyymi kirjoitti:

        suomen- ja englanninkielen tarpeisiin riittäisi Windows-1252 -merkkivalikoima, jonka etu on periaate: 1 merkki = 1 tavu.

        Jos kuitenkin halutaan merkkijärjestelmä, joka on kansainvälinen, eli kelpaa kaikkien kielten kirjoittamiseen ja myös vaikkapa sanakirjaohjelman tekemiseen (jossa pitää esitää 2 tai useampaa kieltä samanaikaisesti) niin silloin valinta on selvä: Unicode.

        Unicodessa mahdollisia merkkejä on melkein 17 * 65536 = 1114112 merkkiä teoreettisesti, mutta jotkut koodit on pysyvästi varattuja = ei merkkiä, joten todellisten mahdollisten merkkien määrä on hieman tuota teoreettista arvoa pienempi.

        Kaikki nämä ovat UNICODE:n esitystapoja:

        UTF-8
        UTF-16LE
        UTF-16BE
        UTF-32LE
        UTF-32BE
        UCS-2
        UCS-4

        näistä UCS-4 = UTF-32, mutta (LE/BE?) jätän lukijan selvitettäväksi.

        Sensijaan UCS-2 on osajoukko UTF-16:sta.

        Eli UCS-2 mahdollistaa vain koodit 0..65535 eli U 0000 .. U FFFF.
        Sensijaan UTF-16 mahdollistaa kaikki lailliset UNICODE-merkit.

        Microsoftin kielenkäytössä UNICODE = UTF-16LE, mutta Microsoftin ulkopuolisessa käytössä tuollainen kielenkäyttö on virheellistä, sillä UTF-16LE on vain yksi mahdollisista UNICODEn enkoodaustavoista.

        Freepascalissa ja Lazaruksessa yleisin UNICODEn esitystapa on UTF-8.

        Tuossa UTF-8:ssa siis ASCII -merkit (koodit 0..127) tallennetaan 1 tavulla, muut merkit kuluttavat tilaa 2..4 tavua.

        Windows API:ssahan UNICODE-merkistön käyttö tapahtuu pääosin UTF-16LE -enkoodaustavalla, mutta jotkut funktiot tukevat vain UCS-2 eli tällöin vain merkit 0..65535 ovat käytettävissä.

        Tästä siis todellakin seuraa se, että ä, ö, Ä, Ö kuluttavat 2 tavua UTF-8 enkoodaustavalla.

        Mainittakoon vielä:

        Windowsissa homma toimii oikein, kun UNICODE -koodattu tekstitiedosto alkaa AINA BOM -merkillä (Byte Order Mark), jos ei ala, niin Windows tulkitsee tiedoston olevan Windows-1252 -merkistöä käyttävä (suomen- ja englanninkielinen windows, toki vaikkapa venäjän- tai thaikielisessä windowsissa tuo oletus on jotain muuta kuin Windows-1252, eli se on paikalliseen venäläiseen tai thaimaalaiseen standardiin perustuva).

        Linux -maailman yksi suurimpia mokia on se, että linux kernel -kehittäjät kieltäytyivät muokkaamasta linux kerneliä siten, että kun komentoriviltä annetaan skriptitiedoston nimi, niin kieltäytyivät muokkaamasta ns. shebang -tunnistusta (esimerkki:

        #!/bin/bash
        ) siten, että se voisi olla myös:

        <UTF-8 -enkoodattu BOM>#!/bin/bash

        Jos noin olisi tehty, niin kaikki toimisi hienosti ja tuo "BOM pakollliseksi kaikkialla" ei aiheuttaisi mitään ongelmia missään!

        Mutta kun linux kernel -kehittäjät kieltäytyivät tästä, saatiin aikaiseksi iso yhteensopivuusongelma windows- ja linux -maailman välille:

        windowsissa tuon BOM on utf-8 -enkoodatussa tekstitiedostossa pakollinen tiedoston alussa, mutta linuxissa skriptitiedostoissa tuo tiedoston alussa oleva BOM on kielletty, koska sen käyttäminen johtaisi siihen, ettei linux kernel tunnista tiedostoa skriptiksi !

        Mutta, milloinkas linux-kehittäjät olisivat käyttäneet järkeä - linuxissa GPL -fanatismi (ja eräät muutkin fanatismit) ovat järjen käyttöä tärkeämpiä asioita.

        Ehkä tarkoitus onkin vieraannuttaa normaalikäyttäjät linuxista naurettavilla ja huonoilla teknisillä ratkaisuilla... miksikö? .... no siksi, että näin taataan windowsin valta-aseman säilyminen - windowsin laajamittaisesta vakoilusta huolimatta.

        Ei kukaan vakoilusta tykkää - mutta vielä vähemmän käyttäjät tykkäävät teknisestä hölmöilystä - jota tuon BOM:in tukemattomuus skriptitiedoston alussa edustaa,

        "suomen- ja englanninkielen tarpeisiin riittäisi Windows-1252 -merkkivalikoima, jonka etu on periaate: 1 merkki = 1 tavu."

        Tuo on vanhentunut. UTF-8 tuli uudeksi standardiksi vuosikymmeniä sitten.

        "Windowsissa homma toimii oikein, kun UNICODE -koodattu tekstitiedosto alkaa AINA BOM -merkillä (Byte Order Mark)"

        BOM ollut AINA valinnainen. Sellaista ei tarvitse kun kaikki tekstitiedostot ovat UTF-8:a. Mitään Windows-1252 merkistöä ei käytetä, itseasiassa ohjelmistotestaajat merkitsevät tuollaisen bugiksi jos sellaista näkyy kun UTF-8 on tietokannassa, lähdekoodin tiedostoissa kuin myös käyttöliittymässä. Tulee vain ongelmia jos sotkee jotain muuta.

        "<UTF-8 -enkoodattu BOM>#!/bin/bash"

        Ei helvetissä mitään tuollaisia. Helposti aiheutuu bugeja jos tuollaista pelleilyä tehdään.

        "Mutta kun linux kernel -kehittäjät kieltäytyivät tästä, saatiin aikaiseksi iso yhteensopivuusongelma windows- ja linux -maailman välille"

        Ei ole mitään yhteensopivuusongelmaa kun kaikki käyttävät UTF-8:a.

        "Ehkä tarkoitus onkin vieraannuttaa normaalikäyttäjät linuxista naurettavilla ja huonoilla teknisillä ratkaisuilla... miksikö? .... no siksi, että näin taataan windowsin valta-aseman säilyminen - windowsin laajamittaisesta vakoilusta huolimatta."

        Ei Windowsilla ole mitään valta-asemaa.


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

    Luetuimmat keskustelut

    1. Useita puukotettu Tampereella

      Mikäs homma tämä nyt taas on? "Useaa henkilöä on puukotettu Tampereen keskustassa kauppakeskus Ratinan lähistöllä." ht
      Tampere
      148
      2814
    2. Asiakas iski kaupassa varastelua tehneen kanveesiin.

      https://www.iltalehti.fi/kotimaa/a/33a85463-e4d5-45ed-8014-db51fe8079ec Oikein. Näin sitä pitää. Kyllä kaupoissa valtava
      Maailman menoa
      363
      2017
    3. Leipivaaran päällä on kuoleman hiljaista.

      Suru vai suuri helpotus...
      Puolanka
      40
      1757
    4. Kuka rääkkää eläimiä Puolangalla?

      Poliisi ampui toistakymmentä nälkiintynyttä eläintä Puolangalla Tilalta oli ollut karkuteillä lähes viisikymmentä nälkii
      Puolanka
      35
      1678
    5. Meneeköhän sulla

      oikeasti pinnan alla yhtä huonosti kuin mulla? Tai yhtä huonosti mutta jollain eri tyylillä? Ei olisi pitänyt jättää sua
      Ikävä
      31
      1393
    6. Jos ei tiedä mitä toisesta haluaa

      Älä missään nimessä anna mitään merkkejä kiinnostuksesta. Ole haluamatta mitään. Täytyy ajatella toistakin. Ei kukaan em
      Ikävä
      94
      1213
    7. Määpä tiijän että rakastat

      Minua nimittäin. Samoin hei! Olet mun vastakappaleeni.
      Ikävä
      54
      1173
    8. Muutama kysymys ja huomio hindulaisesta kulttuurista.

      Vedakirjoituksia pidetään historiallisina teksteinä, ei siis "julistuksena" kuten esimerkiksi Raamattua, vaan kuten koul
      Hindulaisuus
      327
      949
    9. Jumala puhui minulle

      Hän kertoi sinusta asioita, joiden takia jaksan, uskon ja luotan. Hän kuvaili sinua minulle ja pakahduin onnesta kuulles
      Ikävä
      110
      938
    10. Annan meille mahdollisuuden

      Olen avoimin mielin ja katson miten asiat etenevät. Mutta tällä kertaa sun on tehtävä eka siirto.Sen jälkeen olen täysil
      Ikävä
      53
      782
    Aihe