Bør UTF-16 betraktes som skadelig?

Kommentarer

  • Ikke riktig. Jeg forklarer, hvis du skriver " שָׁ " det sammensatte tegnet som består av " ש ", " ָ " og " ׁ ", vokaler, da er fjerning av hver av dem logisk, du fjerner ett kodepunkt når du trykker " baksiden " og fjern alt tegn inkludert vokaler når du trykker " del ". Men du produserer aldri ulovlig tilstand av tekst – ulovlige kodepunkter. Dermed er situasjonen når du trykker på tilbaketasten og får ulovlig tekst feil.
  • CiscoIPPhone: Hvis en feil " rapporteres flere forskjellige ganger, av mange forskjellige mennesker ", og et par år senere skriver en utvikler på en dev-blogg at " Tro det eller ei, oppførselen er stort sett forsettlig! ", så (mildt sagt) pleier jeg å tro at det ' sannsynligvis ikke er den beste designbeslutningen noensinne. 🙂 Bare fordi det ' s bevisst betyr ikke ' t det ' er ikke en feil.
  • Flott innlegg. UTF-16 er faktisk " verste av begge verdener ": UTF8 har variabel lengde, dekker hele Unicode, krever en transformasjonsalgoritme til og fra rå kodepunkter, begrenser seg til ASCII, og den har ingen endiannessproblemer. UTF32 har fast lengde, krever ingen transformasjon, men tar mer plass og har endiannessproblemer. Så langt så bra, du kan bruke UTF32 internt og UTF8 for serialisering. Men UTF16 har ingen fordeler: Det ' endianavhengig, det ' s variabel lengde, det tar mye plass, det ' er ikke ASCII-kompatibel. Innsatsen som trengs for å håndtere UTF16 riktig, kan brukes bedre på UTF8.
  • @Ian: UTF-8 IKKE har samme advarsler som UTF-8. Du kan ikke ha surrogater i UTF-8. UTF-8 maskerer seg ikke som noe den ikke er, men de fleste programmerere som bruker UTF-16 bruker det feil. Jeg vet. Jeg ' har sett dem igjen og igjen og igjen og igjen.
  • UTF-8 gjør ikke ' t har problemet fordi alle behandler det som en koding med variabel bredde. Grunnen til at UTF-16 har problemet er at alle behandler det som en koding med fast bredde.

Svar

Dette er et gammelt svar.
Se UTF-8 overalt for de siste oppdateringene.

Opinion: Ja, UTF-16 bør betraktes som skadelig . Selve grunnen til at den eksisterer er fordi det for en tid tilbake pleide å være en misforstått tro på at widechar kommer til å være det UCS-4 nå er.

Til tross for «anglosentrismen» til UTF-8, er det bør betraktes som den eneste nyttige kodingen for tekst. Man kan hevde at kildekoder til programmer, websider og XML-filer, OS-filnavn og andre tekst-grensesnitt fra datamaskin til datamaskin aldri burde ha eksistert. Men når de gjør det, er tekst ikke bare for menneskelige lesere.

På den annen side er UTF-8 overhead en liten pris å betale mens den har betydelige fordeler. Fordeler som kompatibilitet med uvitende kode som bare overfører strenger med char*. Dette er en flott ting. Det er få nyttige tegn som er KORTE i UTF-16 enn de er i UTF-8.

Jeg tror at alle andre kodinger vil dø etter hvert. Dette innebærer at MS-Windows, Java, ICU, python slutte å bruke den som favoritt. Etter lang forskning og diskusjoner forbyr utviklingskonvensjonene på mitt firma å bruke UTF-16 hvor som helst unntatt OS API-samtaler, og dette til tross for viktighet av ytelsen i applikasjonene våre og det faktum at vi bruker Windows. Konverteringsfunksjoner ble utviklet for å konvertere alltid antatt-UTF8 std::string s til native UTF-16, som Windows selv støtter ikke ordentlig .

Til folk som sier « bruk det som trengs der det trengs «, sier jeg: det er en stor fordel å bruke den samme kodingen overalt, og jeg ser ingen tilstrekkelig grunn til å Spesielt tror jeg å legge til wchar_t til C ++ var en feil, og det er også Unicode-tilleggene til C ++ 0x. Det som må kreves av STL-implementeringer er imidlertid at hver std::string eller char* -parameter vil bli ansett som unicode-kompatibel.

Jeg er også imot « bruk hva du vil «tilnærming. Jeg ser ingen grunn til slik frihet. Det er nok forvirring om emnet tekst, noe som resulterer i all denne ødelagte programvaren. Når det er sagt, er jeg overbevist om at programmerere endelig må oppnå enighet om UTF-8 som en riktig måte. (Jeg kommer fra et ikke-ascii-talende land og vokste opp på Windows, så jeg forventet sist å angripe UTF-16 basert på religiøse grunner).

Jeg vil gjerne dele mer informasjon om hvordan jeg lager tekst på Windows, og hva jeg anbefaler alle andre for kompileringstidskontrollert unicode-korrekthet, brukervennlighet og bedre koden på flere plattformer. Forslaget skiller seg vesentlig fra det som vanligvis anbefales som den riktige måten å bruke Unicode på windows på. Likevel resulterte en grundig undersøkelse av disse anbefalingene i den samme konklusjonen. Så her går:

  • Ikke bruk wchar_t eller std::wstring noe annet sted enn tilstøtende punkt til APIer som godtar UTF-16.
  • Ikke bruk _T("") eller L"" UTF-16 bokstaver (Disse bør IMO tas ut av standarden , som en del av UTF-16 avskrivning).
  • Ikke bruk typer, funksjoner eller deres derivater som er følsomme for _UNICODE -konstanten, for eksempel LPTSTR eller CreateWindow().
  • Likevel, _UNICODE alltid definert, til unngå å overføre char* strenger til WinAPI blir stille sammen
  • std::strings og char* hvor som helst i programmet betraktes som UTF-8 (hvis ikke annet er sagt)
  • Alle strengene mine er std::string, selv om du kan sende tegn * eller streng bokstavelig til convert(const std::string &).
  • bruker bare Win32-funksjoner som godtar widechars (LPWSTR). Aldri de som godtar LPTSTR eller LPSTR. Send parametere på denne måten:

    ::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str()) 

    (Retningslinjene bruker konverteringsfunksjoner nedenfor.)

  • Med MFC-strenger :

    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); 
  • Arbeide med filer, filnavn og fstream på Windows:

    • Pass aldri std::string eller const char* filnavnargumenter til fstream familie. MSVC STL støtter ikke UTF-8-argumenter, men har en ikke-standard utvidelse som skal brukes som følger:
    • Konverter std::string argumenter til std::wstring med Utils::Convert:

      std::ifstream ifs(Utils::Convert("hello"), std::ios_base::in | std::ios_base::binary); 

      Vi må manuelt fjern konverteringen når MSVCs holdning til fstream endres.

    • Denne koden er ikke multi-plattform og må kanskje endres manuelt i fremtiden
    • Se fstream unicode-forskning / diskusjonssak 4215 for mer info.
    • Produser aldri tekstutdatafiler med ikke-UTF8-innhold
    • Unngå å bruke fopen() av RAII / OOD-årsaker. Bruk om nødvendig _wfopen() og WinAPI-konvensjonene.

// 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 } 

