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

286

    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. Ikävä sua j-mies!

      Enkä oikeesti ymmärrä miksi. Eihän me tunneta ees kovin hyvin. Mut haluaisin sun kanssa jotain säätöä sit kai vaan 🫦
      Ikävä
      60
      5870
    2. Voi itku! Sanna Marinilla EI OLLUT mitään tekemistä jäänmurtajakauppojen kanssa

      Miten tässä näin kävi? Sanna-kultti paniikissa.
      Maailman menoa
      212
      4833
    3. En välttämättä koskaan aikaisemmin tosissani uskonut mihinkään sielunkumppanuuteen ym

      Ennen kuin tapasin sinut. Oudointahan tässä on että ollaan tiedetty toisemme kuitenkin vuosia ja enemmän vuosia, mutta v
      Ikävä
      19
      4613
    4. Tykkäys ei tarkoita

      yhtään mitään!
      Ikävä
      55
      3865
    5. Sanna Marin kysyi hämmästyneenä: Onko Suomessa jäänmurtajia?

      Nettilehden toimittaja kysyi Sanna Marinilta suoraan, että sovittiinko nuo jäänmurtajien kaupat jo 2019, jolloin Marin k
      Maailman menoa
      68
      3777
    6. Mitä on tapahtunut myllymäessä ?

      On poliisit Sepänkadulla myllymäessä
      Kankaanpää
      11
      3511
    7. Voiko normaali ihminen ryhtyä vasemmistolaiseksi?

      Tätä jäin pohdiskelemaan.
      Maailman menoa
      99
      3436
    8. SDP haluaa 40 000 nettomaahanmuuttajaa

      SDP:n Suunnanmuutos-vaihtoehtobudjetissa, käy ilmi, että demarit itse asiassa vaativat räjähdysmäistä ”työperäisen” maah
      Maailman menoa
      76
      3272
    9. Puukotus Lidlissä

      Kuka sai puukkoo Lidlin pihas tänään. Ja kuka oli tekijä?
      Kankaanpää
      33
      2991
    10. Mikä tuota vasemmistolaisista jankkaavaa vaivaa?

      Pahasti on ihon alle, siis korvien väliin, päässeet kummittelemaan. Ei ole terveen ihmisen merkki jankata yhdestä asia
      Maailman menoa
      36
      2608
    Aihe