Kommentit
- Ei oikeastaan oikein. Selitän, jos kirjoitat " שָׁ " yhdistemerkki, joka koostuu " ש ", " ָ " ja " ׁ ", vovels, sitten jokaisen poistaminen on loogista, poistat yhden koodipisteen, kun painat " askelpalautinta " ja poista kaikki merkit, myös vovelit, kun painat " del ". Et kuitenkaan koskaan tuota laitonta tekstin tilaa – laitonta koodipistettä. Täten tilanne, kun painat askelpalautinta ja saat lukemattoman tekstin, on väärä.
- CiscoIPPhone: Jos virhe on " raportoitu useita kertoja, monet ihmiset " ja sitten pari vuotta myöhemmin kehittäjä kirjoittaa dev-blogiin, että " Uskokaa tai älkää, käyttäytyminen on enimmäkseen tarkoituksellista! ", sitten (lievästi sanottuna) minusta on tapana ajatella, että se ' ei todennäköisesti ole paras koskaan tehty suunnittelupäätös. 🙂 Vain siksi, että se ' tarkoituksellisesti ei tarkoita ' t tarkoita sitä ' ei vika.
- Loistava viesti. UTF-16 on todellakin " kummankin maailman pahin ": UTF8 on vaihtelevan pituinen, kattaa kaiken Unicoden, vaatii muunnosalgoritmin raakakoodipisteisiin ja niistä, rajoittuu ASCII: een, eikä sillä ole endianismiongelmia. UTF32 on kiinteän pituinen, ei vaadi muutosta, mutta vie enemmän tilaa ja sillä on endianiteettiongelmia. Toistaiseksi niin hyvä, että voit käyttää UTF32: ta sisäisesti ja UTF8: ta sarjoitukseen. Mutta UTF16: lla ei ole etuja: Se ' on riippuvainen endiineistä, se on ' muuttuvan pituinen, se vie paljon tilaa, se ' eivät ole ASCII-yhteensopivia. UTF16: n kunnolliseen käsittelyyn tarvittavat ponnistelut voidaan käyttää paremmin UTF8: een.
- @Ian: UTF-8 EI ole samoja varoituksia kuin UTF-8. Sinulla ei voi olla korvikkeita UTF-8: ssa. UTF-8 ei naamiota sellaisena kuin se ei ole, mutta useimmat UTF-16: ta käyttävät ohjelmoijat käyttävät sitä väärin. Tiedän. Olen ' katsellut heitä yhä uudestaan ja uudestaan ja uudestaan.
- Myös UTF-8 ei ' t on ongelma, koska kaikki käsittelevät sitä vaihtelevana koodauksena. UTF-16: n ongelman syynä on se, että jokainen kohtelee sitä kiinteän leveyden koodauksena.
Vastaa
Tämä on vanha vastaus.
Katso UTF-8 kaikkialla uusimmat päivitykset.
Mielipide: Kyllä, UTF-16: ta on pidettävä haitallisena . Juuri syy sen olemassaoloon johtuu siitä, että jokin aika sitten oli väärä uskomus, että widechar tulee olemaan sellainen kuin UCS-4 nyt on.
Huolimatta UTF-8: n ”anglikeskeisyydestä”, se tulisi pitää ainoana hyödyllisenä tekstin koodauksena. Voidaan väittää, että ohjelmien, verkkosivujen ja XML-tiedostojen lähdekoodeja, käyttöjärjestelmän tiedostojen nimiä ja muita tietokoneiden välisiä tekstirajapintoja ei olisi koskaan pitänyt olla. Mutta kun he tekevät, teksti ei ole vain ihmislukijoille.
Toisaalta UTF-8-yleiskustannukset ovat pieni hinta, vaikka sillä on merkittäviä etuja. Edut, kuten yhteensopivuus tiedostamattoman koodin kanssa, joka välittää vain merkkijonot char*
kanssa. Tämä on hieno asia. UTF-16: ssa on muutama hyödyllinen merkki, jotka ovat LYHYEMPI kuin UTF-8: ssa.
Uskon, että kaikki muut koodaukset kuolevat lopulta. Tähän liittyy MS-Windows, Java, ICU, python lopeta sen käyttäminen suosikkinsa. Pitkien tutkimusten ja keskustelujen jälkeen yritykseni kehityskäytännöt kieltävät UTF-16: n käytön missä tahansa paitsi käyttöliittymän sovellusliittymäkutsut, ja tämä tärkeydestä huolimatta suorituskykyä sovelluksissamme ja tosiasia, että käytämme Windowsia. Muunnostoiminnot kehitettiin muuntamaan aina oletetut UTF8 std::string
s alkuperäisiksi UTF-16, jotka Windows itse ei tue kunnolla .
Ihmisille, jotka sanovat ” käytä mitä tarvitaan missä tarvitaan ”, sanon: saman koodauksen käyttäminen kaikkialla on valtava etu, enkä näe riittävää syytä tee muuten. Erityisesti mielestäni wchar_t
lisääminen C ++: een oli virhe, samoin Unicoden lisäykset C ++ 0x: een. STL-toteutuksilta vaaditaan kuitenkin, että jokainen std::string
– tai char*
-parametri katsotaan unicode-yhteensopivaksi.
Vastustan myös ” use” mitä haluat ”-lähestymistapa. En näe mitään syytä tälle vapaudelle. Teksti-aiheeseen liittyy riittävästi sekaannusta, mikä johtaa tähän rikki ohjelmistoon. Edellä sanottuani olen vakuuttunut siitä, että ohjelmoijien on vihdoin päästävä yksimielisyyteen UTF-8: sta yhtenä oikeana tapana. (Olen kotoisin muusta kuin ascii-puhuvasta maasta ja vartuin Windowsissa, joten minun odotetaan viimeksi hyökkäävän UTF-16: een uskonnollisten syiden perusteella.
Haluaisin jakaa lisätietoja siitä, miten teen tekstiä Windowsissa, ja mitä suosittelen kaikille muille käännösajan tarkistamasta unicode-oikeellisuudesta, helppokäyttöisyydestä ja koodin monitasoisuudesta. Ehdotus eroaa huomattavasti siitä, mitä yleensä suositellaan oikeaan tapaan käyttää Unicodea Windowsissa. Näiden suositusten perusteellinen tutkimus johti kuitenkin samaan johtopäätökseen. Joten tässä:
- Älä käytä
wchar_t
taistd::wstring
missään muualla kuin viereisessä paikassa UTF-16: n hyväksyvät sovellusliittymät. - Älä käytä
_T("")
taiL""
UTF-16-literaaleja (nämä tulisi poistaa IMO: sta standardista , osana UTF-16-poistoa). - Älä käytä tyyppejä, funktioita tai niiden johdannaisia, jotka ovat herkkiä vakiolle
_UNICODE
, kutenLPTSTR
taiCreateWindow()
. - Silti
_UNICODE
määritelty aina vältächar*
-merkkijonojen siirtämistä WinAPI: lle, joka kääntyy hiljaa -
std::strings
jachar*
missä tahansa ohjelmassa katsotaan UTF-8: ksi (ellei toisin mainita) - Kaikki merkkijononi ovat
std::string
, vaikka voit välittää merkin * tai merkkijonon kirjaimelleconvert(const std::string &)
. -
käytä vain Win32-toimintoja, jotka hyväksyvät widecharit (
LPWSTR
). Koskaan niitä, jotka hyväksyvätLPTSTR
taiLPSTR
. Välitä parametrit tällä tavalla:::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str())
(Käytäntö käyttää alla olevia muunnostoimintoja.)
-
MFC-merkkijonoilla :
CString someoneElse; // something that arrived from MFC. Converted as soon as possible, before passing any further away from the API call: std::string s = str(boost::format("Hello %s\n") % Convert(someoneElse)); AfxMessageBox(MfcUtils::Convert(s), _T("Error"), MB_OK);
-
Tiedostojen, tiedostonimien ja suoratoiston käyttäminen Windowsissa:
- Älä koskaan siirrä
std::string
taiconst char*
tiedostonimen argumentitfstream
-perheeseen. MSVC STL ei tue UTF-8-argumentteja, mutta sillä on epätyypillinen laajennus, jota tulisi käyttää seuraavasti: -
Muunna
std::string
argumentitstd::wstring
jaUtils::Convert
:std::ifstream ifs(Utils::Convert("hello"), std::ios_base::in | std::ios_base::binary);
Meidän on tehtävä manuaalisesti poista muunnos, kun MSVC: n asenne
fstream
muuttuu. - Tämä koodi ei ole monialustainen, ja se on ehkä muutettava manuaalisesti tulevaisuus
- Lisätietoja on
fstream
unicode -tutkimus- / keskustelutapauksessa 4215. - Älä koskaan tuota tekstitulostustiedostoja, joiden sisältö ei ole UTF8
- Vältä
fopen()
käyttöä RAII / OOD-syistä. Käytä tarvittaessa_wfopen()
ja WinAPI-käytäntöjä yllä.
- Älä koskaan siirrä
// For interface to win32 API functions std::string convert(const std::wstring& str, unsigned int codePage /*= CP_UTF8*/) { // Ask me for implementation.. ... } std::wstring convert(const std::string& str, unsigned int codePage /*= CP_UTF8*/) { // Ask me for implementation.. ... } // Interface to MFC std::string convert(const CString &mfcString) { #ifdef UNICODE return Utils::convert(std::wstring(mfcString.GetString())); #else return mfcString.GetString(); // This branch is deprecated. #endif } CString convert(const std::string &s) { #ifdef UNICODE return CString(Utils::convert(s).c_str()); #else Exceptions::Assert(false, "Unicode policy violation. See W569"); // This branch is deprecated as it does not support unicode return s.c_str(); #endif }
kommentit
- en voi ' olla samaa mieltä. Usean aasialaisen kielen utf16: n edut utf8: een hallitsevat täysin antamiasi pisteitä. On naiivia toivoa, että japanilaiset, thaimaalaiset, kiinalaiset jne. Luopuvat tästä koodauksesta. Merkkisarjojen väliset ongelmalliset ristiriidat ovat silloin, kun merkinnät näyttävät enimmäkseen samanlaisilta, lukuun ottamatta eroja. Ehdotan standardointia: kiinteä 7-bittinen: iso-irv-170; 8-bittinen muuttuja: utf8; 16-bittinen muuttuja: utf16; 32-bittinen kiinteä: ucs4.
- @Charles: kiitos panoksestasi. Totta, jotkut BMP-merkit ovat pidempiä UTF-8: ssa kuin UTF-16: ssa. Mutta olkoon ' s kohdattava se: ongelma ei ole tavuissa, jotka BMP-kiinalaiset merkit ottavat, vaan syntyvä ohjelmistosuunnittelun monimutkaisuus. Jos kiinalaisen ohjelmoijan on joka tapauksessa suunniteltava muuttuvapituisia merkkejä, näyttää siltä, että UTF-8 on edelleen pieni hinta maksettavaksi verrattuna muihin järjestelmän muuttujiin. Hän voi käyttää UTF-16: ta pakkausalgoritmina, jos tila on niin tärkeä, mutta silloinkin se ei sovi LZ: lle, ja LZ: n tai muun yleisen pakkauksen jälkeen molemmat vievät suunnilleen saman kokoisen ja entropian.
- Pohjimmiltaan sanon, että yksinkertaistamista, jonka tarjoaa One-koodaus, joka on myös yhteensopiva olemassa olevien char * -ohjelmien kanssa ja joka on myös suosituin kaikessa, ei voida kuvitella.Se on melkein kuin vanhojen hyvien " tavallinen teksti ". Haluatko avata tiedoston nimeltä? Sinun ei tarvitse huolehtia siitä, minkä tyyppistä unicodea teet jne. Jne. Ehdotan, että kehittäjät rajoittavat UTF-16: n vain erityisiin vakavan optimoinnin tapauksiin, joissa pieni suorituskyky on ihmiskuukausien arvoinen.
- Linuxilla on ollut erityinen vaatimus UTF-8: n sisäisestä käytöstä: yhteensopivuus Unixin kanssa. Windows ei tarvinnut sitä, ja kun kehittäjät ottivat Unicoden käyttöön, he lisäsivät UCS-2-versiot melkein kaikista tekstin käsittelytoiminnoista ja saivat monitavuiset yksinkertaisesti muuntamaan UCS-2: ksi ja soita muille. THey korvaa myöhemmin UCS-2: n UTF-16: lla. Toisaalta Linux piti 8-bittisiä koodauksia ja käytti siten UTF-8: ta, koska se ' on siinä tapauksessa oikea valinta.
- @Pavel Radzivilovsky : BTW, kirjoituksesi ": stä uskon, että kaikki muut koodaukset kuolevat lopulta. Tämä edellyttää, että MS-Windows, Java, ICU, python lopettavat sen käytön suosikkinsa. " ja " Erityisesti mielestäni wchar_t: n lisääminen C ++: een oli virhe, ja niin ovat myös C ++ Oxin unicode-lisäykset. " ovat joko melko naiiveja tai erittäin ylimielisiä . Ja tämä tulee jokulta, joka koodaa kotona Linuxilla ja joka on tyytyväinen UTF-8-merkkeihin. Suoraan sanottuna: Se ei voitu ' ei tapahdu .
Vastaa
Unicode-koodipisteet eivät ole merkkejä! Joskus ne eivät ole edes kuviot (visuaaliset muodot) .
Joitakin esimerkkejä:
- roomalaiset numerokoodipisteet, kuten ”ⅲ”. (Yksittäinen merkki, joka näyttää ”iii”.)
- Aksenttimerkit, kuten ”á”, jotka voidaan esittää joko yhtenä yhdistelmämerkkinä ”\ u00e1” tai merkkinä ja erotettuna diakriittisenä merkkinä ”\ u0061 \” u0301 ”.
- Hahmot, kuten kreikkalaiset pienet sigmat, joilla on eri muodot sana-asemien keskelle (” σ ”) ja loppuun (” ς ”), mutta joita on pidettävä haun synonyymeinä.
- Unicoden vapaaehtoinen yhdysviiva U + 00AD, joka saattaa olla tai ei välttämättä näkyä visuaalisesti kontekstista riippuen ja joka jätetään huomiotta semanttisessa haussa.
Ainoa tapa saada Unicode-muokkaus oikea on käyttää asiantuntijan kirjoittamaa kirjastoa , tai tulla asiantuntijaksi ja kirjoittaa se itse. Jos lasket vain koodipisteitä, asut synnin tilassa.
Kommentit
- Tämä. Paljon tätä. UTF-16 voi aiheuttaa ongelmia, mutta jopa koko UTF-32: n käyttö voi (ja tulee) aiheuttamaan sinulle ongelmia.
- Mikä merkki on? Voit määrittää koodipisteen merkiksi ja tulla toimeen melko hyvin. Jos tarkoitat käyttäjän näkyvää kuviota, se on jotain muuta.
- @tristus varma varaamaan tilaa, tämä määritelmä on hieno, mutta jos jotain muuta? Ei niin paljon. Jos käsittelet yhdistävää merkkiä ainoana merkkinä (ts. Poistaaksesi tai " ota ensimmäiset N merkkiä "), ' käy outoa ja väärää käyttäytymistä. Jos koodikohdalla on merkitys vain yhdistettynä ainakin toiseen, et voi ' t käsitellä sitä yksinään järkevällä tavalla.
- @Pacerier, tämä on myöhässä juhliin, mutta minun on kommentoitava sitä. Joillakin kielillä on hyvin suuret joukot mahdollisia diakriitikoiden yhdistelmiä (vrt. Vietnam, ts. Mệt đừ). Yhdistelmien käyttäminen pikemminkin kuin yhden merkin kohdalla diakritikoita on erittäin hyödyllistä.
- pieni huomautus terminologiasta: koodipisteet eivät vastaa unicode-merkkejä ; mitä Daniel puhuu tässä, ovat käyttäjän havaitsemia merkkejä , jotka vastaavat unicode-grafeemiklustereita
Vastaa
On olemassa yksinkertainen nyrkkisääntö siitä, mitä Unicode Transformation Formia (UTF) käytetään: – utf-8 tallennukseen ja viestintään – utf-16 tietojenkäsittelyyn – saatat mennä utf-32: n kanssa, jos suurin osa käyttämästäsi alustan sovellusliittymästä on utf-32 (yleinen UNIX-maailmassa).
Useimmat järjestelmät käyttävät nykyään utf-16: ta (Windows, Mac OS, Java, .NET, ICU (Qt). Katso myös tämä asiakirja: http://unicode.org/notes/tn12/
Takaisin sivulle UTF-16 haitallisena, Sanon: ehdottomasti ei.
Ihmiset, jotka pelkäävät korvikkeita (ajattelevat muuttavansa Unicoden muuttuvan pituiseksi koodaukseksi), eivät ymmärrä muita (tavallista isompia) monimutkaisuuksia, jotka tekevät merkkien ja a Unicode-koodipiste on hyvin monimutkainen: yhdistämällä merkkejä, ligatuureja, muunnelvalitsimia, kontrollimerkkejä jne.
Lue tämä sarja täältä http://www.siao2.com/2009/06/29/9800913.aspx ja katso kuinka UTF-16: sta tulee helppo ongelma.
kommentit
- Lisää esimerkkejä, joissa UTF-32 on yleinen UNIX-maailmassa!
- Ei, et haluat käyttää UTF-16: ta tietojenkäsittelyyn. Se ' on kipu perseeseen. Siinä on kaikki UTF-8: n haitat, mutta mikään sen eduista. Sekä UTF-8 että UTF-32 ovat selvästi parempia kuin aikaisemmin Mrs UTF-16: ksi kutsutun ilkeä hakkerointi, jonka tyttönimi oli UCS-2.
- Löysin eilen virheen Java core String -luokasta
equalsIgnoreCase
-menetelmä (myös muut merkkijonoluokassa), jota ei olisi koskaan ollut siellä, Java olisi käyttänyt joko UTF-8: ta tai UTF-32: ta. Miljoonia näitä nukkuvia pommeja on missään koodissa, joka käyttää UTF-16: ta, ja olen niistä kyllästynyt ja kyllästynyt. UTF-16 on ilkeä rokka, joka vaivaa ohjelmistojamme salakavalilla virheillä ikuisesti ja ikuisesti. Se on selvästi haitallinen, ja se on poistettava käytöstä ja kiellettävä. - @tchrist Wow niin ei-korvike tietoinen toiminto (koska se kirjoitettiin silloin, kun sellaisia ei ollut, ja se on valitettavasti dokumentoitu tavalla, joka tekee siitä todennäköisesti mahdotonta sopeutua – se määrittelee .toUpperCase (char)) johtaa väärään käyttäytymiseen? ' tiedät uudelleen, että UTF-32-funktio, jossa on vanhentunut koodipistekartta, ei käsitteleisi tätä paremmin? ' Myös koko Java-sovellusliittymä ei käsittele korvikkeita erityisen hyvin, ja monimutkaisemmat kohdat Unicodesta eivät lainkaan – ja myöhemmin käytetyllä koodauksella ei ole merkitystä.
- -1: Ehdollinen
.Substring(1)
.NETissä on triviaali esimerkki jostakin, joka katkaisee tuen kaikille muille kuin BMP-Unicodeille. Kaikella joka käyttää UTF-16: ta, on tämä ongelma; ' on liian helppoa käsitellä sitä kiinteän leveyden koodauksena, ja ongelmia esiintyy liian harvoin. Se tekee siitä aktiivisesti haitallisen koodauksen, jos haluat tukea Unicodea.
Vastaa
Kyllä, ehdottomasti.
Miksi? Se liittyy koodin käyttämiseen .
Jos tarkastelet näitä koodipisteen käyttötilastoja suuressa korpusessa Tom Christiansen, ”huomaat, että 8-bittisiä BMP-koodipisteitä käytetään useita kertoja, jos suuruusluokkaa on enemmän kuin ei-BMP-koodipisteitä:
2663710 U+002013 ‹–› GC=Pd EN DASH 1065594 U+0000A0 ‹ › GC=Zs NO-BREAK SPACE 1009762 U+0000B1 ‹±› GC=Sm PLUS-MINUS SIGN 784139 U+002212 ‹−› GC=Sm MINUS SIGN 602377 U+002003 ‹ › GC=Zs EM SPACE 544 U+01D49E ‹𝒞› GC=Lu MATHEMATICAL SCRIPT CAPITAL C 450 U+01D4AF ‹𝒯› GC=Lu MATHEMATICAL SCRIPT CAPITAL T 385 U+01D4AE ‹𝒮› GC=Lu MATHEMATICAL SCRIPT CAPITAL S 292 U+01D49F ‹𝒟› GC=Lu MATHEMATICAL SCRIPT CAPITAL D 285 U+01D4B3 ‹𝒳› GC=Lu MATHEMATICAL SCRIPT CAPITAL X
Ota TDD-sanelu: ”Testaamaton koodi on rikki koodi” ja muotoile se uudelleen käyttämättömänä koodina rikkinäisenä koodina. Ajattele kuinka usein ohjelmoijien on käsiteltävä muita kuin BMP-koodipisteitä.
Virheet, jotka liittyvät UTF-16: n puuttumiseen muuttuvan leveyden koodauksena, jäävät paljon todennäköisemmin huomaamatta kuin vastaavat virheet UTF-8: ssa . Jotkut ohjelmointikielet ovat edelleen Älä takaa, että saat UTF-16: n UCS-2: n sijaan, ja jotkut ns. korkean tason ohjelmointikielet tarjoavat pääsyn koodiyksiköihin koodipisteiden sijaan (jopa C: n oletetaan antavan sinulle pääsyn koodipisteisiin, jos käytät wchar_t
riippumatta siitä, mitä jotkut levyt lomakkeet voivat tehdä.).
Kommentit
- " Virheet, jotka liittyvät UTF-16 vaihtelevan leveyden koodaus jää huomattavasti todennäköisemmin huomaamatta kuin vastaavat virheet UTF-8: ssa. " Tämä on ongelman ydin ja siten oikea vastaus.
- Tarkalleen. Jos UTF-8-käsittelysi on tukossa, se ' on heti ilmeinen. Jos UTF-8-käsittelysi on tukossa, ' huomaat vain, jos laitat harvinaisia han-merkkejä tai matematiikkasymboleja.
- Erittäin totta, mutta toisaalta toisaalta, mitkä ovat yksikötestit, jos sinun pitäisi riippua onnesta löytääksesi virheitä harvinaisemmissa tapauksissa?
- @musiphil: niin, milloin viimeksi loit yksikötestin muille kuin BMP-merkkeille?
- Aiemman lausunnon tarkentaminen: Jopa UTF-8: n kanssa, et voi olla varma, että olet katsonut kaikki tapaukset nähtyäsi vain joitain toimivia esimerkkejä. Sama UTF-16: n kanssa: sinun on testattava, toimiiko koodisi sekä korvaamattomien että korvaavien kanssa. (Joku voisi jopa väittää, että UTF-8: lla on ainakin neljä suurta tapausta, kun taas UTF-16: lla on vain kaksi.)
Vastaa
Ehdotan, että ajattelua UTF-16: sta voidaan pitää haitallisena, mikä tarkoittaa, että sinun on ymmärrettävä paremmin unicode .
Koska minua on aliarvioitu esittämästä mielipiteeni subjektiivisesta kysymyksestä, anna minun tarkentaa. Mikä juuri häiritsee sinua UTF-16: ssa? Haluatko mieluummin, jos kaikki koodattaisiin UTF-8: een? UTF-7: een? Entä UCS-4? Tietysti tiettyjä sovelluksia ei ole suunniteltu käsittelemään yhden merkkikoodin olemassaoloa – mutta ne ovat välttämättömiä etenkin nykypäivän globaalissa informaatioalueessa, kansainvälisten rajojen väliseen viestintään.
Mutta todellakin, jos sinusta tuntuu, että UTF-16: ta tulisi pitää haitallisena, koska se on hämmentävää tai se voidaan toteuttaa väärin (unicode voi varmasti olla), minkä tyyppistä merkkikoodausta ei pidetä haitallisena?
MUOKKAA: Selvennys: Miksi standardin virheellistä toteutusta pidetään itse standardin laadun heijastuksena? Kuten muut ovat myöhemmin huomauttaneet, se, että sovellus käyttää työkalua väärin, ei tarkoita, että työkalu itsessään on viallinen. Jos näin olisi, voisimme todennäköisesti sanoa esimerkiksi ”var avainsana pidetään haitallisena” tai ”ketjuttaminen pidetään haitallisena”. Luulen, että kysymys sekoittaa standardin laadun ja luonteen vaikeuksiin, joita monilla ohjelmoijilla on toteutuksessa ja käyttää sitä oikein, mikä mielestäni johtuu pikemminkin siitä, että he eivät ymmärrä, miten unicode toimii, eikä itse unicode.
Kommentit
- -1: Entä puhuminen joihinkin Artyom ' -objekteihin eikä pelkästään holhota häntä?
- BTW: Kun aloitin tämän artikkelin kirjoittamisen, halusin melkein kirjoittaa " Pitäisikö Joelia pitää harkita Unicoden Softeare-artikkelissa? haitallinen ", koska virheitä on paljon. Esimerkiksi: utf-8-koodaus vie enintään 4 merkkiä eikä 6. Ei myöskään tehdä eroa UCS-2: n ja UTF-16: n välillä, jotka ovat todella erilaisia – ja aiheuttavat itse asiassa ongelmia, joista puhun.
- On myös huomattava, että kun Joel kirjoitti kyseisen artikkelin, UTF-8-standardi oli WAS 6 tavua, ei 4. RFC 3629 muutti standardin 4 tavuksi useita kuukausia sen jälkeen, kun hän kirjoitti artikkelin. Kuten useimmat muutkin Internetissä, kannattaa lukea useammasta kuin yhdestä lähteestä ja olla tietoinen lähteiden iästä. Linkin ei ollut ' t tarkoitus olla " loppu kaikki ", mutta pikemminkin lähtökohta.
- Haluaisin kuvata: utf-8 tai utf-32, jotka ovat: vaihtelevan pituinen koodaus lähes kaikissa tapauksissa (mukaan lukien BMP) tai kiinteän pituinen koodaus aina.
- @iconiK: Älä ole typerä. UTF-16 ei todellakaan ole de facto standardi tekstin käsittelyyn. Näytä minulle ohjelmointikieli, joka soveltuu paremmin tekstinkäsittelyyn kuin Perl, joka on aina (hyvin, yli vuosikymmen) käytti abstrakteja merkkejä, joiden taustalla oli UTF-8-esitys sisäisesti. Tämän vuoksi jokainen Perl-ohjelma käsittelee automaattisesti kaikki Unicode-koodit ilman, että käyttäjän tarvitsee jatkuvasti apinoida idioottisten korvikkeiden kanssa. Merkkijonon pituus on sen määrä koodipisteissä, ei koodiyksiköissä. Kaikki muu on pelkkää tyhmyyttä, joka asettaa taaksepäin yhteensopivuuden taaksepäin.
Vastaa
Utf- 16 koodaus. Mutta kieliä, jotka käsittelevät 16-bittisiä yksiköitä hahmoina, tulisi todennäköisesti pitää huonosti suunniteltuina. On melko hämmentävää, että sinulla on tyyppi nimeltä ”div div = = 02b823509f”>
”, joka ei aina edusta merkkiä. Koska useimmat kehittäjät odottavat, että merkityyppi edustaa koodipistettä tai merkkiä, suuri osa koodista todennäköisesti rikkoutuu, kun se altistetaan hahmoille, paitsi BMP.
Huomaa kuitenkin, että edes utf-32: n käyttö ei tarkoita, että kukin 32- bittikoodipiste edustaa aina merkkiä. Merkkien yhdistämisen vuoksi todellinen merkki voi koostua useista koodipisteistä. Unicode ei ole koskaan triviaali.
BTW. Luultavasti on sama luokkavirhe alustoilla ja sovelluksilla, jotka odottavat merkkien olevan 8-bittisiä, ja syötetään Utf-8: lle.
Kommentit
- Jos Java ' -tapauksissa tarkastellaan heidän aikajanaa ( java.com/en/javahistory/timeline.jsp), näet, että Stringin pääasiallinen kehitys tapahtui, kun Unicode oli 16 bittiä (se muuttui vuonna 1996). Heidän piti kiinnittää kyky käsitellä muita kuin BMP-koodipisteitä, mikä aiheuttaa sekaannusta.
- @Kathy: Ei kuitenkaan oikeastaan tekosyy C #: lle. Yleensä olen samaa mieltä siitä, että on oltava
CodePoint
-tyyppi, jolla on yksi koodipiste (21 bittiä),CodeUnit
-tyyppi, yhden koodin yksikön (16 bittiä UTF-16: lle) jaCharacter
-tyypin olisi ihanteellisessa tapauksessa tuettava täydellistä grafemia. Mutta se tekee toiminnallisesti vastaavanString
… - Tämä vastaus on melkein kaksi vuotta vanha, mutta voin ' t auta, mutta kommentoi sitä. " Tyyppi nimeltä ' char ', joka ei aina kuvaa merkkiä, on kaunis sekava. " Ja silti ihmiset käyttävät sitä koko ajan C: ssä ja vastaavissa edustamaan kokonaislukutietoja, jotka voidaan tallentaa yhteen tavuun.
- Ja I ' olet nähnyt erän C-koodia, joka ei käsittele ' t merkkien koodausta oikein.
- C #: llä on erilainen tekosyy: se on suunniteltu Windowsille ja Windows rakennettiin UCS-2: lle (se ' ärsyttää hyvin, että nykyäänkin Windows-sovellusliittymät eivät voi tuki UTF-8). Lisäksi luulen, että Microsoft halusi Java-yhteensopivuuden (.NET 1.0: lla oli Java-yhteensopivuuskirjasto, mutta ne pudottivat Java-tuen hyvin nopeasti – luulen, että tämä johtuu Sun ' oikeusjuttu MS: tä vastaan?)
Vastaa
Oma valintani on aina käyttää UTF-8. Se on melkein kaiken standardi Linuxissa. Se on taaksepäin yhteensopiva monien vanhojen sovellusten kanssa. Muilla kuin latinalaisilla merkeillä käytetyn ylimääräisen tilan suhteen on hyvin vähän lisämääriä verrattuna muihin UTF-muotoihin, ja latinankielisten merkkien tilaa säästetään huomattavasti. Verkossa latinankielet hallitsevat korkeinta, ja mielestäni ne tulevat lähitulevaisuudessa. Ja vastaamaan yhteen tärkeimmistä argumenteista alkuperäisessä viestissä: melkein jokainen ohjelmoija on tietoinen siitä, että UTF-8: ssa on joskus monitavuisia merkkejä. Kaikki eivät käsittele tätä oikein, mutta he ovat yleensä tietoisia, mikä on enemmän kuin voidaan sanoa UTF-16: sta. Mutta tietysti sinun on valittava sovelluksellesi sopivin. Siksi aluksi on enemmän kuin yksi.
Kommentit
- UTF-16 on yksinkertaisempi kaikelle BMP: n sisällä, että ' s miksi sitä käytetään niin laajasti. Mutta olen ' myös UTF-8: n fani, sillä ei myöskään ole ongelmia tavujärjestyksessä, mikä toimii sen eduksi.
- Teoreettisesti kyllä. Käytännössä on esimerkiksi UTF-16BE, mikä tarkoittaa UTF-16: ta suuressa endiassa ilman BOM: ää. Tämä ei ole jotain, jonka olen keksinyt, tämä on todellinen koodaus, joka on sallittu ID3v2.4-tunnisteissa (ID3v2-tunnisteet imevät, mutta ovat valitettavasti laajalti käytössä). Ja tällaisissa tapauksissa joudut määrittelemään endianisyyden ulkoisesti, koska itse teksti ei sisällä ' ei BOM: ää. UTF-8 kirjoitetaan aina yhdellä tavalla, eikä sillä ole ' tällaista ongelmaa.
- Ei, UTF-16 ei ole yksinkertaisempi. Se on vaikeampi. Se johtaa harhaan ja pettää sinut ajattelemaan, että se on kiinteä. Kaikki tällainen koodi on rikki ja kaikki moreso, koska et huomaa ennen kuin on liian myöhäistä. CASE IN POINT: Löysin eilen jälleen yhden tyhmän UTF-16-virheen Java-ydinkirjastoista, tällä kertaa String.equalsIgnoreCase -ohjelmassa, joka jätettiin UCS-2-buggeryn alapuolelle ja epäonnistui siten 16/17 kelvollisessa Unicode-koodipisteessä. Kuinka kauan koodi on ollut käytössä? Ei tekosyy sille, että se on buginen. UTF-16 johtaa pelkkään tyhmyyteen ja onnettomuuteen, joka odottaa tapahtumista. Suorita huutaminen UTF-16: sta.
- @tchrist Yksi on oltava hyvin tietämätön kehittäjä, jotta hän ei tiedä, että UTF-16 ei ole kiinteä pituus. Jos aloitat Wikipediasta, lue seuraava yläreunasta: " Se tuottaa vaihtelevan pituisen tuloksen joko yhdestä tai kahdesta 16-bittisestä koodiyksiköstä koodipistettä kohti ". Unicode FAQ: ssä sanotaan sama: unicode.org/faq//utf_bom.html#utf16-1 . En tiedä ' en tiedä, kuinka UTF-16 voi pettää ketään, jos kaikkialla on kirjoitettu, että se on vaihteleva pituus. Menetelmää varten sitä ei ole koskaan suunniteltu UTF-16: lle, eikä sitä pidä pitää ' ei pidetä yksinkertaisena Unicode-muodossa.
- @tchrist Onko sinulla lähde tilastoihisi? Vaikka hyviä ohjelmoijia onkin vähän, mielestäni tämä on hyvä, koska meistä tulee arvokkaampia. 🙂 Java-sovellusliittymien osalta char-pohjaiset osat saattavat lopulta vanhentua, mutta tämä ei takaa, että niitä ei käytetä '. Ja he ehdottomasti eivät voittaneet ' poistamista yhteensopivuussyistä.
Vastaus
No, on olemassa koodaus, joka käyttää kiinteäkokoisia symboleja. Tarkoitan varmasti UTF-32: ta. Mutta 4 tavua jokaiselle symbolille on liian paljon hukkaan menevää tilaa, miksi käytämme sitä jokapäiväisissä tilanteissa?
Mielestäni suurin osa ongelmista ilmenee siitä, että jotkut ohjelmistot putosivat Unicode-standardin takana, mutta eivät onnistuneet nopeasti korjaamaan tilannetta. Opera, Windows, Python, Qt – kaikki ne ilmestyivät ennen kuin UTF-16 tuli tunnetuksi tai jopa syntyi. Voin kuitenkin vahvistaa, että Operassa, Windows Explorerissa ja Muistiossa ei ole enää ongelmia BMP: n ulkopuolella olevien hahmojen kanssa (ainakin tietokoneellani). Mutta joka tapauksessa, jos ohjelmat eivät tunnista korvaavia pareja, ne eivät käytä UTF-16: ta. Riippumatta ongelmista, jotka aiheutuvat tällaisten ohjelmien käsittelystä, niillä ei ole mitään tekemistä itse UTF-16: n kanssa.
Uskon kuitenkin, että vanhojen ohjelmistojen ongelmat, joilla on vain BMP-tuki, ovat hieman liioiteltuja. BMP: n ulkopuolella olevat hahmot kohtaavat vain hyvin erityisissä tapauksissa ja alueilla. Unicoden virallisen usein kysytyn kysymyksen mukaan ”jopa Itä-Aasian tekstissä korvaavien parien esiintyvyyden tulisi olla selvästi alle 1% kaikesta tekstivarastosta keskimäärin”.Tietysti BMP: n ulkopuolella olevia merkkejä ei pidä laiminlyödä , koska ohjelma ei muuten ole Unicode-yhteensopiva, mutta useimpia ohjelmia ei ole tarkoitettu työskentelemään tällaisia merkkejä sisältävien tekstien kanssa. Siksi ”jos ne eivät” Se ei tue sitä, se on epämiellyttävää, mutta ei katastrofia.
Tarkastellaan nyt vaihtoehtoa. Jos UTF-16: ta ei ole olemassa, meillä ei ole koodausta, joka sopii hyvin ei-ASCII-tekstille, ja kaikki UCS-2: lle luodut ohjelmistot olisi suunniteltava kokonaan uudelleen, jotta ne pysyisivät Unicode-yhteensopivina. Jälkimmäinen todennäköisesti vain hidastaa Unicoden käyttöönottoa. Emme olisi myöskään pystyneet ylläpitämään yhteensopivuutta tekstin kanssa UCS-2: ssa, kuten UTF-8 tekee ASCII: n suhteen.
Nyt kun jätetään sivuun kaikki vanhat ongelmat, mitkä ovat argumentit koodausta vastaan Itse epäilen, että kehittäjät eivät nykyään tiedä, että UTF-16 on vaihtelevan pituinen, se on kirjoitettu kaikkialla Wikipedian kanssa. UTF-16: n jäsentäminen on paljon vähemmän vaikeaa kuin UTF-8: n, jos joku mainitsi monimutkaisuuden mahdollisena ongelmana. On myös väärin ajatella, että merkkijonon pituuden määrittäminen on helppoa vain UTF-16: ssa. Jos käytät UTF-8: ta tai UTF-32: ta, sinun tulee silti olla tietoinen siitä, että yksi Unicode-koodipiste ei välttämättä tarkoita yhtä merkkiä. Sen lisäksi en usko, että koodauksessa on mitään merkittävää.
Siksi en usko, että itse koodausta pitäisi pitää haitallisena. UTF-16 on kompromissi yksinkertaisuuden ja kompaktiuden välillä, eikä siitä ole haittaa, kun käytetään tarvitsemaansa missä tarvitaan Joissakin tapauksissa sinun on pysyttävä yhteensopivana ASCII: n kanssa ja tarvitset UTF-8: n, joissakin tapauksissa haluat työskennellä Han-ideografien kanssa ja säästää tilaa UTF-16: n avulla, joissakin tapauksissa tarvitaan yleisiä merkkien esityksiä kiinnittämällä kiinteä -pituuskoodaus. Käytä mitä sopivampaa, vain tee se oikein.
Kommentit
- Että ' on melko välkkyvä, anglo-keskitetty näkymä, Malcolm. Lähes parin tasolla " kanssa ASCII on tarpeeksi hyvä Yhdysvalloille – muun maailman tulisi sopia kanssamme ".
- Itse olen ' m Venäjältä ja kohtaan kyrillisiä koko ajan (mukaan lukien omat ohjelmani), joten en ' Luulen, että minulla on anglokeskeinen näkemys. 🙂 ASCII: n mainitseminen ei ole aivan tarkoituksenmukaista, koska se ' ei ole Unicode eikä tue ' t tiettyjä merkkejä. UTF-8, UTF-16, UTF-32 tukevat samoja kansainvälisiä merkistöjä, ne on tarkoitettu vain käytettäviksi omilla alueillaan. Ja tämä on täsmälleen minun mielipiteeni: jos käytät enimmäkseen englantia, käytä UTF-8: ta, jos enimmäkseen kyrillisiä, käytä UTF-16: tä, jos käytät muinaisia kieliä, käytä UTF-32: ta. Melko yksinkertainen.
- " Ei totta, myös aasialaiset skriptit, kuten japani, kiina tai arabia, kuuluvat BMP: hen. Itse BMP on todella suuri ja varmasti riittävän suuri sisällyttämään kaikki nykyään käytetyt skriptit " Kaikki on niin väärin. BMP sisältää 0xFFFF merkkiä (65536). Pelkästään kiinalaisella on enemmän. Kiinan standardeilla (GB 18030) on enemmän. Unicode 5.1 on jo varannut yli 100 000 merkkiä.
- @Marcolm: " Itse BMP on todella suuri ja varmasti riittävän suuri sisällyttämään kaikki nykyään käytetyt skriptit " Ei totta. Tässä vaiheessa Unicode on jo varannut noin 100 kt merkkiä, enemmän kuin BMP voi majoittaa. BMP: n ulkopuolella on suuria kiinalaisia merkkejä. Ja jotkut niistä vaaditaan GB-18030 (pakollinen kiinalainen standardi). Muut vaativat (ei-pakolliset) japanilaiset ja korealaiset standardit. Joten jos yrität myydä mitään noilla markkinoilla, tarvitset BMP-tuen lisäksi.
- Kaikki, joka käyttää UTF-16: ta, mutta pystyy käsittelemään vain kapeita BMP-merkkejä, ei oikeastaan käytä UTF-16: ta. Se on buginen ja rikki. OP: n lähtökohta on järkevä: UTF-16 on haitallinen, koska se saa na ï ve ihmisiä kirjoittamaan rikkinäisen koodin. Voit joko käsitellä Unicode-tekstiä tai et. Jos et pysty, valitset alijoukon, joka on yhtä tyhmä kuin vain ASCII-tekstinkäsittely.
Vastaa
Vuosien Windows-kansainvälistyminen erityisesti Itä-Aasian kielillä on saattanut korruptoida minut, mutta olen taipuvainen UTF-16: een merkkijonojen sisäisten ohjelmien esitysten osalta ja UTF-8: n selkeiden tekstien verkko- tai tiedostotallennukseen. kuten asiakirjat. UTF-16 voidaan kuitenkin yleensä käsitellä nopeammin Windowsissa, joten se on ensisijainen hyöty UTF-16: n käytöstä Windowsissa.
Siirtyminen UTF-16: een paransi dramaattisesti keskimääräisen tuotteiden käsittelyn riittävyyttä. kansainvälinen teksti.On vain muutamia kapeita tapauksia, joissa korvausparit on otettava huomioon (poistot, lisäykset ja rivinvaihto, periaatteessa), ja keskimääräinen tapaus on enimmäkseen suora läpikulku. Ja toisin kuin aikaisemmat koodaukset, kuten JIS-muunnokset, UTF-16 rajoittaa korvaavat parit hyvin kapealle alueelle, joten tarkistus on todella nopeaa ja toimii eteenpäin ja taaksepäin.
Myönnetty, se on suunnilleen yhtä nopea oikein – koodattu myös UTF-8. Mutta on myös monia rikki UTF-8 -sovelluksia, jotka koodaavat väärin korvaajaparit kahtena UTF-8-sekvenssinä. Joten UTF-8 ei myöskään takaa pelastusta.
IE käsittelee korvaavia pareja kohtuullisen hyvin vuodesta 2000 lähtien, vaikka se yleensä muuntaa ne UTF-8-sivuista sisäiseksi UTF-16-esitykseksi; I ”Olen melko varma, että myös Firefox on saanut sen oikein, joten en välitä siitä, mitä Opera tekee.
UTF-32 (alias UCS4) on hyödytön useimmissa sovelluksissa, koska se on niin tilaa vievä, joten se on melkein ei-käynnistys.
Kommentit
- En saanut ' en saanut kommentoi UTF-8- ja korvausparia. Korvausparit ovat vain käsite, jolla on merkitystä UTF-16-koodauksessa, eikö? Ehkä koodi, joka muuntaa suoraan UTF-16-koodauksesta UTF-8-koodaukseksi, saattaa saada tämän väärin, ja siinä tapauksessa ongelma on UTF-16: n väärä lukeminen, ei UTF-8: n kirjoittaminen. Onko totta?
- Mitä Jason ' puhuu, on ohjelmisto toteuttaa tarkoituksella UTF-8: n siten: luo korvaava pari ja sitten UTF-8 fi koodaa molemmat puolikkaat erikseen. Koodauksen oikea nimi on CESU-8, mutta Oracle (esim.) Esittää sen väärin nimellä UTF-8. Java käyttää samanlaista mallia objektien sarjoitukseen, mutta se ' dokumentoidaan selvästi nimellä " Muokattu UTF-8 " ja vain sisäiseen käyttöön. (Nyt, jos saisimme vain ihmiset lukemaan nämä asiakirjat ja lopettamaan DataInputStream # readUTF (): n ja DataOutputStream # writeUTF (): n käyttämisen väärin …)
- AFAIK, UTF-32 on edelleen vaihtelevan pituinen koodaus, ja ei ole yhtä suuri kuin UCS4, joka on tietty koodipistealue.
- @Eonil, UTF-32 voidaan aina erottaa UCS4: stä vain, jos meillä on Unicode-standardi, joka sisältää jotain UCS5: n tai suurempaa.
- @JasonTrue Silti vain tulokset ovat yhtä suuret sattumalta, joita suunnittelu ei takaa. Sama tapahtui 32-bittisessä muistiosoitteessa, Y2K, UTF16 / UCS2. Vai onko meillä mitään takeita tasa-arvosta? Jos meillä on, käytän sitä mielelläni. Mutta en halua ' halua kirjoittaa mahdollista rikkoutuvaa koodia. Kirjoitan merkkitason koodia, ja taatun tavan puuttua koodaamiseen UTF < – > -koodipisteen välillä on vikaa minulle paljon .
vastaus
UTF-8 on ehdottomasti oikea tapa edetä, mahdollisesti mukana UTF-32 sisäiseen käyttöön Käytä algoritmeissa, jotka tarvitsevat korkean suorituskyvyn satunnaista pääsyä (mutta jättävät huomiotta merkkien yhdistämisen).
Sekä UTF-16 että UTF-32 (samoin kuin niiden LE / BE-muunnokset) kärsivät lopullisuudesta, joten heidän pitäisi Älä koskaan käytä ulkoisesti.
Kommentit
- Jatkuva ajallinen satunnainen käyttö on mahdollista myös UTF-8: n kanssa, käytä vain koodiyksiköitä koodipisteiden sijaan. Ehkä tarvitset todellista satunnaiskoodipisteen käyttöä, mutta en ' ole koskaan nähnyt käyttötapausta, ja sinä ' haluat yhtä todennäköisesti sen sijaan satunnainen grafemiryhmä.
Vastaa
UTF-16? ehdottomasti haitallista. Tässä on vain suolainen suolani, mutta ohjelmassa on täsmälleen kolme hyväksyttävää koodausta tekstille:
- ASCII: kun käsitellään matalan tason asioita (esim. Mikro-ohjaimia), joilla ei ole varaa parempaan
- UTF8: tallennus kiinteän levyisiin tietovälineisiin, kuten tiedostoihin
-
kokonaislukukohdat (”CP”?): joukko suurimpia kokonaislukuja, jotka ovat käteviä ohjelmointikielellesi ja alusta (hajoaa ASCII: ksi vähäisten resorsioiden rajoissa). Pitäisi olla int32 vanhemmilla tietokoneilla ja int64 kaikilla, joilla on 64-bittinen osoite.
-
Ilmeisesti käyttöliittymät vanhan koodin käyttöön mitä koodausta tarvitaan, jotta vanha koodi toimii oikein.
Kommentit
- @simon buchan,
U+10ffff
max menee ulos ikkunasta, kun (ei jos) koodipisteet loppuvat. Siitä syystä int32: n käyttö p64-järjestelmässä nopeuden varmistamiseksi on todennäköisesti turvallista, koska epäilen heidän ' ll ylittääU+ffffffff
ennen kuin pakotetaan kirjoittamaan koodi uudelleen 128-bittisille järjestelmille noin vuoteen 2050 mennessä. (Se on kohta " käyttää suurinta sopivaa int-arvoa " toisin kuin " suurin käytettävissä oleva " (mikä todennäköisesti olisi int256 tai bignums tai jotain muuta).) - @David: Unicode 5.2 koodaa 107361 koodipistettä.Käyttämättömiä koodipisteitä on 867169. " kun " on vain typerää. Unicode-koodipiste on määritelty lukuna 0 – 0x10FFFF, ominaisuus, josta UTF-16 riippuu. (Myös vuosi 2050 näyttää olevan alhainen arvio 128-bittisistä järjestelmistä, kun 64-bittinen järjestelmä voi pitää sisällään koko Internetin ' osoitetilassa.)
- @David: ", kun " tarkoitti Unicode-koodipisteiden loppumista, ei 128-bittistä kytkintä, joka kyllä, tulevina vuosisatoina. Toisin kuin muisti, merkkien eksponentiaalista kasvua ei ole, joten Unicode-konsortio on nimenomaisesti taannut, etteivät ne koskaan jaa koodipistettä
U+10FFFF
. Tämä on todellakin yksi tilanteista, joissa 21 bittiä riittää kenellekään. - @Simon Buchan: Ainakin ensimmäiseen yhteydenottoon asti. 🙂
- Unicodea käytetään takaamaan, että myöskään U + FFFF: n yläpuolella ei ole koodipisteitä.
Vastaa
Unicode määrittelee koodipisteet aina 0x10FFFF: iin asti (1114112 koodia), kaikki sovellukset, jotka toimivat monikielisessä ympäristössä merkkijonoilla / tiedostonimillä jne. pitäisi käsitellä sitä oikein.
Utf-16 : kattaa vain 1112 064 koodit. Vaikka Unicode -listan lopussa olevat ovat lentokoneista 15-16 (yksityiskäyttöalue). Se ei voi kasvaa tulevaisuudessa paitsi rikkomalla Utf-16 -käsitteen.
Utf-8 : kattaa teoreettisesti 2216757376 koodia. Unicode -koodien nykyinen alue voidaan edustaa enintään 4 tavun sekvenssillä. Se ei kärsi -tavajärjestyksen ongelmasta, se on ”yhteensopiva” ascii: n kanssa.
Utf-32 : kattaa teoreettisesti 2 ^ 32 = 4 294 967 296 koodia. Tällä hetkellä se ei ole koodattu vaihtelevan pituiseksi eikä todennäköisesti tule tulevaisuudessa.
Nämä tosiasiat ovat itsestään selviä. En ymmärrä Utf-16: n yleisen käytön kannattamista. Se on koodattu vaihtelevan pituiseksi (ei pääse hakemistoon), sillä on ongelmia kattaa koko Unicode -alue jopa tällä hetkellä, tavujärjestys on käsiteltävä jne. En näe mitään etua paitsi että sitä käytetään luonnollisesti Windowsissa ja joissakin muissa paikoissa. Vaikka kirjoitat monialustakoodia, on todennäköisesti parempi käyttää Utf-8 natiivisti ja tehdä tuloksia vain loppupisteissä alustasta riippuvalla tavalla (kuten jo ehdotettiin). Kun suora pääsy hakemiston mukaan on välttämätöntä ja muisti ei ole ongelma, tulisi käyttää Utf-32 .
Suurin ongelma on, että monet Windows Unicode = Utf-16 -ohjelmaa käsittelevät ohjelmoijat eivät edes tiedä tai sivuuttavat sitä, että se on koodattu vaihtelevan pituiseksi.
Tapa, jolla se yleensä on * nix -alustalla, on melko hyvä, c-merkkijonot (char *) tulkitaan Utf-8 -koodattuna, leveät c-merkkijonot (wchar_t *) tulkittuina nimellä Utf-32 .
Kommentit
- Huomaa: UTF -16 kattaa kaikki Unicode-koodit, koska Unicode-konsortio päätti, että 10FFFF on Unicoden TOP-alue ja määritti UTF-8: n maksimitavan 4 tavun pituuden ja poisti nimenomaisesti alueen 0xD800-0xDFFF voimassa olevista koodipisteistä ja tätä aluetta käytetään korvikkeen luomiseen paria. Joten mikä tahansa kelvollinen Unicode-teksti voidaan esittää jokaisella näistä koodauksista. Myös kasvamisesta tulevaisuuteen. Näyttää siltä, että ' ei näytä, että miljoona koodipistettä ei riitä missään kaukaisessa tulevaisuudessa.
- @Kerrek: Virheellinen: UCS-2 ei ole kelvollinen Unicode koodaus. Kaikki UTF- * -koodaukset voivat määritelmän mukaan edustaa mitä tahansa Unicode-koodipistettä, joka on laillista vaihdettavaksi. UCS-2 voi edustaa huomattavasti vähemmän, kuin muutama muu. Toista: UCS-2 ei ole kelvollinen Unicode-koodaus, mikä tahansa muu kuin ASCII.
- " En ymmärrä Utf- 8 . Se on koodattu vaihtelevan pituiseksi (ei pääse hakemistoon) "
- @Ian Boyd, tarve käyttää merkkijonon yksittäistä merkkiä satunnaiskäyttökuviossa uskomattoman yliarvioitu. Se on suunnilleen yhtä yleistä kuin haluaa laskea merkkimatriisin diagonaali, mikä on erittäin harvinaista. Merkkijonoja käsitellään käytännössä aina peräkkäin, ja koska pääsy UTF-8-merkkiin N + 1, koska olet UTF-8-merkissä, N on O (1), ei ole mitään ongelmaa. Jousien satunnaiskäyttöä ei tarvitse ylittää. Onko mielestänne varastoinnin arvoinen mennä UTF-32: een UTF-8: n sijasta, on oma mielipiteesi, mutta minulle se ei ole kysymys.
- @tchrist, myönnän merkkijonot käsitellään käytännössä aina peräkkäin, jos sisällytät käänteisen iteraation " peräkkäisenä " ja venytät sitä hieman tarkemmin merkkijono tunnettuun merkkijonoon. Kaksi hyvin yleistä skenaariota on välilyönnin katkaiseminen merkkijonojen päästä ja tiedostotunnisteen tarkistaminen polun lopussa.
Vastaa
Lisää tämä luetteloon:
Esitetty skenaario on yksinkertainen (vielä yksinkertaisempi, koska esitän sen täällä kuin alun perin! ): 1. WinForms TextBox istuu lomakkeella, tyhjä. Sen MaxLength-arvoksi on asetettu 20 .
2.Käyttäjä kirjoittaa tekstiruutuun tai ehkä liittää siihen tekstin.
3. Riippumatta siitä, mitä kirjoitat tai liität TextBoxiin, olet rajoitettu 20: een, vaikka se antaa sympaattisesti äänen 20: n ylittävälle tekstille (YMMV täällä; muutin äänimallini antaa minulle tämän vaikutuksen!).
4. Pieni tekstipaketti lähetetään sitten jonnekin muualle aloittaaksesi jännittävän seikkailun.
Nyt tämä on helppo skenaario, ja kuka tahansa voi kirjoittaa sen vapaa-ajallaan. Kirjoitin sen itse useille ohjelmointikielille WinFormsin avulla, koska olin tylsistynyt enkä ollut koskaan kokeillut sitä aiemmin. Ja tekstillä useilla todellisilla kielillä, koska olen kytketty tällä tavalla ja minulla on enemmän näppäimistöasetteluja kuin kukaan muu koko freaking universumissa.
Nimetin jopa muodon Taikamattoajo , jotta ikävystyminen olisi helpompaa.
Tämä ei toiminut, sen arvoista.
Joten kirjoitin sen sijaan seuraavat 20 -merkit Taikamattoajo -lomakkeeseeni:
0123401234012340123 𠀀
Uh oi.
Tämä viimeinen merkki on U + 20000, ensimmäinen Unicoden B-laajennuksen ideografia (alias U + d840 U + dc00, läheisille ystävilleen, joita hän ei häpeä, että häntä riisutaan ikään kuin edessä) ….
Ja nyt meillä on pallopeli.
Koska kun TextBox. MaxLength kertoo
Hakee tai asettaa merkkien enimmäismäärän, joka voidaan syöttää manuaalisesti tekstiruutuun.
mitä se todella tarkoittaa, on
saa tai asettaa UTF-16 LE -koodin enimmäismäärä Yksiköt, jotka voidaan syöttää manuaalisesti tekstiruutuun ja katkaisee armottomasti elävän pasan kaikista merkkijonoista, jotka yrittävät pelata hienoja pelejä kielellisellä käsityksellä, jonka vain sellainen pakkomielle kuin Kaplanin kaveri löytää loukkaavaksi saat enemmän!).
Yritän selvittää asiakirjan päivittämisen ….
Säännölliset lukijat, jotka muista, että UCS-2 – UTF-16 -sarjani huomaavat onnettomuuteni yksinkertaistetulla TextBox.MaxLength ja kuinka sen tulisi käsitellä vähintään tapausta, jossa sen drakoninen käytös luo laittoman sekvenssin, jonka muut .Net Frameworkin osat saattavat heittää
- System.Text.EncoderFallbackException : Unicode-merkkiä \ uD850 indeksissä 0 ei voida kääntää määritetylle koodisivulle. *
poikkeus, jos välität tämän merkkijonon muualla .Net Frameworkissa (kuten kollegani Dan Thompson teki).
Nyt okei, ehkä koko UCS-2 – UTF-16 -sarja on monien ulottumattomissa.
Mutta ei ”Onko järkevää olettaa, että TextBox.Text ei tuota System.String -ohjelmaa, joka ei voinut aiheuttaa toisen osan .Net Frameworkista heitettäväksi? Tarkoitan, että kontrollissa ei ole mahdollisuutta jonkin tapahtuman muodossa, joka kertoo sinulle tulevasta katkaisusta, johon voit helposti lisätä älykkäämman validoinnin – validoinnin, jota ohjaus itse ei välitä. sanotaan, että tämä punk-ohjaus rikkoo turvallisuussopimusta, joka voi jopa johtaa turvallisuusongelmiin, jos voit luokitella odottamattomia poikkeuksia sovelluksen lopettamiseksi raakana palvelunestona. Miksi WinForms-prosessin tai -menetelmän tai algoritmi tai tekniikka tuottaa virheellisiä tuloksia?
Lähde: Michael S.Kaplan MSDN -blogi
Kommentit
- Kiitos, erittäin hyvä linkki! Olen ' lisännyt sen kysymyksen kysymysluetteloon.
Vastaa
En sanoisi välttämättä, että UTF-16 on haitallinen. Se ei ole tyylikäs, mutta palvelee taaksepäin yhteensopivuutta UCS-2: n kanssa, aivan kuten GB18030 tekee GB2312: n kanssa, ja UTF-8 ASCII.
Mutta perusteellisen muutoksen tekeminen Unicoden rakenteeseen keskivaiheessa, sen jälkeen kun Microsoft ja Sun olivat rakentaneet valtavat sovellusliittymät 16-bittisten merkkien ympärille, oli haitallista. Epäonnistuminen tietoisuuden levittämisestä muutoksesta oli enemmän haitallista.
Kommentit
- UTF-8 on ASCII: n superset , mutta UTF-16 EI OLE UCS-2: n superset. Vaikka melkein superset, UCS-2: n oikea koodaus UTF-8: een johtaa kauhistukseen, joka tunnetaan nimellä CESU-8; UCS-2: lla ei ole ' ei korvikkeita, vain tavallisia koodipisteitä, joten ne on käännettävä sellaisenaan. UTF-16: n todellinen etu on, että ' on helpompaa päivittää UCS-2-koodikanta kuin täydellinen uudelleenkirjoittaminen UTF-8: lle. Hauska, vai mitä?
- Toki teknisesti UTF-16 ei ole ' ta UCS-2: n superset, mutta milloin U + D800 – U + DFFF olivat koskaan käytetty mihin tahansa muuhun kuin UTF-16-korvikkeisiin?
- Eikö ' ole väliä. Muu käsittely kuin sokkojen ohittaminen bytestreamin kautta edellyttää, että purat korvaavat parit, minkä voit ' tehdä, jos ' käsittelet uudelleen se UCS-2: na.
Vastaus
UTF-16 on paras kompromissi käsittelyn ja avaruuden välillä ja siksi useimmat suuret käyttöympäristöt (Win32, Java, .NET) käyttävät sitä merkkijonojen sisäiseen esitykseen.
Kommentit
- -1, koska UTF-8 on todennäköisesti pienempi tai poikkea merkittävästi toisistaan. Tietyissä Aasian skripteissä UTF-8 on kolme tavua glyfiä kohti, kun taas UTF-16 on vain kaksi, mutta tämä on tasapainossa siten, että UTF-8 on vain yksi tavu ASCII: lle (joka esiintyy usein jopa aasialaisten kielten sisällä tuotenimissä, komennoissa ja muissa asioissa). Lisäksi mainituilla kielillä glyf välittää enemmän tietoa kuin latinalainen merkki, joten se on perusteltu jotta se vie enemmän tilaa.
- En sanoisi Wor: n yhdistämistä kummankin vaihtoehdon ensimmäinen puoli on hyvä kompromissi.
- Se ' ei ole helpompaa kuin UTF-8. Se ' on myös vaihtelevan pituinen.
- Jättämällä keskustelut UTF-16: n eduista syrjään: Lainasi ei ole syy Windowsille, Java: lle tai .NET: lle UTF-16: n käytöstä. Windows ja Java ovat peräisin ajalta, jolloin Unicode oli 16-bittinen koodaus. UCS-2 oli silloin kohtuullinen valinta. Kun Unicodesta tuli 21-bittinen koodaus, siirtyminen UTF-16: een oli paras valinta olemassa olevilla alustoilla. Tällä ei ollut mitään tekemistä käsittelyn helppouden tai avaruuskompromissien kanssa. Se ' on vain perintöasia.
- .NET perii Windows-perinnön täältä.
Vastaa
En ole koskaan ymmärtänyt UTF-16: n asiaa. Jos haluat mahdollisimman tilaa säästävän esityksen, käytä UTF-8: ta. Jos haluat pystyä käsittele tekstiä kiinteäpituisena, käytä UTF-32: ta. Jos et halua kumpaakaan, käytä UTF-16: ta. Pahempaa vielä, koska kaikki UTF-16: n yleiset (monikielinen perustaso) merkit sopivat yhteen koodipisteeseen, virheitä, jotka olettavat että UTF-16 on kiinteän pituinen, on hienovarainen ja vaikea löytää, kun taas jos yrität tehdä tämän UTF-8: lla, koodi epäonnistuu nopeasti ja äänekkäästi heti, kun yrität kansainvälistyä.
Vastaa
Koska en voi vielä kommentoida, lähetän tämän vastauksena, koska näyttää siltä, etten voi muuten ottaa yhteyttä kohteen utf8everywhere.org
. Häpeä, etten saa automaattisesti kommentointioikeutta, koska minulla on tarpeeksi mainetta muissa pino-pörsseissä.
Tämä on tarkoitettu kommenttina lausuntoon : Kyllä, UTF-16: ta on pidettävä haitallisena vastauksena.
Yksi pieni korjaus:
Jotta estetään UTF-8: n siirtäminen vahingossa char*
Windows-API-toimintojen ANSI-merkkijonoihin, sinun tulisi määritä UNICODE
, ei _UNICODE
. _UNICODE
kartoittaa toiminnot, kuten _tcslen
, wcslen
, ei MessageBox
– MessageBoxW
. Sen sijaan määritelmä UNICODE
hoitaa jälkimmäisen. Todisteeksi tämä on MS Visual Studio 2005: n ”s WinUser.h
-otsikosta:
#ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE
Vähintään tämä virhe tulisi korjata kohdassa utf8everywhere.org
.
Ehdotus:
Ehkä oppaassa tulisi olla esimerkki Wide- merkkijono tietorakenteesta, jotta sen unohtaminen / unohtaminen olisi vähemmän helppoa.Laajojen merkkijonoversioiden käyttäminen tietorakenteiden lisäksi toimintojen leveiden merkkijonojen versioiden kanssa tekee vielä vähemmän todennäköiseksi, että joku vahingossa kutsuu tällaisen toiminnon ANSI-merkkijono-versiota. / p>
WIN32_FIND_DATAW data; // Note the W at the end. HANDLE hSearch = FindFirstFileW(widen("*.txt").c_str(), &data); if (hSearch != INVALID_HANDLE_VALUE) { FindClose(hSearch); MessageBoxW(nullptr, data.cFileName, nullptr, MB_OK); }
Kommentit
- Hyväksytty; Kiitos! Päivitämme asiakirjan. Asiakirjaa on edelleen kehitettävä ja lisättävä tietoa tietokannoista. Olemme iloisia saadessamme sanamuotoja.
- @PavelRadzivilovsky
_UNICODE
on edelleen olemassa 🙁 - kiitos muistutuksesta. Cubus, Jelle, Haluatko käyttäjän SVN: ään?
- @Pavel Toki, kiitosta siitä!
- @JelleGeerts: Pahoittelen tätä viivettä. Voit aina ottaa meihin yhteyttä sähköpostilla (linkitetty) manifestista) tai Facebookista. Olemme helposti löydettävissä. Vaikka uskon, että korjasimme ongelman, jonka toit tänne (ja hyvitin sinut sinne), koko UTF-8 vs UTF-16 -keskustelut ovat edelleen merkityksellisiä. Jos sinulla on vielä voit vapaasti ottaa yhteyttä meihin näiden yksityisten kanavien kautta.
Vastaa
Joku sanoi, että UCS4 ja UTF-32 olivat Ei niin, mutta tiedän mitä tarkoitat. Yksi niistä on kuitenkin toisen koodaus. Toivon, että he ajattelivat täsmentää endianiteettia ensimmäisestä, jotta emme myöskään taistele endianess-taistelua täällä. Eivätkö he ole nähneet sitä tulevaa? Ainakin UTF-8 on sama jokainen re (ellei joku seuraa alkuperäistä määritystä 6 tavulla).
Jos käytät UTF-16: ta, sinun on sisällytettävä käsittely monitavuisten merkkien kanssa. Et voi siirtyä N: nnen merkin kohdalle indeksoimalla 2N tavutaulukkoon. Sinun on käytävä sitä tai sinulla on oltava merkkiindeksejä. Muuten olet kirjoittanut virheen.
C ++: n nykyinen luonnos spec kertoo että UTF-32: lla ja UTF-16: lla voi olla pienen endian, big-endian ja määrittelemättömiä variantteja. Todella? Jos Unicode olisi täsmentänyt, että kaikkien on pitänyt tehdä vähän endiania alusta alkaen, se olisi kaikki ollut yksinkertaisempaa. (Olisin ollut kunnossa myös big-endianin kanssa.) Sen sijaan jotkut ihmiset panivat sen täytäntöön yhdellä tavalla, toiset toisella, ja nyt olemme juuttuneet typeryyteen turhaan. Joskus on kiusallista olla ohjelmistoinsinööri.
Kommentit
- Määrittelemättömän lopullisuuden on tarkoitus sisältää BOM ensimmäisenä merkkinä, jota käytetään määrittämään, millä tavalla merkkijono tulisi lukea. UCS-4 ja UTF-32 ovat todellakin samat nykyään, ts. Numeerinen UCS-arvo välillä 0 – 0x10FFFF, joka on tallennettu 32-bittiseen kokonaislukuun.
- @Tronic: Teknisesti tämä ei ole totta. Vaikka UCS-4 voi tallentaa minkä tahansa 32-bittisen kokonaisluvun, UTF-32: ta on kielletty tallentamasta ei-merkkisiä koodipisteitä, jotka ovat laittomia vaihdettavaksi, kuten 0xFFFF, 0xFFFE ja kaikkia korvikkeita. UTF on siirtokoodaus, ei sisäinen.
- Endianismiongelmia ei voida välttää, kunhan eri prosessorit käyttävät edelleen erilaisia tavujärjestyksiä. Olisi kuitenkin voinut olla mukavaa, jos " ensisijainen " -tavujärjestys UTF-16: n tiedostojen tallentamista varten.
- Vaikka UTF-32 on kiinteä leveys koodipisteille , se ei ole kiinteä leveys merkkeille . (Kuullut nimeltään " yhdistämällä merkit "?) Voit siis ' mennä N ' -merkkiin yksinkertaisesti indeksoimalla 4N tavutaulukkoon.
Vastaa
En usko, että se on haitallista, jos kehittäjä on riittävän varovainen.
Ja heidän pitäisi hyväksyä tämä kauppa, jos he tietävät myös hyvin.
Japanilaisena ohjelmistokehittäjänä pidän UCS-2: ta riittävän suurena ja tilan rajoittaminen ilmeisesti yksinkertaistaa logiikkaa ja vähentää ajonaikaisia muistia, joten utf-16: n käyttö UCS-2: n rajoissa on tarpeeksi hyvä.
On olemassa tiedostojärjestelmä tai jokin muu sovellus, joka olettaa, että koodipisteet ja tavut ovat suhteellisia, jotta raakakoodipisteiden numero voidaan taata joillekin kiinteäkokoisille varastoille.
Yksi esimerkki on NTFS ja VFAT, jotka määrittelevät UCS-2: n tiedostonimen tallennuskoodaukseksi.
Jos kyseinen esimerkki todella haluaa laajentaa tukemaan UCS-4: tä, voisin kuitenkin sopia kaikesta kaikesta utf-8: n käyttämisestä, mutta kiinteällä pituudella on hyviä kohtia, kuten:
- voi takaa koon pituuden mukaan (datan koko ja koodipisteen pituus ovat verrannollisia)
- voi käyttää koodausnumeroa hajautushakuun
- pakkaamaton data on kohtuullisen kokoinen (verrattuna utf-32 / UCS-4)
Tulevaisuudessa, kun muisti / prosessointiteho on halpaa jopa upotetuissa laitteissa, voimme hyväksyä laitteen olevan hieman hidas ylimääräisten välimuistihäviöiden, sivuvirheiden ja ylimääräisen muistin varalta käyttö, mutta tämä ei tapahdu lähitulevaisuudessa …
Kommentit
- Niille, jotka lukevat tätä kommenttia, on syytä huomata, että UCS- 2 ei ole sama asia kuin UTF-16. Ole hyvä ja etsi eroja ymmärtääksesi.
vastaus
”Pitäisikö yksi suosituimmista koodauksia, UTF-16, pidetään haitallisina? ”
Aivan mahdollista, mutta vaihtoehtojen ei välttämättä tarvitse katsoa olevan paljon parempia.
Peruskysymys on, että on olemassa monia erilaisia käsitteitä: kuviot, merkit, koodipisteet ja tavusekvenssit. Näiden välinen kartoitus ei ole triviaali, jopa normalisointikirjaston avulla. (Esimerkiksi joitakin merkkejä eurooppalaisilla kielillä, jotka kirjoitetaan latinalaisella kirjoituskoodilla, ei kirjoiteta yhdellä Unicode-koodipisteellä. Ja tämä on monimutkaisuuden yksinkertaisemmassa päässä!) Tämä tarkoittaa sitä, että kaiken oikein saaminen on melko hämmästyttävän vaikeaa; odottamattomia vikoja on odotettavissa (ja sen sijaan, että vain moitisit niistä täällä, kerro kyseisen ohjelmiston ylläpitäjille ).
Ainoa tapa, jolla UTF- 16 voidaan pitää haitallisena verrattuna toisin sanoen UTF-8: een sillä, että sillä on erilainen tapa koodata koodipisteitä BMP: n ulkopuolella (korvikeparina) .Jos koodi haluaa päästä käsiksi tai toistaa koodipisteittäin, OTOH, se tarkoittaa, että huomattava joukko olemassa olevaa koodia, joka ottaa ”merkit”, voidaan aina sovittaa kaksitavuiseen määrään – melko yleinen, jos väärä oletus – voi vähiten jatkaa työtä rakentamatta sitä kaikkea. Toisin sanoen ainakin pääset näkemään nuo merkki joita ei käsitellä oikein!
Kääntäisin kysymyksesi päähän ja sanon, että koko Unicoden pirun shebangia tulisi pitää haitallisena ja kaikkien tulisi käyttää 8-bittistä koodausta paitsi Olen nähnyt (viimeisten 20 vuoden aikana) mihin tämä johtaa: kamala sekaannus erilaisiin ISO 8859 -koodauksiin, plus kyrillisiin ja EBCDIC-sarjaan käytettyjen joukko ja… No, Unicode kaikista vioistaan voittaa sen . Jos vain se ei olisi ollut niin ilkeä kompromissi eri maiden välillä ”väärinkäsityksiä.
Kommentit
- Kun tiedämme onnemme, muutamassa vuodessa ' Löydämme itsemme loppuvan tilasta UTF-16: ssa. Meh.
- Peruskysymys on, että teksti on petollisen kovaa. Mikään lähestymistapa tietojen esittämiseen digitaalisella tavalla ei voi olla mutkaton. ' on sama syy, että päivämäärät ovat kovia, kalenterit ovat kovia, aika on kovaa, henkilökohtaiset nimet ovat kovia, postiosoitteet ovat vaikeita: aina kun digitaalikoneet leikkaavat ihmisen kulttuurirakenteita, monimutkaisuus puhkeaa. Se on elämän tosiasia. Ihmiset eivät toimi digitaalisessa logiikassa.