Kommentarer

  • Jeg kan ' ikke er enig. Fordelene med utf16 over utf8 for mange asiatiske språk dominerer helt poengene du tar. Det er naivt å håpe at japanerne, thailenderne, kineserne osv. Skal gi opp denne kodingen. De problematiske sammenstøtene mellom charsets er når charsets stort sett virker like, bortsett fra med forskjeller. Jeg foreslår at du standardiserer på: fast 7bit: iso-irv-170; 8bit variabel: utf8; 16bit variabel: utf16; 32bit fast: ucs4.
  • @Charles: takk for innspillet ditt. Det er sant at noen BMP-tegn er lengre i UTF-8 enn i UTF-16. Men la ' innse det: problemet er ikke i byte som kinesiske BMP-tegn tar, men programvaredesignkompleksiteten som oppstår. Hvis en kinesisk programmerer uansett må designe for tegn med variabel lengde, ser det ut til at UTF-8 fortsatt er en liten pris å betale sammenlignet med andre variabler i systemet. Han kan bruke UTF-16 som en komprimeringsalgoritme hvis plassen er så viktig, men selv da vil det ikke være noen match for LZ, og etter LZ eller annen generisk komprimering tar begge omtrent samme størrelse og entropi.
  • Det jeg i utgangspunktet sier er at forenkling som tilbys ved å ha En koding som også er kompatibel med eksisterende char * -programmer, og som også er den mest populære i dag for alt, er utenkelig.Det er nesten som i gode gamle " plaintext " dager. Vil du åpne en fil med et navn? Du trenger ikke å bry deg om hva slags unicode du gjør osv. Jeg foreslår at vi, utviklere, begrenser UTF-16 til helt spesielle tilfeller av alvorlig optimalisering der en liten bit ytelse er verdt arbeidsmåneders arbeid.
  • Linux har hatt et spesifikt krav når man velger å bruke UTF-8 internt: kompatibilitet med Unix. Windows trengte ikke ', og dermed da utviklerne implementerte Unicode, la de til UCS-2-versjoner av nesten alle funksjoner som håndterte tekst og fikk multibyte til å bare konvertere til UCS-2 og ring de andre. De erstatter senere UCS-2 med UTF-16. Linux holdt derimot på 8-biters koding og brukte dermed UTF-8, da det ' er det riktige valget i så fall.
  • @Pavel Radzivilovsky : BTW, dine skrifter om " Jeg tror at alle andre kodinger vil til slutt dø. Dette innebærer at MS-Windows, Java, ICU, python slutter å bruke det som favoritt. " og " Spesielt tror jeg å legge til wchar_t til C ++ var en feil, og det samme er unicode-tilleggene til C ++ Ox. " er enten ganske naive eller veldig veldig arrogante . Og dette kommer fra noen som koder hjemme med en Linux og som er fornøyd med UTF-8-tegnene. For å si det rett ut: Det vant ' skjedde ikke .

Svar

Unicode-kodepunkter er ikke tegn! Noen ganger er de ikke engang tegn (visuelle former) .

Noen eksempler:

  • Romerske kodepunkter som «ⅲ». (Et enkelt tegn som ser ut som «iii».)
  • Tegn med aksent som «á», som kan representeres som enten et enkelt kombinert tegn «\ u00e1» eller et tegn og skilt diakritisk «\ u0061 \ u0301 «.
  • Tegn som gresk liten signatur, som har forskjellige former for mellom (» σ «) og slutt (» ς «) av ordposisjoner, men som bør betraktes som synonymer for søk.
  • Unicode diskresjonær bindestrek U + 00AD, som kanskje eller ikke vises visuelt, avhengig av kontekst, og som ignoreres for semantisk søk.

De eneste måtene å få Unicode-redigering riktig er å bruke et bibliotek skrevet av en ekspert , eller bli ekspert og skrive et selv. Hvis du bare teller kodepunkter, lever du i en tilstand av synd.

Kommentarer

  • Dette. Veldig mye dette. UTF-16 kan forårsake problemer, men selv å bruke UTF-32 gjennom kan (og vil) fremdeles gi deg problemer.
  • Hva er et tegn? Du kan definere et kodepunkt som et tegn og klare deg ganske bra. Hvis du mener et brukersynlig tegn, er det noe annet.
  • @tchrist sikker på at du tildeler plass denne definisjonen er bra, men for noe annet? Ikke så mye. Hvis du håndterer et kombinasjonstegn som eneste tegn (dvs. for å slette eller " ta første N tegn " -operasjon) vil du ' Det blir merkelig og feil oppførsel. Hvis et kodepunkt bare har betydning når det kombineres med minst et annet, kan du ' t håndtere det alene på en fornuftig måte.
  • @Pacerier, dette er sent til festen, men jeg må kommentere det. Noen språk har veldig store sett med potensielle kombinasjoner av diakritiske stoffer (jfr. Vietnamesisk, dvs. mệt đừ). Å ha kombinasjoner i stedet for ett tegn per diakritisk er veldig nyttig.
  • et lite notat om terminologi: kodepunkter gjør tilsvarer unicode-tegn ; det Daniel snakker om her er brukeropplevde tegn , som tilsvarer unicode-grafeklynger

Svar

Det er en enkel tommelfingerregel for hva Unicode Transformation Form (UTF) skal brukes: – utf-8 for lagring og kommunikasjon – utf-16 for databehandling – du kan gå med utf-32 hvis det meste av plattform-API-en du bruker er utf-32 (vanlig i UNIX-verdenen).

De fleste systemene bruker i dag utf-16 (Windows, Mac OS, Java, .NET, ICU , Qt). Se også dette dokumentet: http://unicode.org/notes/tn12/

Tilbake til «UTF-16 som skadelig», Jeg vil si: definitivt ikke.

Folk som er redde for surrogater (tenker at de forvandler Unicode til en koding med variabel lengde) forstår ikke de andre (langt større) kompleksitetene som gjør kartlegging mellom tegn og et Unicode-kodepunkt veldig komplekst: kombinere tegn, ligaturer, variasjonsvelgere, kontrolltegn osv.

Bare les denne serien her http://www.siao2.com/2009/06/29/9800913.aspx og se hvordan UTF-16 blir et enkelt problem.

Kommentarer

  • Vennligst legg til noen eksempler der UTF-32 er vanlig i UNIX-verdenen!
  • Nei, det gjør du ikke vil bruke UTF-16 for databehandling. Det ' er vondt i rumpa. Den har alle ulempene med UTF-8, men ingen av fordelene. Både UTF-8 og UTF-32 er klart overlegne den onde hacken tidligere kjent som fru UTF-16, hvis pikenavn var UCS-2.
  • I går fant jeg nettopp en feil i Java-kjernen String classs equalsIgnoreCase metode (også andre i strengklassen) som aldri hadde vært der hadde Java brukt UTF-8 eller UTF-32. Det er millioner av disse sovende bomber i hvilken som helst kode som bruker UTF-16, og jeg er lei av dem. UTF-16 er en ond pox som plager programvaren vår med lumske feil for alltid og alltid. Det er tydelig skadelig, og bør avskaffes og utestenges.
  • @tchrist Wow så en ikke-surrogatbevisst funksjon (fordi den ble skrevet når det ikke var noen og er dessverre dokumentert på en slik måte som gjør det sannsynligvis umulig å tilpasse – det spesifiserer .toUpperCase (char)) vil føre til feil oppførsel? Du ' er klar over at en UTF-32-funksjon med et utdatert kodepunktskart ikke ville ' ikke taklet dette bedre? Også hele Java API håndterer surrogater ikke spesielt bra, og de mer intrikate punktene om Unicode slett ikke – og med senere vil den brukte kodingen ikke ' telle i det hele tatt.
  • -1: En ubetinget .Substring(1) i .NET er et trivielt eksempel på noe som bryter støtte for alle ikke-BMP Unicode. Alt som bruker UTF-16 har dette problemet; det ' er for lett å behandle det som en koding med fast bredde, og du ser problemer for sjelden. Det gjør det til en aktiv skadelig koding hvis du vil støtte Unicode.

Svar

Ja, absolutt.

Hvorfor? Det har å gjøre med å trene kode .

Hvis du ser på disse bruksstatistikk for kodepunkt på et stort korpus av Tom Christiansen vil du se at trans-8bit BMP-kodepunkter brukes flere ordrer hvis størrelsesorden mer enn ikke-BMP-kodepunkter:

 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 

Ta TDD-dikten: «Utestet kode er ødelagt kode», og omformuler den som «uutøvet kode er ødelagt kode», og tenk hvor ofte programmerere må håndtere kodepunkter som ikke er BMP.

Feil relatert til å ikke håndtere UTF-16 som koding med variabel bredde, er mye mer sannsynlig å gå ubemerket hen enn tilsvarende feil i UTF-8 . Noen programmeringsspråk fremdeles ikke garantere å gi deg UTF-16 i stedet for UCS-2, og noen såkalte høyt nivå programmeringsspråk gir tilgang til kodeenheter i stedet for kodepunkter (selv C er ment å gi deg tilgang til kodepunkter hvis du bruker wchar_t, uansett hva noen plat skjemaer kan gjøre).

Kommentarer

  • " Feil relatert til å ikke håndtere UTF-16 som det er mye mer sannsynlig at en koding med variabel bredde ikke blir lagt merke til enn de tilsvarende feilene i UTF-8. " Dette er kjernen i problemet, og dermed det riktige svaret.
  • Nettopp. Hvis UTF-8-håndteringen din blir borket, vil den ' være umiddelbart åpenbar. Hvis UTF-8-håndteringen din blir borked, vil du ' bare legge merke til om du legger inn uvanlige Han-tegn eller matematiske symboler.
  • Veldig sant, men på den andre hånd, hva er enhetstester for hvis du skulle være avhengig av flaks for å finne feil i sjeldnere tilfeller?
  • @musiphil: så, når sist du opprettet en enhetstest for ikke-BMP-tegn?
  • For å utdype min tidligere uttalelse: selv med UTF-8, kan du ikke være trygg på at du har dekket alle tilfeller etter bare å ha sett noen arbeidseksempler. Samme med UTF-16: du må teste om koden din fungerer både med ikke-surrogater og med surrogater. (Noen kan til og med hevde at UTF-8 har minst fire hovedtilfeller mens UTF-16 bare har to.)

Svar

Jeg vil foreslå at tenkning UTF-16 kan betraktes som skadelig, sier at du trenger å få en større forståelse av unicode .

Siden jeg har blitt nedstemt for å presentere min mening om et subjektivt spørsmål, la meg utdype det. Hva er det som plager deg med UTF-16? Foretrekker du om alt var kodet i UTF-8? UTF-7? Eller Hva med UCS-4? Visse applikasjoner er selvfølgelig ikke designet for å håndtere enkeltegnkoder der ute – men de er nødvendige, spesielt i dagens globale informasjonsdomene, for kommunikasjon mellom internasjonale grenser.

Men egentlig, hvis du føler at UTF-16 bør betraktes som skadelig fordi det er forvirrende eller kan implementeres feil (unicode kan absolutt være), hvilken metode for tegnkoding vil da bli ansett som ikke-skadelig?

REDIGERING: For å avklare: Hvorfor vurdere feil implementeringer av en standard som en refleksjon av kvaliteten på selve standarden? Som andre senere har bemerket, bare fordi en applikasjon ikke bruker et verktøy, betyr det ikke at verktøyet i seg selv er mangelfull. Hvis det var tilfelle, kunne vi sannsynligvis si ting som «var nøkkelord som betraktet som skadelig», eller «tråder betraktet som skadelig». Jeg tror spørsmålet forveksler kvaliteten og arten av standarden med vanskeligheter mange programmerere har med å implementere og bruke den riktig, noe jeg føler stammer mer fra deres manglende forståelse for hvordan unicode fungerer, i stedet for unicode i seg selv.

Kommentarer

  • -1: Hva med å ta opp noen av Artyom ' s objekter ons, i stedet for bare å nedlatende ham?
  • BTW: Da jeg begynte å skrive denne artikkelen, ville jeg nesten skrive " Skal Joel på Softeare-artikkelen til Unicode vurderes skadelig " fordi det er mange feil. For eksempel: utf-8-koding tar opptil 4 tegn og ikke 6. Det skiller heller ikke mellom UCS-2 og UTF-16 som er veldig forskjellige – og som faktisk forårsaker problemene jeg snakker om.
  • Det bør også bemerkes at når Joel skrev den artikkelen, var UTF-8-standarden WAS 6 byte, ikke 4. RFC 3629 endret standarden til 4 byte flere måneder etter at han skrev artikkelen. Som det meste på internett, lønner det seg å lese fra mer enn én kilde, og å være klar over alderen til kildene dine. Koblingen var ikke ' t ment å være " slutten alle være alle " snarere et utgangspunkt.
  • Jeg vil bilde: utf-8 eller utf-32 som er: koding med variabel lengde i nesten alle tilfeller (inkludert BMP) eller koding med fast lengde alltid.
  • @iconiK: Ikke vær dum. UTF-16 er absolutt ikke de facto -standarden for behandling av tekst. Vis meg en programmeringsspråk som er mer egnet til tekstbehandling som Perl, som alltid har (vel, i mer enn et tiår) brukte abstrakte tegn med en underliggende UTF-8-representasjon internt. På grunn av dette håndterer hvert Perl-program automatisk alle Unicode uten at brukeren hele tiden må ape rundt med idiotiske surrogater. Lengden på en streng er dens antall i kodepunkter, ikke kodenheter. Noe annet er ren dumhet som setter bakover i bakoverkompatibilitet.

Svar

Det er ikke noe galt med Utf- 16 koding. Men språk som behandler 16-biters enhetene som tegn, bør sannsynligvis betraktes som dårlig utformet. Å ha en type som heter «char» som ikke alltid representerer et tegn, er ganske forvirrende. Siden de fleste utviklere vil forvente at en røyktype representerer et kodepunkt eller tegn, vil mye kode trolig bryte når de blir utsatt for tegn utenfor BMP.

Merk imidlertid at selv å bruke utf-32 ikke betyr at hver 32- bitkodepunkt vil alltid representere et tegn. På grunn av kombinasjon av tegn kan en faktisk karakter bestå av flere kodepunkter. Unicode er aldri trivielt.

BTW. Det er sannsynligvis den samme klassen av bugs med plattformer og applikasjoner som forventer at tegn skal være 8-bit, som mates med Utf-8.

Kommentarer

  • I Java ' tilfelle, hvis du ser på tidslinjen deres ( java.com/en/javahistory/timeline.jsp), ser du at den primære utviklingen av String skjedde mens Unicode var 16 bits (den endret seg i 1996). De måtte skru på evnen til å håndtere ikke BMP-kodepunkter, og dermed forvirringen.
  • @Kathy: Ikke egentlig en unnskyldning for C #. Generelt er jeg enig i at det skal være en CodePoint -type, som holder et enkelt kodepunkt (21 bits), en CodeUnit -type, holder en enkelt kodeenhet (16 bits for UTF-16) og en Character -type vil ideelt sett måtte støtte et komplett grafeme. Men det gjør det funksjonelt ekvivalent med et String
  • Dette svaret er nesten to år gammelt, men jeg kan ' t annet enn å kommentere det. " Å ha en type som heter ' char ' som ikke alltid representerer et tegn, er pen forvirrende. " Og likevel bruker folk det hele tiden i C og lignende for å representere heltallsdata som kan lagres i en enkelt byte.
  • Og jeg ' har sett et parti av C-kode som ikke ' t håndterer tegnkoding riktig.
  • C # har en annen unnskyldning: den ble designet for Windows, og Windows ble bygget på UCS-2 (den ' er veldig irriterende at selv i dag kan ikke Windows API-er støtte UTF-8). I tillegg tror jeg Microsoft ønsket Java-kompatibilitet (.NET 1.0 hadde et Java-kompatibilitetsbibliotek, men de droppet Java-støtte veldig raskt – jeg ' gjetter at dette skyldes Sun ' saksak mot MS?)

Svar

Mitt personlige valg er å alltid bruke UTF-8. Det er standarden på Linux for nesten alt. Den er bakoverkompatibel med mange eldre apper. Det er en veldig minimal overhead når det gjelder ekstra plass som brukes til ikke-latinske tegn mot de andre UTF-formatene, og det er betydelige besparelser i plass til latinske tegn. På nettet hersker latinske språk, og jeg tror de vil gjøre det i overskuelig fremtid. Og for å ta opp et av hovedargumentene i det opprinnelige innlegget: nesten alle programmerere er klar over at UTF-8 noen ganger vil ha flerbyte-tegn i seg. Ikke alle takler dette riktig, men de er vanligvis klar over, noe som er mer enn det som kan sies for UTF-16. Men selvfølgelig må du velge den som passer best for søknaden din. Derfor er det mer enn en i utgangspunktet.

Kommentarer

  • UTF-16 er enklere for alt innen BMP, at ' hvorfor det brukes så mye. Men jeg ' er også en fan av UTF-8, den har heller ingen problemer med bytebestilling, noe som fungerer til sin fordel.
  • Teoretisk sett ja. I praksis er det slike ting som for eksempel UTF-16BE, som betyr UTF-16 i stor endian uten BOM. Dette er ikke noe jeg har laget, dette er en faktisk koding tillatt i ID3v2.4-koder (ID3v2-koder suger, men er dessverre mye brukt). Og i slike tilfeller må du definere endenhet eksternt, fordi selve teksten ikke inneholder ' TOM. UTF-8 er alltid skrevet på en måte, og det har ikke ' et slikt problem.
  • Nei, UTF-16 er ikke enklere. Det er vanskeligere. Det villeder og lurer deg til å tro at det er fast bredde. All slik kode er ødelagt og mer fordi du ikke merker før det er for sent. SAKE I PUNKT: Jeg fant nettopp en annen dum UTF-16-feil i Java-kjernebibliotekene i går, denne gangen i String.equalsIgnoreCase, som ble igjen i UCS-2 bak hjerter buggeri, og mislykkes så på 16/17 gyldige Unicode-kodepunkter. Hvor lenge har den koden eksistert? Ingen unnskyldning for at den skal være buggy. UTF-16 fører til ren dumhet og en ulykke som venter på å skje. Kjør skrikende fra UTF-16.
  • @tchrist Man må være en veldig uvitende utvikler for å ikke vite at UTF-16 ikke er fast lengde. Hvis du begynner med Wikipedia, vil du lese følgende helt øverst: " Det gir et resultat med variabel lengde på enten en eller to 16-bits kodenheter per kodepunkt ". Vanlige spørsmål om Unicode sier det samme: unicode.org/faq//utf_bom.html#utf16-1 . Jeg vet ikke ' hvordan UTF-16 kan lure hvem som helst hvis det står overalt at det er variabel lengde. Når det gjelder metoden, ble den aldri designet for UTF-16 og skulle ikke ' ikke betraktes som Unicode, så enkelt som det.
  • @tchrist Har du en kilde for statistikken din? Selv om gode programmerere er knappe, tror jeg dette er bra, fordi vi blir mer verdifulle. 🙂 Når det gjelder Java API-ene, kan char-baserte deler til slutt bli utfaset, men dette er ikke en garanti for at de ikke vant '. Og de vil definitivt ikke ' bli fjernet av hensyn til kompatibilitet.

Svar

Vel, det er en koding som bruker symboler i fast størrelse. Jeg mener absolutt UTF-32. Men 4 byte for hvert symbol er for mye av bortkastet plass, hvorfor skulle vi bruke det i hverdagssituasjoner? bak Unicode-standarden, men var ikke raske til å rette opp situasjonen. Opera, Windows, Python, Qt – alle dukket opp før UTF-16 ble allment kjent eller til og med ble til. Jeg kan imidlertid bekrefte at det i Opera, Windows Utforsker og Notisblokk ikke er noen problemer med tegn utenfor BMP lenger (i det minste på PCen min). Men uansett, hvis programmer ikke gjenkjenner surrogatpar, bruker de ikke UTF-16. Uansett hvilke problemer som oppstår ved å håndtere slike programmer, har de ikke noe med selve UTF-16 å gjøre.

Imidlertid tror jeg at problemene med eldre programvare med bare BMP-støtte er noe overdrevne. Tegn utenfor BMP opptrer bare i veldig spesifikke tilfeller og områder. I henhold til Offisielle vanlige spørsmål om Unicode , «selv i østasiatisk tekst, bør forekomsten av surrogatpar være i underkant av mindre enn 1% av all tekstlagring i gjennomsnitt».Naturligvis bør tegn utenfor BMP ikke overses fordi et program ikke er Unicode-samsvar ellers, men de fleste programmer er ikke ment for å arbeide med tekster som inneholder slike tegn. Det er derfor hvis de ikke gjør det ikke støtte det, det er ubehagelig, men ikke en katastrofe.

La oss nå vurdere alternativet. Hvis UTF-16 ikke eksisterte, ville vi ikke ha en koding som egner seg godt for ikke-ASCII-tekst, og all programvaren som er laget for UCS-2, må redesignes for å forbli Unicode-kompatibel. Sistnevnte vil sannsynligvis bare redusere Unicode-adopsjonen. Vi ville ikke ha vært i stand til å opprettholde kompatibilitet med tekst i UCS-2 slik UTF-8 gjør i forhold til ASCII.

Nå, når vi legger til side alle eldre spørsmål, hva er argumentene mot kodingen i seg selv? Jeg tviler virkelig på at utviklere i dag ikke vet at UTF-16 har variabel lengde. Det er skrevet overalt med Wikipedia. UTF-16 er mye mindre vanskelig å analysere enn UTF-8, hvis noen påpekte kompleksitet som et mulig problem. Det er også feil å tro at det er lett å rote med å bestemme strenglengden bare i UTF-16. Hvis du bruker UTF-8 eller UTF-32, bør du fremdeles være klar over at ett Unicode-kodepunkt ikke nødvendigvis betyr ett tegn. Annet enn det, tror jeg ikke at det er noe vesentlig mot kodingen.

Derfor tror jeg ikke selve kodingen skal betraktes som skadelig. UTF-16 er et kompromiss mellom enkelhet og kompaktitet, og det er ingen skade i å bruke det som trengs der det trengs I noen tilfeller må du være kompatibel med ASCII og du trenger UTF-8, i noen tilfeller vil du jobbe med arbeid med Han-ideografer og spare plass ved bruk av UTF-16, i noen tilfeller trenger du universelle representasjoner av tegn som bruker en fast -lengde koding. Bruk det som er mer passende, bare gjør det ordentlig.

Kommentarer

  • At ' er en ganske blinkende, anglosentrisk visning, Malcolm. Nesten på nivå med " ASCII er bra nok for USA – resten av verden bør passe inn i oss ".
  • Egentlig er jeg ' fra Russland og møter kyrillikere hele tiden (inkludert mine egne programmer), så jeg gjør ikke ' Jeg tror ikke jeg har anglosentrisk utsikt. 🙂 Å nevne ASCII er ikke helt passende, fordi det ' ikke er Unicode og ikke støtter ' t spesifikke tegn. UTF-8, UTF-16, UTF-32 støtter de samme internasjonale tegnsettene, de er bare ment for bruk i sine spesifikke områder. Og dette er akkurat poenget mitt: Hvis du bruker mest engelsk, bruk UTF-8, hvis du bruker mest kyrillikk, bruk UTF-16, hvis du bruker eldgamle språk, bruk UTF-32. Ganske enkelt.
  • " Ikke sant, asiatiske skript som japansk, kinesisk eller arabisk tilhører også BMP. BMP i seg selv er faktisk veldig stort og absolutt stort nok til å inkludere alle manusene som brukes i dag " Dette er alt så galt. BMP inneholder 0xFFFF tegn (65536). Kinesisk alene har mer enn det. Kinesiske standarder (GB 18030) har mer enn det. Unicode 5.1 tildelte allerede mer enn 100 000 tegn.
  • @Marcolm: " Selve BMP er faktisk veldig stor og absolutt stor nok til å inkludere alle skriptene som brukes i dag " Ikke sant. På dette tidspunktet tildelte Unicode allerede 100K tegn, mye mer enn BMP kan imøtekomme. Det er store biter av kinesiske tegn utenfor BMP. Og noen av dem kreves av GB-18030 (obligatorisk kinesisk standard). Annet kreves av (ikke-obligatoriske) japanske og koreanske standarder. Så hvis du prøver å selge noe i disse markedene, trenger du mer enn BMP-støtte.
  • Alt som bruker UTF-16, men som bare kan håndtere smale BMP-tegn, bruker faktisk ikke UTF-16. Det er buggy og ødelagt. Forutsetningen for OP er lyd: UTF-16 er skadelig fordi det fører til at ï har folk til å skrive ødelagt kode. Enten kan du håndtere Unicode-tekst, eller så kan du ikke. Hvis du ikke kan, velger du et delsett, som er like dumt som bare ASCII-tekstbehandling.

Svar

År med internasjonalisering av Windows, spesielt på østasiatiske språk, kan ha ødelagt meg, men jeg lener meg mot UTF-16 for interne representasjoner av strenger og UTF-8 for nettverks- eller fillagring av ren tekst- som dokumenter. UTF-16 kan vanligvis behandles raskere på Windows, slik at det er den viktigste fordelen med å bruke UTF-16 i Windows.

Å gjøre spranget til UTF-16 forbedret dramatikken tilstrekkelig med gjennomsnittlig produkthåndtering internasjonal tekst.Det er bare noen få smale tilfeller når surrogatparene må vurderes (sletting, innsetting og linjebryting, i utgangspunktet) og gjennomsnittssaken er for det meste rett gjennom. Og i motsetning til tidligere kodinger som JIS-varianter, begrenser UTF-16 surrogatpar til et veldig smalt område, så sjekken er veldig rask og fungerer fremover og bakover.

Gitt, den er omtrent like rask i riktig- kodet UTF-8 også. Men det er også mange ødelagte UTF-8 applikasjoner som feilkoder surrogatpar som to UTF-8 sekvenser. Så UTF-8 garanterer ikke frelse heller.

IE håndterer surrogatpar rimelig siden 2000 eller så, selv om det vanligvis konverterer dem fra UTF-8 sider til en intern UTF-16-representasjon; I «Jeg er ganske sikker på at Firefox har fått det riktig også, så jeg bryr meg ikke veldig om hva Opera gjør.

UTF-32 (aka UCS4) er meningsløs for de fleste applikasjoner siden den er så plasskrevende, så det er ganske mye en ikke-startende.

Kommentarer

  • Jeg fikk ikke ' t helt kommentere UTF-8 og surrogatpar. Surrogatpar er bare et begrep som er meningsfylt i UTF-16-kodingen, ikke sant? Kanskje kode som konverterer direkte fra UTF-16-koding til UTF-8-koding, kan få dette feil, og i det i tilfelle problemet er å lese UTF-16 feil, ikke skrive UTF-8. Er det riktig?
  • Det Jason ' snakker om er programvare som implementerer bevisst UTF-8 på den måten: lag et surrogatpar, deretter UTF-8 no kode hver halvdel separat. Det riktige navnet for den kodingen er CESU-8, men Oracle fremstiller den feil som UTF-8. Java benytter en lignende ordning for objektserialisering, men den ' er tydelig dokumentert som " Modifisert UTF-8 " og kun til internt bruk. (Hvis vi bare kunne få folk til å LESE den dokumentasjonen og slutte å bruke DataInputStream # readUTF () og DataOutputStream # writeUTF () uhensiktsmessig …)
  • AFAIK, UTF-32 er fortsatt koding med variabel lengde, og ikke lik UCS4, som er spesifikt område for kodepunktet.
  • @Eonil, UTF-32 vil alltid kunne skilles fra UCS4 hvis vi har en Unicode-standard som har noe som en UCS5 eller større.
  • @JasonTrue Likevel, bare resultatene er like tilfeldig, ikke garantert av design. Samme skjedde i 32-biters minneadressering, Y2K, UTF16 / UCS2. Eller har vi noen garanti for den likheten? Hvis vi har det, vil jeg gjerne bruke det. Men jeg vil ikke ' ikke skrive en mulig knekkbar kode. Jeg skriver en tegnnivåkode, og mangelen på en garantert måte å omkode mellom UTF < – > kodepunktet bugger meg mye .

Svar

UTF-8 er definitivt veien å gå, muligens ledsaget av UTF-32 for intern bruk i algoritmer som trenger tilfeldig tilgang med høy ytelse (men som ignorerer å kombinere tegn).

Både UTF-16 og UTF-32 (samt deres LE / BE-varianter) lider av problemer med endianess, så de aldri brukes eksternt.

Kommentarer

  • Tilfeldig tilgang med konstant tid er også mulig med UTF-8, bare bruk kodenheter i stedet for kodepunkter. Kanskje du trenger virkelig tilfeldig kodepunkttilgang, men jeg ' har aldri sett en brukstilfelle, og du ' er like sannsynlig å ønske deg tilfeldig grafemklyngetilgang i stedet.

Svar

UTF-16? definitivt skadelig. Bare saltkornet mitt her, men det er nøyaktig tre akseptable kodinger for tekst i et program:

  • ASCII: når du arbeider med ting på lavt nivå (f.eks. Mikrokontrollere) som ikke har råd til noe bedre
  • UTF8: lagring i medier med fast bredde, for eksempel filer
  • heltallkodepunkter («CP»?): en matrise med de største heltallene som passer for programmeringsspråket ditt og plattform (forfaller til ASCII i grensen for lave resorces). Bør være int32 på eldre datamaskiner og int64 på hva som helst med 64-biters adressering.

  • Tydeligvis grensesnitt til eldre kodebruk hvilken koding som trengs for å få den gamle koden til å fungere riktig.

Kommentarer

  • @simon buchan, U+10ffff max vil gå ut av vinduet når (ikke hvis) de går tom for kodepunkter. Når det er sagt, er det sannsynligvis trygt å bruke int32 på et p64-system for hastighet, siden jeg tviler på at de ' vil overstige U+ffffffff før du er tvunget til å omskrive koden din for 128-bits systemer rundt 2050. (Det er poenget med " bruk det største intet som er praktisk " i motsetning til " største tilgjengelige " (som sannsynligvis ville være int256 eller bignums eller noe). / li>
  • @David: Unicode 5.2 koder 107.361 kodepunkter.Det er 867.169 ubrukt kodepunkter. " når " bare er tullete. Et Unicode-kodepunkt er definert som et tall fra 0 til 0x10FFFF, en egenskap som UTF-16 er avhengig av. (Også 2050 virker mye for lavt et estimat for 128 bit-systemer når et 64-biters system kan inneholde hele Internett i det ' s adresseplass.)
  • @David: " når " refererte til å gå tom for Unicode-kodepunkter, ikke en 128-bits bryter som, ja, vil være i løpet av de neste århundrene. I motsetning til minne er det ingen eksponentiell vekst av tegn, så Unicode Consortium har spesifikt garantert at de aldri tildeler et kodepunkt over U+10FFFF. Dette er virkelig en av de situasjonene da 21 bits er nok for hvem som helst.
  • @Simon Buchan: I hvert fall til første kontakt. 🙂
  • Unicode pleide å garantere at det ikke ville være noen kodepunkter over U + FFFF også.

Svar

Unicode definerer kodepunkter opp til 0x10FFFF (1 114 112 koder), alle applikasjoner som kjører i flerspråklig miljø med strenger / filnavn osv. skal håndtere det riktig.

Utf-16 : dekker bare 1.112.064 koder. Selv om de på slutten av Unicode er fra fly 15-16 (privat bruksområde). Det kan ikke vokse lenger i fremtiden, bortsett fra å bryte Utf-16 konsept.

Utf-8 : dekker teoretisk 2 216 757 376 koder. Nåværende område av Unicode koder kan representeres av maksimalt 4 byte sekvenser. Det lider ikke med bytebestilling problem, det er «kompatibelt» med ascii.

Utf-32 : dekker teoretisk 2 ^ 32 = 4,294,967,296 koder. Foreløpig er den ikke kodet med variabel lengde og vil sannsynligvis ikke være i fremtiden.

Disse fakta er selvforklarende. Jeg forstår ikke at jeg tar til orde for generell bruk av Utf-16 . Den er kodet med variabel lengde (kan ikke nås med indeks), den har problemer med å dekke hele Unicode selv i øyeblikket, bytebestilling må håndteres osv. Jeg ser ingen fordel bortsett fra at den brukes naturlig i Windows og noen andre steder. Selv om det er sannsynligvis bedre å bruke Utf-8 når du skriver flere plattformskoder og foreta konverteringer bare på sluttpunktene på plattformavhengig måte (som allerede foreslått). Når direkte tilgang via indeks er nødvendig og minne ikke er et problem, bør Utf-32 brukes.

Hovedproblemet er at mange programmerere som arbeider med Windows Unicode = Utf-16 ikke engang vet eller ignorerer det faktum at det er kodet med variabel lengde.

Slik det vanligvis er i * nix plattform er ganske bra, c-strenger (char *) tolket som Utf-8 kodede, brede c-strenger (wchar_t *) tolket som Utf-32 .

Kommentarer

  • Merk: UTF -16 dekker All Unicode da Unicode Consortium bestemte seg for at 10FFFF er TOP-området for Unicode og definerte UTF-8 maksimal lengde på 4 byte og eksplisitt ekskludert område 0xD800-0xDFFF fra gyldig kodepunktområde, og dette området brukes til å lage surrogat par. Så hvilken som helst gyldig Unicode-tekst kan vises med hver av disse kodingene. Også om å vokse til fremtiden. Det ser ikke ut ' at 1 million kodepunkter ikke ville være nok i noen fremtid.
  • @Kerrek: Feil: UCS-2 er ikke en gyldig Unicode koding. Alle UTF- * kodinger per definisjon kan representere ethvert Unicode-kodepunkt som er lovlig for utveksling. UCS-2 kan representere langt færre enn det, pluss noen flere. Gjenta: UCS-2 er ikke en gyldig Unicode-koding, noe mer enn ASCII er.
  • " Jeg forstår ikke å anbefale generell bruk av Utf- 8 . Den er kodet med variabel lengde (kan ikke nås med indeks) "
  • @Ian Boyd, behovet for å få tilgang til en strengs individuelle karakter i et tilfeldig tilgangsmønster utrolig overvurdert. Det er omtrent like vanlig som å ville beregne diagonalen til en matrise av tegn, noe som er super sjeldent. Strenger behandles nesten alltid sekvensielt, og siden tilgang til UTF-8-tegn N + 1 gitt at du er på UTF-8, er tegn N er O (1), er det ikke noe problem. Det er overlegent lite behov for å gjøre tilfeldig tilgang til strenger. Enten du synes det er verdt lagringsplassen å gå til UTF-32 i stedet for UTF-8, er din egen mening, men for meg er det helt et ikke-tema.
  • @tchrist, jeg vil gi strengene dine blir nesten alltid behandlet sekvensielt hvis du inkluderer omvendt iterasjon som " sekvensiell " og strekker det litt videre sammenligning av den bakre enden av en streng til en kjent streng. To veldig vanlige scenarier er å trunke mellomrom fra slutten av strenger og sjekke filtypen på slutten av en bane.

Svar

Legg dette til listen:

Det presenterte scenariet er enkelt (enda enklere da jeg vil presentere det her enn det var opprinnelig! ): 1.En WinForms TextBox sitter på et skjema, tomt. Den har en maks lengde satt til 20 .

2. Brukeren skriver inn i TextBox, eller kanskje limer inn tekst i den.

3. Uansett hva du skriver eller limer inn i TextBox, er du begrenset til 20, selv om den sympatisk piper ved tekst utover 20 (YMMV her; jeg endret lydskjemaet mitt for å gi meg den effekten!).

4.Den lille pakken med tekst blir deretter sendt et annet sted for å starte et spennende eventyr.

Nå er dette et enkelt scenario, og alle kan skrive dette opp på fritiden. Jeg skrev det opp selv på flere programmeringsspråk ved hjelp av WinForms, fordi jeg kjedet meg og hadde aldri prøvd det før. Og med tekst på flere faktiske språk fordi jeg er kablet på den måten og har flere tastaturoppsett enn muligens noen i hele det freaking universet.

Jeg kalte til og med skjemaet Magic Carpet Ride , for å bidra til å forbedre kjedsomheten.

Dette fungerte ikke, for hva det er verdt.

Så i stedet skrev jeg inn følgende 20 tegn til Magic Carpet Ride form:

0123401234012340123 𠀀

Uh oh.

Det siste tegnet er U + 20000, det første Utvidelse B-ideografi til Unicode (aka U + d840 U + dc00, til sine nære venner som han ikke skammer seg over å bli disrovert, som det var, foran) ….

skriv inn bildebeskrivelse her

Og nå har vi et ballspill.

For når TextBox. MaxLength snakker om

Henter eller angir maksimalt antall tegn som kan legges inn manuelt i tekstboksen.

hva det egentlig betyr er

Får eller sett maksimalt antall UTF-16 LE torsk Enheter som kan legges inn i tekstboksen manuelt og vil nådeløst avkutte den levende dritten ut av en hvilken som helst streng som prøver å spille søte spill med den språklige karakterforestillingen om at bare noen som er så besatt som den Kaplan-fyren, vil finne støtende (ga han må kom deg ut mer!).

Jeg prøver å se om å få dokumentet oppdatert ….
Vanlige lesere som husk at UCS-2 til UTF-16 -serien vil merke min ulykke med den enkle forestillingen om TextBox.MaxLength og hvordan det i det minste skal håndtere dette tilfellet der dets drakoniske oppførsel skaper en ulovlig sekvens, en som andre deler av .Net Framework kan kaste et

  • System.Text.EncoderFallbackException : Kan ikke oversette Unicode-tegn \ uD850 ved indeks 0 til spesifisert kodeside. *

unntak hvis du sender denne strengen andre steder i .Net Framework (slik min kollega Dan Thompson gjorde).

Nå greit, kanskje hele UCS-2 til UTF-16-serien er utilgjengelig for mange.
Men er ikke «t det er rimelig å forvente at TextBox.Text ikke vil produsere et System.String som ikke får en annen del av .Net Framework til å kaste? Jeg mener, det er ikke som om det er en sjanse i form av en hendelse på kontrollen som forteller deg om den kommende avkortingen der du enkelt kan legge til den smartere valideringen – validering som kontrollen ikke har noe imot å gjøre. gå så langt som å si at denne punk-kontrollen bryter en sikkerhetskontrakt som til og med kan føre til sikkerhetsproblemer hvis du kan klasse forårsake uventede unntak for å avslutte en applikasjon som en grov nektelse av tjenesten. Hvorfor skal noen WinForms-prosesser eller -metoder eller algoritme eller teknikk gir ugyldige resultater?

Kilde: Michael S.Kaplan MSDN-blogg

Kommentarer

  • Takk, veldig god lenke! Jeg ' har lagt den til i problemlisten i spørsmålet.

Svar

Jeg vil ikke nødvendigvis si at UTF-16 er skadelig. Det er ikke elegant, men det tjener formålet med bakoverkompatibilitet med UCS-2, akkurat som GB18030 gjør med GB2312, og UTF-8 gjør med ASCII.

Men å gjøre en grunnleggende endring i strukturen til Unicode i midstream, etter at Microsoft og Sun hadde bygget enorme API-er rundt 16-biters tegn, var skadelig. Mangelen på å spre bevisstheten om endringen var mer skadelig.

Kommentarer

  • UTF-8 er et supersett av ASCII , men UTF-16 er IKKE et supersett av UCS-2. Selv om det nesten er et supersett, resulterer en korrekt koding av UCS-2 i UTF-8 i avskyen kjent som CESU-8; UCS-2 har ikke ' t surrogater, bare vanlige kodepunkter, så de må oversettes som sådan. Den virkelige fordelen med UTF-16 er at det ' er lettere å oppgradere en UCS-2-kodebase enn en fullstendig omskrivning for UTF-8. Morsomt, va?
  • Visst, teknisk UTF-16 er ikke ' en supersett av UCS-2, men når var U + D800 til U + DFFF noen gang brukt til noe annet enn UTF-16 surrogater?
  • Betyder ikke ' t noe. Enhver annen behandling enn blindgang gjennom bytestream krever at du dekoder surrogatparene, som du kan ' t gjøre hvis du ' behandler det som UCS-2.

Svar

UTF-16 er beste kompromiss mellom håndtering og plass og det er grunnen til at de fleste store plattformer (Win32, Java, .NET) bruker den til intern representasjon av strenger.

Kommentarer

  • -1 fordi UTF-8 sannsynligvis vil være mindre eller ikke vesentlig forskjellig. For visse asiatiske skript er UTF-8 tre byte per tegn mens UTF-16 bare er to, men dette er balansert av at UTF-8 bare er en byte for ASCII (som ofte vises selv innenfor asiatiske språk i produktnavn, kommandoer og slike ting). Videre, i de nevnte språkene, gir en glyf mer informasjon enn et latinsk tegn, så det er berettiget for at det skal ta mer plass.
  • Jeg vil ikke kalle å kombinere wor st sider av begge alternativene et godt kompromiss.
  • Det ' er ikke enklere enn UTF-8. Det ' s også med variabel lengde.
  • Å legge igjen debatter om fordelene med UTF-16 til side: Det du siterte er ikke årsaken til at Windows, Java eller .NET bruker UTF-16. Windows og Java dateres tilbake til en tid der Unicode var en 16-biters koding. UCS-2 var et rimelig valg den gang. Da Unicode ble en 21-biters koding, var migrering til UTF-16 det beste valget eksisterende plattformer hadde. Det hadde ingenting å gjøre med enkel håndtering eller plasskompromisser. Det ' er bare et spørsmål om arv.
  • .NET arver Windows-arven her.

Svar

Jeg har aldri forstått poenget med UTF-16. Hvis du vil ha den mest plasseffektive representasjonen, bruk UTF-8. Hvis du vil være i stand til å behandle tekst som fast lengde, bruk UTF-32. Hvis du ikke vil ha noen av dem, bruk UTF-16. Verre ennå, siden alle de vanlige (grunnleggende flerspråklige planet) tegn i UTF-16 passer inn i et enkelt kodepunkt, feil som antar at UTF-16 har fast lengde vil være subtil og vanskelig å finne, mens hvis du prøver å gjøre dette med UTF-8, vil koden din mislykkes raskt og høyt så snart du prøver å internasjonalisere.

Svar

Siden jeg ennå ikke kan kommentere, legger jeg ut dette som et svar, siden det ser ut til at jeg ellers ikke kan kontakte forfatterne av utf8everywhere.org. Det er synd at jeg ikke automatisk får kommentarprivilegiet, siden jeg har nok rykte på andre stackexchanges.

Dette er ment som en kommentar til Uttalelse: Ja, UTF-16 bør betraktes som skadelig svar.

En liten korreksjon:

For å forhindre at man ved et uhell sender en UTF-8 char* til ANSI-strengversjoner av Windows-API-funksjoner, bør man definere UNICODE, ikke _UNICODE. _UNICODE kartlegger funksjoner som _tcslen til wcslen, ikke MessageBox til MessageBoxW. I stedet tar UNICODE definere seg av sistnevnte. For bevis er dette fra MS Visual Studio 2005 «s WinUser.h header:

#ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE 

I det minste, denne feilen bør rettes på utf8everywhere.org.

Et forslag:

Kanskje guiden skal inneholde et eksempel på eksplisitt bruk av Wide- strengversjon av en datastruktur, for å gjøre det mindre enkelt å savne / glemme det.Bruk av bredstrengede versjoner av datastrukturer i tillegg til bruk av bredstrengede versjoner av funksjoner gjør det enda mindre sannsynlig at man ved et uhell kaller en ANSI-strengversjon av en slik funksjon.

Eksempel på eksempel:

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); } 

Kommentarer

  • Avtalt; Takk! Vi oppdaterer dokumentet. Dokumentet trenger fortsatt mer utvikling og å legge til informasjon om databaser. Vi er glade for å motta formuleringer.
  • @PavelRadzivilovsky _UNICODE er fortsatt der 🙁
  • takk for påminnelsen. Cubus, Jelle, Vil du ha en bruker til SVN?
  • @Pavel Jada, vil sette pris på det!
  • @JelleGeerts: Jeg beklager forsinkelsen. Du kan alltid kontakte oss via e-postene våre (lenket fra manifestet) eller Facebook. Vi er enkle å finne. Selv om jeg mener vi løste problemet du kom hit (og jeg krediterte deg der), er hele UTF-8 vs UTF-16-debattene fortsatt relevante. Hvis du har mer å gjøre bidra til å kontakte oss gjennom disse private kanalene.

Svar

Noen sa UCS4 og UTF-32 var det samme. Nei, men jeg vet hva du mener. En av dem er en koding av den andre, skjønt. Jeg skulle ønske de hadde tenkt å spesifisere endeligheten fra den første, slik at vi ikke ville kjempe endianess-kampen her også. Kunne de ikke sett det komme? I det minste er UTF-8 den samme hverandre re (med mindre noen følger den opprinnelige spesifikasjonen med 6 byte).

Hvis du bruker UTF-16, må du ha til å inkludere håndtering av multibyttegn. Du kan ikke gå til det Nte tegnet ved å indeksere 2N i en byte-matrise. Du må gå på den eller ha tegnindekser. Ellers har du skrevet en feil.

Gjeldende utkastspesifikasjon for C ++ sier at UTF-32 og UTF-16 kan ha små endian, big-endian og uspesifiserte varianter. Egentlig? Hvis Unicode hadde spesifisert at alle måtte gjøre lite endian fra begynnelsen, ville det hele vært enklere. (Jeg hadde også hatt det bra med big-endian.) I stedet implementerte noen det på en måte, noen på den andre, og nå sitter vi fast med tullete for ingenting. Noen ganger er det pinlig å være programvareingeniør.

Kommentarer

  • Uspesifisert endianesse skal inneholde BOM som det første tegnet, brukt til å bestemme hvilken vei strengen skal leses. UCS-4 og UTF-32 er faktisk de samme i dag, dvs. en numerisk UCS-verdi mellom 0 og 0x10FFFF lagret i et 32-biters heltall.
  • @Tronic: Teknisk sett er dette ikke sant. Selv om UCS-4 kan lagre hvilket som helst 32-biters heltall, er UTF-32 forbudt å lagre kodepunktene som ikke er tegn, som er ulovlige for utveksling, for eksempel 0xFFFF, 0xFFFE og alle surrogatene. UTF er en transportkoding, ikke en intern.
  • Endianness-problemer er uunngåelige så lenge forskjellige prosessorer fortsetter å bruke forskjellige byteordrer. Det kunne imidlertid vært fint om det var en " foretrukket " bytebestilling for fillagring av UTF-16.
  • Selv om UTF-32 har fast bredde for kodepunkter , er det ikke fast bredde for tegn . (Hørt om noe som heter " som kombinerer tegn "?) Så du kan ' ikke gå til N ' th tegnet ganske enkelt ved å indeksere 4N i byte-arrayet.

Svar

Jeg synes ikke det er skadelig hvis utvikleren er forsiktig nok.
Og de bør godta denne avtalen hvis de også vet godt.

Som japansk programvareutvikler synes jeg UCS-2 er stor nok og å begrense plassen forenkler tilsynelatende logikken og reduserer kjøretidsminnet, så det er bra nok å bruke utf-16 under UCS-2-begrensning.

Det finnes filsystemer eller andre applikasjoner som antar at kodepunkter og byte er proporsjonale, slik at det rå kodepunktnummeret kan garanteres å passe til noe lagringsplass i fast størrelse.

Et eksempel er NTFS og VFAT som angir UCS-2 som deres koding for lagring av filnavn.

Hvis dette eksemplet virkelig vil utvide for å støtte UCS-4, kan jeg være enig i å bruke utf-8 for alt uansett, men fast lengde har gode poeng som:

  1. kan garanterer størrelsen etter lengde (datastørrelse og kodepunktlengde er proporsjonal)
  2. kan bruke kodingsnummeret for hashoppslag
  3. ikke-komprimerte data er rimelig størrelse (sammenlignet med utf-32 / UCS-4)

I fremtiden når minne / prosessorkraft er billig selv i alle innebygde enheter, kan vi akseptere at enheten er litt treg for ekstra hurtigbuffer eller sidefeil og ekstra minne bruk, men dette vil ikke skje i nær fremtid antar jeg …

Kommentarer

  • For de som leser denne kommentaren, er det verdt å merke seg at UCS- 2 er ikke det samme som UTF-16. Vennligst se på forskjellene for å forstå.

Svar

«Skulle en av de mest populære kodinger, UTF-16, betraktes som skadelige? «

Ganske muligens, men alternativene skal ikke nødvendigvis sees på som mye bedre.

Det grunnleggende problemet er at det er mange forskjellige begreper om: tegn, tegn, kodepunkter og bytesekvenser. Kartleggingen mellom hver av disse er ikke triviell, selv ved hjelp av et normaliseringsbibliotek. (For eksempel er noen tegn på europeiske språk som er skrevet med et latinsk basert skrift ikke skrevet med et eneste Unicode-kodepunkt. Og det er i den enklere enden av kompleksiteten!) Det dette betyr er at for å få alt riktig er ganske utrolig vanskelig; bisarre feil kan forventes (og i stedet for bare å stønne om dem her, fortell vedlikeholdere for den aktuelle programvaren).

Den eneste måten UTF- 16 kan anses å være skadelig i motsetning til, for eksempel, UTF-8 er at den har en annen måte å kode kodepunkter utenfor BMP (som et par surrogater). Hvis kode ønsker å få tilgang til eller gjenta ved hjelp av kodepunkt, det betyr at det må være klar over forskjellen. OTOH, det betyr at en betydelig mengde eksisterende kode som antar «tegn» alltid kan passe inn i en to-byte mengde – en ganske vanlig, hvis feil, antagelse – kan ved minst fortsette å jobbe uten å gjenoppbygge det hele. Med andre ord, i det minste kommer du til se den karakteren s som ikke blir håndtert riktig!

Jeg vil snu spørsmålet ditt på hodet og si at hele den forbannede shebangen til Unicode skal betraktes som skadelig, og alle burde bruke en 8-biters koding, bortsett fra Jeg har sett (i løpet av de siste 20 årene) hvor det fører til: forferdelig forvirring over forskjellige ISO 8859-kodinger, pluss hele settet som ble brukt til kyrillisk, og EBCDIC-pakken, og … vel, Unicode for alle sine feil slår . Hvis bare det ikke var «et så stygt kompromiss mellom forskjellige land» misforståelser.

Kommentarer

  • Å vite lykken vår om noen år ' Vi vil gå tom for plass i UTF-16. Meh.
  • Det grunnleggende problemet er at teksten er villedende vanskelig. Ingen tilnærming til å representere den informasjonen på en digital måte kan være ukomplisert. Det ' er den samme grunnen til at datoer er harde, kalendere er harde, tiden er vanskelig, personnavn er vanskelig, postadressene er vanskelig: når digitale maskiner krysser menneskelige kulturelle konstruksjoner, kompleksitet bryter ut. Det er et faktum i livet. Mennesker fungerer ikke på digital logikk.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *