Răspuns
Acesta este un răspuns vechi.
Consultați UTF-8 pretutindeni pentru ultimele actualizări.
Aviz: Da, UTF-16 ar trebui considerat dăunător . Motivul pentru care există este că, cu ceva timp în urmă, exista o credință greșită că widechar va fi ceea ce este acum UCS-4.
În ciuda „anglo-centrismului” UTF-8, ar trebui considerată singura codificare utilă pentru text. Se poate argumenta că codurile sursă ale programelor, paginilor web și fișierelor XML, numele fișierelor OS și alte interfețe text computer-computer nu ar fi trebuit să existe niciodată. Dar când o fac, textul nu este doar pentru cititorii umani.
Pe de altă parte, cheltuielile generale UTF-8 sunt un preț mic de plătit, în timp ce are avantaje semnificative. Avantajele, cum ar fi compatibilitatea cu codul necunoscut, care trece doar șirurile cu char*
. Acesta este un lucru grozav. Există puține caractere utile care sunt SHORTER în UTF-16 decât în UTF-8.
Cred că toate celelalte codificări vor muri în cele din urmă. Aceasta implică faptul că MS-Windows, Java, ICU, python încetați să-l mai folosiți ca favorit. După cercetări și discuții îndelungate, convențiile de dezvoltare de la compania mea interzic utilizarea UTF-16 oriunde, cu excepția apelurilor API OS, și asta în ciuda importanței de performanță în aplicațiile noastre și faptul că folosim Windows. Funcțiile de conversie au fost dezvoltate pentru a converti mereu-presupus-UTF8 std::string
s în UTF-16 nativ, pe care Windows însuși nu acceptă corect .
Pentru persoanele care spun „ folosește ceea ce este necesar acolo unde este nevoie ”, le spun: există „un avantaj imens de a folosi aceeași codificare peste tot și nu văd niciun motiv suficient pentru a faceți altfel. În special, cred că adăugarea wchar_t
la C ++ a fost o greșeală, la fel și adăugările Unicode la C ++ 0x. Totuși, ceea ce trebuie cerut de la implementările STL este că fiecare Parametrul std::string
sau char*
ar fi considerat compatibil unicode.
Sunt și împotriva opțiunii „ use ceea ce vrei abordare. Nu văd niciun motiv pentru o astfel de libertate. Există suficientă confuzie cu privire la subiectul textului, rezultând tot acest software defect. Acestea fiind spuse mai sus, sunt convins că programatorii trebuie să ajungă în cele din urmă la un consens cu privire la UTF-8 ca un mod adecvat. (Am venit dintr-o țară care nu vorbește despre ascii și am crescut pe Windows, așa că aș fi așteptat să atac ultima dată UTF-16 pe motive religioase).
Aș dori să împărtășesc mai multe informații despre cum fac text pe Windows și ce recomand tuturor celorlalți pentru corectitudinea unicode verificată în timp de compilare, ușurința utilizării și o mai bună platformă a codului. Sugestia diferă în mod substanțial de ceea ce se recomandă de obicei ca mod adecvat de utilizare a Unicode pe Windows. Cu toate acestea, cercetarea aprofundată a acestor recomandări a dus la aceeași concluzie. Deci, iată:
- Nu utilizați
wchar_t
sau std::wstring
în niciun alt loc decât punctul adiacent la API-uri care acceptă UTF-16.
- Nu utilizați
_T("")
sau L""
literele UTF-16 (Acestea ar trebui să fie eliminate din standardul IMO din standard) , ca parte a deprecierii UTF-16).
- Nu utilizați tipuri, funcții sau derivatele lor care sunt sensibile la constanta
_UNICODE
, cum ar fi LPTSTR
sau CreateWindow()
.
- Totuși,
_UNICODE
este întotdeauna definit, pentru a evitați să treceți char*
șiruri către WinAPI să fie compilate în mod silențios
-
std::strings
și char*
oriunde în program sunt considerate UTF-8 (dacă nu s-a spus altfel)
- Toate șirurile mele sunt
std::string
, deși puteți transmite caractere * sau șir literal convert(const std::string &)
.
-
utilizează doar funcții Win32 care acceptă widechars (LPWSTR
). Niciodată cei care acceptă LPTSTR
sau LPSTR
. Treceți parametrii în acest fel:
::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str())
(Politica folosește funcțiile de conversie de mai jos.)
-
Cu șiruri MFC :
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);
-
Lucrul cu fișiere, nume de fișiere și fstream pe Windows:
- Nu treceți niciodată
std::string
sau const char*
argumente pentru numele fișierului pentru familia fstream
. MSVC STL nu acceptă argumentele UTF-8, dar are o extensie non-standard care ar trebui utilizată după cum urmează:
-
Convertiți argumentele std::string
în std::wstring
cu Utils::Convert
:
std::ifstream ifs(Utils::Convert("hello"), std::ios_base::in | std::ios_base::binary);
Va trebui să manual eliminați conversia, atunci când atitudinea MSVC față de fstream
se modifică.
- Acest cod nu este multi-platformă și poate fi necesar să fie schimbat manual în viitorul
- Pentru mai multe informații, consultați
fstream
caz de cercetare / discuție Unicode.
- Nu produceți niciodată fișiere de ieșire text cu conținut non-UTF8 / li>
- Evitați utilizarea
fopen()
din motive RAII / OOD. Dacă este necesar, utilizați _wfopen()
și convențiile WinAPI de mai sus.
// 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 }
Comentarii
Răspuns
Punctele de cod Unicode nu sunt caractere! Uneori nu sunt nici măcar glife (forme vizuale) .
Câteva exemple:
- Puncte de cod cu cifre romane precum „ⅲ”. (Un singur caracter care arată ca „iii”.)
- Caracterele accentuate precum „á”, care pot fi reprezentate fie ca un singur caracter combinat „\ u00e1”, fie ca un caracter și diacritic separat „\ u0061 \ u0301 „.
- Caractere precum sigma minusculă greacă, care au forme diferite pentru mijlocul (” σ „) și sfârșitul (” ς „) ale pozițiilor cuvântului, dar care ar trebui considerate sinonime pentru căutare.
- Cratime discreționară Unicode U + 00AD, care ar putea sau nu să fie afișată vizual, în funcție de context și care este ignorată pentru căutarea semantică.
Singurele modalități de a obține editare Unicode dreptul este de a utiliza o bibliotecă scrisă de un expert sau de a deveni un expert și de a scrie unul singur. Dacă numărați doar punctele de cod, trăiți într-o stare de păcat.
Comentarii
Răspuns
Există o regulă simplă privind formularul de transformare Unicode (UTF) de utilizat: – utf-8 pentru stocare și comunicare – utf-16 pentru procesarea datelor – ați putea merge cu utf-32 dacă cea mai mare parte a API-ului platformei pe care îl utilizați este utf-32 (comun în lumea UNIX).
Majoritatea sistemelor folosesc astăzi utf-16 (Windows, Mac OS, Java, .NET, ICU , Qt). Consultați și acest document: http://unicode.org/notes/tn12/
Înapoi la „UTF-16 ca dăunător”, Aș spune: cu siguranță nu.
Oamenii cărora le este frică de surogate (crezând că transformă Unicode într-o codificare cu lungime variabilă) nu înțeleg celelalte complexități (mult mai mari) care fac maparea între caractere și un punct de cod Unicode foarte complex: combinarea caracterelor, ligaturilor, selectorilor de variație, caracterelor de control etc.
Doar citiți aici această serie http://www.siao2.com/2009/06/29/9800913.aspx și vedeți cum UTF-16 devine o problemă ușoară.
Comentarii
Răspuns
Da, absolut.
De ce? Are legătură cu exercitarea codului .
Dacă te uiți la aceste statistici de utilizare a punctelor de cod pe un corpus mare de Tom Christiansen, veți vedea că punctele de cod BMP trans-8 biți sunt utilizate mai multe ordine dacă magnitudinea este mai mare decât punctele de cod non-BMP:
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
Luați dictatul TDD: „Codul netestat este codul defect” și reformulați-l ca „codul neexercitat este codul defect” și gândiți-vă cât de des programatorii trebuie să facă față punctelor de cod non-BMP.
Bugurile legate de faptul că nu se ocupă de UTF-16 ca o codificare cu lățime variabilă sunt mult mai susceptibile să treacă neobservate decât bug-urile echivalente din UTF-8 . Unele limbaje de programare încă nu vă garantează că vă oferă UTF-16 în loc de UCS-2, iar unele așa-numitele limbaje de programare la nivel înalt oferă acces la unități de cod în loc de puncte de cod (chiar și C ar trebui să vă ofere acces la puncte de cod dacă utilizați wchar_t
, indiferent de ceea ce unele plat formularele pot face).
Comentarii
Răspuns
Aș sugera că gândirea UTF-16 ar putea fi considerată dăunătoare spune că trebuie să obțineți o o mai bună înțelegere a unicode .
Din moment ce am fost votat în jos pentru că mi-am prezentat opinia cu privire la o întrebare subiectivă, permiteți-mi să explic. Ce anume vă deranjează în legătură cu UTF-16? Ați prefera dacă totul ar fi codat în UTF-8? UTF-7? Sau Cum rămâne cu UCS-4? Desigur, anumite aplicații nu sunt concepute pentru a gestiona fiecare cod de caractere unic – dar sunt necesare, mai ales în domeniul informațiilor globale de astăzi, pentru comunicarea între granițele internaționale.
Dar, într-adevăr, dacă credeți că UTF-16 ar trebui să fie considerat dăunător, deoarece este confuz sau poate fi implementat necorespunzător (unicode poate fi sigur), atunci ce metodă de codificare a caracterelor ar fi considerată nepericuloasă?
EDIT: Pentru a clarifica: De ce considerăm implementările necorespunzătoare ale unui standard o reflectare a calității standardului în sine? După cum au observat alții ulterior, doar pentru că o aplicație folosește un instrument în mod necorespunzător, nu înseamnă că instrumentul în sine este defect. Dacă ar fi cazul, am putea spune probabil lucruri precum „var cuvânt cheie considerat dăunător”, sau „threading considerat dăunător”. Cred că întrebarea confundă calitatea și natura standardului cu dificultățile pe care mulți programatori le au în implementare și folosindu-l corect, ceea ce cred că provin mai mult din lipsa lor de înțelegere a modului în care funcționează unicode, mai degrabă decât unicode în sine.
Comentarii
Răspuns
Nu este nimic în neregulă cu Utf- 16 codificare. Dar limbile care tratează unitățile de 16 biți ca caractere ar trebui probabil să fie considerate prost concepute. A avea un tip numit „char
” care nu reprezintă întotdeauna un personaj este destul de confuz. Deoarece majoritatea dezvoltatorilor se vor aștepta ca un tip de caractere să reprezinte un punct de cod sau un caracter, multe coduri se vor rupe probabil atunci când sunt expuse la caracterele din jurul BMP.
Rețineți însă că chiar și utilizarea utf-32 nu înseamnă că fiecare 32- punctul de cod de biți va reprezenta întotdeauna un caracter. Datorită combinării caracterelor, un caracter real poate consta din mai multe puncte de cod. Unicode nu este niciodată banal.
BTW. Probabil că există aceeași clasă de bug-uri cu platforme și aplicații care se așteaptă ca caracterele să aibă 8 biți, care sunt alimentate cu Utf-8.
Comentarii
Răspuns
Alegerea mea personală este să folosiți întotdeauna UTF-8. Este standardul pentru Linux pentru aproape orice. Este compatibil cu multe aplicații vechi. Există o cheltuială minimă în ceea ce privește spațiul suplimentar utilizat pentru caracterele non-latine față de celelalte formate UTF și există o economie semnificativă în spațiu pentru caracterele latine. Pe web, limbile latine domină suprem și cred că vor avea un viitor previzibil. Și pentru a aborda unul dintre principalele argumente din postarea originală: aproape fiecare programator este conștient că UTF-8 va avea uneori caractere multi-octet în el. Nu toată lumea se ocupă corect de acest lucru, dar sunt de obicei conștienți, ceea ce este mai mult decât se poate spune pentru UTF-16. Dar, desigur, trebuie să îl alegeți pe cel mai potrivit pentru aplicația dvs. Acesta este motivul pentru care există mai mult de unul.
Comentarii
s de ce este folosit atât de mult. Dar ' sunt și eu un fan al UTF-8, de asemenea, nu are probleme cu ordinea de octeți, ceea ce funcționează în avantajul său.
Teoretic, da. În practică există lucruri precum, să zicem, UTF-16BE, ceea ce înseamnă UTF-16 în endian mare fără BOM. Acesta nu este un lucru pe care l-am inventat, acesta este o codificare reală permisă în etichetele ID3v2.4 (etichetele ID3v2 sunt suge, dar, din păcate, sunt utilizate pe scară largă). Și în astfel de cazuri trebuie să definiți endianness extern, deoarece textul în sine nu ' nu conține BOM. UTF-8 este întotdeauna scris într-un singur sens și nu are ' o astfel de problemă.
Nu, UTF-16 nu este mai simplu. Este mai greu. Te induce în eroare și te înșeală crezând că are o lățime fixă. Toate aceste coduri sunt rupte și toate acestea, deoarece nu observați până nu este prea târziu. CAZ ÎN PUNCT: Tocmai am găsit încă o eroare stupidă UTF-16 în bibliotecile de bază Java ieri, de data aceasta în String.equalsIgnoreCase, care a fost lăsată în UCS-2 braindeath buggery și deci nu reușește la 16/17 puncte de cod Unicode valide. De cât timp există acel cod? Nicio scuză pentru a fi buggy. UTF-16 duce la prostie și la un accident care așteaptă să se întâmple. Rulați tipând de la UTF-16.
@tchrist Unul trebuie să fie un dezvoltator foarte ignorant pentru a nu ști că UTF-16 nu are o lungime fixă. Dacă începeți cu Wikipedia, veți citi următoarele în partea de sus: " Produce un rezultat de lungime variabilă, fie unul, fie două unități de cod pe 16 biți per punct de cod ". Întrebările frecvente Unicode spune același lucru: unicode.org/faq//utf_bom.html#utf16-1 . Nu ' nu știu cum UTF-16 poate înșela pe oricine dacă este scris peste tot că are o lungime variabilă. În ceea ce privește metoda, ea nu a fost niciodată concepută pentru UTF-16 și nu ar trebui să ' să fie considerată Unicode, la fel de simplă ca asta.
@tchrist Aveți un sursă pentru statisticile dvs.? Deși dacă programatorii buni sunt puțini, cred că este bine, pentru că devenim mai valoroși. 🙂 În ceea ce privește API-urile Java, părțile bazate pe caractere pot fi în cele din urmă depreciate, dar aceasta nu este o garanție că nu vor fi utilizate '. Și cu siguranță nu vor fi ' să nu fie eliminați din motive de compatibilitate.
Răspuns
Ei bine, există o codificare care utilizează simboluri de dimensiuni fixe. Cu siguranță mă refer la UTF-32. Dar 4 octeți pentru fiecare simbol reprezintă prea spațiu pierdut, de ce l-am folosi în situații de zi cu zi?
În opinia mea, cele mai multe probleme apar din faptul că unele programe au căzut în spatele standardului Unicode, dar nu s-au grăbit să corecteze situația. Opera, Windows, Python, Qt – toate au apărut înainte ca UTF-16 să devină cunoscut sau chiar să intre în existență. Totuși, pot confirma că în Opera, Windows Explorer și Notepad nu mai există probleme cu caracterele din afara BMP (cel puțin pe computerul meu). Dar oricum, dacă programele nu recunosc perechi surogate, atunci nu folosesc UTF-16. Indiferent de problemele care apar din tratarea unor astfel de programe, nu au nimic de-a face cu UTF-16 în sine.
Cu toate acestea, cred că problemele software-urilor vechi cu suport BMP sunt oarecum exagerate. Personajele din afara BMP sunt întâlnite numai în cazuri și zone foarte specifice. Conform Întrebări frecvente oficiale Unicode , „chiar și în textul din Asia de Est, incidența perechilor surogate ar trebui să fie cu mult mai mică de 1% din media stocării textului în medie”.Desigur, caracterele din afara BMP nu ar trebui neglijate deoarece un program nu este conform Unicode, dar majoritatea programelor nu sunt destinate să lucreze cu texte care conțin astfel de caractere. De aceea, dacă nu fac acest lucru ” Nu o susține, este neplăcut, dar nu o catastrofă.
Acum, să luăm în considerare alternativa. Dacă UTF-16 nu ar exista, atunci nu am avea o codificare care să fie potrivită pentru textul care nu este ASCII și tot software-ul creat pentru UCS-2 ar trebui să fie complet reproiectat pentru a rămâne conform Unicode. Cel din urmă, cel mai probabil, ar încetini adoptarea Unicode. De asemenea, nu am fi reușit să menținem compatibilitatea cu textul din UCS-2, așa cum face UTF-8 în legătură cu ASCII.
Acum, lăsând deoparte toate problemele vechi, care sunt argumentele împotriva codificării Într-adevăr, mă îndoiesc că dezvoltatorii din zilele noastre nu știu că UTF-16 are o lungime variabilă, este scris peste tot, pornind de la Wikipedia. UTF-16 este mult mai puțin dificil de analizat decât UTF-8, dacă cineva a subliniat complexitatea ca o posibilă problemă. De asemenea, este greșit să ne gândim că este ușor să ne deranjăm determinând lungimea șirului doar în UTF-16. Dacă utilizați UTF-8 sau UTF-32, tot ar trebui să știți că un punct de cod Unicode nu înseamnă neapărat un caracter. În afară de asta, nu cred că există ceva substanțial împotriva codificării.
Prin urmare, nu cred că codificarea în sine ar trebui considerată dăunătoare. UTF-16 este un compromis între simplitate și compactitate și nu există niciun rău în folosind ceea ce este necesar acolo unde este necesar În unele cazuri, trebuie să rămâneți compatibil cu ASCII și aveți nevoie de UTF-8, în unele cazuri doriți să lucrați cu ideografe Han și să conservați spațiu utilizând UTF-16, în unele cazuri, aveți nevoie de reprezentări universale ale caracterelor pentru a marca -codificare de lungime. Folosiți ceea ce este mai potrivit, faceți-o corect.
Comentarii
Răspuns
Anii de internaționalizare a Windows-ului, în special în limbile din Asia de Est, m-ar fi putut corupe, dar mă aplec spre UTF-16 pentru reprezentări interne ale programului de șiruri și UTF-8 pentru stocarea în rețea sau fișier de text simplu ca documentele. Totuși, UTF-16 poate fi procesat mai rapid pe Windows, astfel încât acesta este principalul avantaj al utilizării UTF-16 în Windows.
Saltul la UTF-16 a îmbunătățit dramatic adecvarea manipulării medii a produselor text internațional.Există doar câteva cazuri înguste când trebuie luate în considerare perechile surogate (ștergeri, inserții și întreruperi de linie, practic), iar cazul mediu este în mare parte direct. Și spre deosebire de codificările anterioare, cum ar fi variantele JIS, UTF-16 limitează perechile surogate la un interval foarte restrâns, astfel încât verificarea este foarte rapidă și funcționează înainte și înapoi.
Acordat, este aproximativ la fel de rapid în corect- au codat și UTF-8. Dar există și multe aplicații UTF-8 rupte care codifică incorect perechi surogate ca două secvențe UTF-8. Așadar, UTF-8 nu garantează nici mântuirea.
IE gestionează perechile surogate în mod rezonabil din 2000 sau cam așa ceva, chiar dacă de obicei le convertește din paginile UTF-8 într-o reprezentare UTF-16 internă; I „Sunt destul de sigur că și Firefox a reușit, așa că nu-mi pasă cu adevărat ce face Opera.
UTF-32 (aka UCS4) este inutil pentru majoritatea aplicațiilor, deoarece este atât de solicitant de spațiu, deci este practic un nonstarter.
Comentarii
Răspuns
UTF-8 este cu siguranță calea de urmat, posibil însoțită de UTF-32 pentru intern utilizați în algoritmi care au nevoie de acces aleatoriu de înaltă performanță (dar care ignoră caracterele combinate).
Atât UTF-16, cât și UTF-32 (precum și variantele lor LE / BE) suferă de probleme finale, așa că ar trebui să nu fie niciodată utilizat extern.
Comentarii
Răspuns
UTF-16? categoric dăunătoare. Doar bobul meu de sare aici, dar există exact trei codificări acceptabile pentru text într-un program:
- ASCII: atunci când se ocupă de lucruri de nivel scăzut (de exemplu: microcontrolere) care nu-și pot permite nimic mai bun
- UTF8: stocare pe suporturi cu lățime fixă, cum ar fi fișiere
-
puncte de cod întregi („CP”?): o matrice de cele mai mari numere întregi care sunt convenabile pentru limbajul de programare și platformă (se descompune la ASCII în limita resorțiilor reduse). Ar trebui să fie int32 pe computerele mai vechi și int64 pe orice element cu adresare pe 64 de biți.
-
Evident, interfețele pentru utilizarea codului vechi ce codare este necesară pentru ca vechiul cod să funcționeze corect.
Comentarii
Răspuns
Unicode definește punctele de cod până la 0x10FFFF (1.114.112 coduri), toate aplicațiile rulând în mediu multilingv cu șiruri / nume de fișiere etc. ar trebui să se descurce corect.
Utf-16 : acoperă doar 1.112.064 coduri. Deși cele de la sfârșitul Unicode provin din planurile 15-16 (Zona de utilizare privată). Nu poate crește în viitor, cu excepția ruperii conceptului Utf-16 .
Utf-8 : acoperă teoretic 2.216.757.376 coduri. Intervalul actual de coduri Unicode poate fi reprezentat prin secvență de maximum 4 octeți. Nu suferă cu ordinea de octeți problemă, este „compatibil” cu ascii.
Utf-32 : acoperă teoretic 2 ^ 32 = 4.294.967.296 coduri. În prezent nu este codificat cu lungime variabilă și probabil că nu va mai fi în viitor.
Aceste fapte se explică de la sine. Nu înțeleg susținerea utilizării generale a Utf-16 . Este codificat cu lungime variabilă (nu poate fi accesat prin index), are probleme pentru a acoperi întreaga gamă Unicode chiar și în prezent, ordinea de octeți trebuie gestionată etc. Nu văd niciun avantaj, cu excepția faptului că este folosit în mod nativ în Windows și în alte locuri. Chiar dacă la scrierea codului cu mai multe platforme este probabil mai bine să utilizați în mod nativ Utf-8 și să faceți conversii numai la punctele finale în mod dependent de platformă (așa cum sa sugerat deja). Când este necesar accesul direct prin index și memoria nu este o problemă, ar trebui să se utilizeze Utf-32 .
Problema principală este că mulți programatori care se ocupă de Windows Unicode = Utf-16 nici măcar nu știu sau ignoră faptul că este codificat cu lungime variabilă.
Modul în care este de obicei în platforma * nix este destul de bun, șiruri c (char *) interpretate ca Utf-8 codate, șiruri largi c (wchar_t *) interpretate ca Utf-32 .
Comentarii
Răspuns
Adăugați acest lucru la listă:
Scenariul prezentat este simplu (chiar mai simplu, deoarece îl voi prezenta aici decât era inițial! ): 1. O WinForms TextBox stă pe un formular, gol. Are o MaxLength setată la 20 .
2. Utilizatorul tastează în TextBox sau poate lipiți textul în acesta.
3. Indiferent de ce tastați sau lipiți în TextBox, sunteți limitat la 20, deși va emite un ton simpatic la text peste 20 (YMMV aici; mi-am schimbat schema sonoră să-mi dea acel efect!).
4. Micul pachet de text este apoi trimis în altă parte, pentru a începe o aventură interesantă.
Acum acesta este un scenariu ușor și oricine poate scrie acest lucru în timpul liber. Tocmai l-am scris eu în mai multe limbaje de programare folosind WinForms, pentru că mă plictiseam și nu mai încercasem niciodată. Și cu text în mai multe limbi reale, pentru că sunt conectat în acest fel și am mai multe planuri de tastatură decât oricine din întregul univers ciudat.
Am denumit chiar forma Magic Carpet Ride , pentru a ajuta la ameliorarea plictiselii.
Acest lucru nu a funcționat, pentru ceea ce merită.
Deci, în schimb, am introdus următorul 20 caractere în Magic Carpet Ride forma:
0123401234012340123 𠀀
Uh oh.
Ultimul caracter este U + 20000, primul Ideografia extensiei B a Unicode (cunoscută și sub numele de U + d840 U + dc00, către prietenii apropiați cărora nu îi este rușine să fie dezbrăcat, așa cum ar fi, în fața) ….
Și acum avem un joc cu mingea.
Pentru că atunci când TextBox. MaxLength vorbește despre
Obține sau setează numărul maxim de caractere care pot fi introduse manual în caseta de text.
ceea ce înseamnă cu adevărat este
Obține sau setează numărul maxim de cod UTF-16 LE Unitățile care pot fi introduse manual în caseta de text și vor trunchia fără milă mizeria vie din orice șir care încearcă să joace jocuri drăguțe cu noțiunea de caracter lingvistic că doar cineva la fel de obsedat ca acel tip Kaplan va găsi jignitor ieșiți mai mult!).
Voi încerca să văd actualizarea documentului ….
Cititori obișnuiți care amintiți-vă că seriile mele UCS-2 la UTF-16 vor nota nefericirea mea cu noțiunea simplistă de TextBox.MaxLength și modul în care ar trebui să gestioneze cel puțin acest caz în care comportamentul său draconian creează o secvență ilegală, pe care alte părți ale .Net Framework ar putea să o arunce
- System.Text.EncoderFallbackException : Nu se poate traduce caracterul Unicode \ uD850 la indexul 0 în pagina de cod specificată. *
excepție dacă treceți acest șir altundeva în .Net Framework (așa cum făcea colegul meu Dan Thompson).
Acum bine, poate că completă din seria UCS-2 până la UTF-16 nu este la îndemâna multora.
Dar nu este „Nu este rezonabil să ne așteptăm ca TextBox.Text să nu producă un System.String care să nu câștige„ să provoace o altă parte din .Net Framework? Adică, nu este ca și cum ar fi o șansă sub forma unui eveniment pe control care să vă spună despre viitoarea tăiere în care puteți adăuga cu ușurință validarea mai inteligentă – validare pe care controlul în sine nu o deranjează să o facă. mergeți atât de departe încât să spuneți că acest control punk încalcă un contract de siguranță care ar putea duce chiar la probleme de securitate dacă puteți clasa provocând excepții neașteptate pentru a rezilia o aplicație ca un fel brut de refuz de serviciu. De ce ar trebui să fie proces sau metodă WinForms sau algoritmul sau tehnica produc rezultate nevalide?
Sursa: Michael S.Kaplan MSDN Blog
Comentarii
Răspuns
Nu aș spune neapărat că UTF-16 este dăunător. Nu este elegant, dar își servește scopul de a fi compatibil înapoi cu UCS-2, la fel cum GB18030 face cu GB2312 și UTF-8 cu ASCII.
Dar modificarea fundamentală a structurii Unicode în mijlocul curentului, după ce Microsoft și Sun au construit API-uri imense în jurul caracterelor de 16 biți, a fost dăunătoare. Eșecul de a răspândi gradul de conștientizare a modificării a fost mai dăunător.
Comentarii
Răspuns
Răspuns
Nu „am înțeles niciodată punctul UTF-16. Dacă doriți cea mai eficientă reprezentare spațială, utilizați UTF-8. Dacă doriți să puteți tratați textul ca pe o lungime fixă, utilizați UTF-32. Dacă nu doriți niciuna, folosiți UTF-16. Mai rău, deoarece toate caracterele comune (plan multilingv de bază) din UTF-16 se potrivesc într-un singur punct de cod, erori faptul că UTF-16 are o lungime fixă va fi subtil și greu de găsit, în timp ce dacă încercați să faceți acest lucru cu UTF-8, codul dvs. va eșua rapid și tare imediat ce încercați să internaționalizați.
Răspuns
Deoarece nu pot încă să comentez, postez acest lucru ca răspuns, deoarece se pare că nu pot contacta altfel autorii utf8everywhere.org
. Este păcat că nu primesc automat privilegiul de comentariu, deoarece am suficientă reputație în alte schimburi stack.
Aceasta se înțelege ca un comentariu la Aviz: Da, UTF-16 ar trebui considerat dăunător răspuns.
O mică corecție:
Pentru a preveni trecerea accidentală a unui UTF-8 char*
în versiunile șirului ANSI ale funcțiilor Windows-API, ar trebui definiți UNICODE
, nu _UNICODE
. _UNICODE
mapează funcții precum _tcslen
la wcslen
, nu MessageBox
la MessageBoxW
. În schimb, definirea UNICODE
se ocupă de aceasta din urmă. Pentru dovadă, acesta este din antetul MS Visual Studio 2005 „s WinUser.h
:
#ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE
Cel puțin, această eroare ar trebui corectată pe utf8everywhere.org
.
O sugestie:
Poate că ghidul ar trebui să conțină un exemplu de utilizare explicită a Wide- versiunea șir a unei structuri de date, pentru a face mai puțin ușor să o ratezi / să o uiți.Folosirea versiunilor cu structuri de date cu caractere largi, în plus față de utilizarea versiunilor cu funcții cu caractere largi, face chiar mai puțin probabil ca cineva să apeleze accidental o versiune de tip ANSI a unei astfel de funcții.
Exemplu de exemplu:
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); }
Comentarii
Răspuns
Cineva a spus că UCS4 și UTF-32 sunt La fel, nu, dar știu la ce te referi. Una dintre ele este o codificare a celeilalte, totuși. Aș vrea să se fi gândit să precizeze endianitatea încă din prima, astfel încât să nu avem bătălia fără sfârșit și aici. Nu ar fi putut să vadă că vine? Cel puțin UTF-8 este același oricând re (cu excepția cazului în care cineva urmărește specificația originală cu 6 octeți).
Dacă utilizați UTF-16, trebuie să includeți gestionarea caracterelor multibyte. Nu puteți merge la caracterul al N-lea indexând 2N într-o matrice de octeți. Trebuie să îl parcurgeți sau să aveți indici de caracter. În caz contrar, ați scris o eroare.
Specificația curentă a proiectului C ++ spune că UTF-32 și UTF-16 pot avea variante little-endian, big-endian și nespecificate. Într-adevăr? Dacă Unicode ar fi specificat că toată lumea ar trebui să facă little-endian de la început, atunci ar fi fost mai simplu. (Aș fi fost bine și cu big-endianul.) În schimb, unii oameni l-au implementat într-un fel, altele în altul, iar acum „suntem lipiți de prostie pentru nimic. Uneori este jenant să fii inginer software.
Comentarii
Răspuns
Nu cred că este dăunător dacă dezvoltatorul este suficient de atent.
Și ar trebui să accepte această schimbare dacă știu și ei bine.
În calitate de dezvoltator de software japonez, consider că UCS-2 este suficient de mare și limitarea spațiului aparent simplifică logica și reduce memoria de rulare, astfel încât utilizarea utf-16 sub limitarea UCS-2 este suficient de bună.
Există un sistem de fișiere sau altă aplicație care presupune că punctele de cod și octeții sunt proporționali, astfel încât numărul de punct de cod brut poate fi garantat pentru a se potrivi cu o anumită dimensiune de stocare.
Un exemplu este NTFS și VFAT care specifică UCS-2 ca codificare a stocării numelui de fișier.
Dacă aceste exemple doresc cu adevărat să se extindă pentru a susține UCS-4, aș putea fi de acord să folosesc utf-8 pentru orice, dar lungimea fixă are puncte bune, cum ar fi:
- garantează dimensiunea în funcție de lungime (dimensiunea datelor și lungimea punctului de cod sunt proporționale)
- pot utiliza numărul de codificare pentru căutare hash
- datele necomprimate sunt dimensionate în mod rezonabil (comparativ cu utf-32 / UCS-4)
În viitor, când puterea de memorie / procesare este ieftină chiar și pe orice dispozitive încorporate, putem accepta ca dispozitivul să fie cam lent pentru pierderi suplimentare de cache sau defecțiuni de pagină și memorie suplimentară utilizare, dar acest lucru nu se va întâmpla în viitorul apropiat, cred …
Comentarii
Răspuns
„Ar trebui să fie unul dintre cele mai populare codificările, UTF-16, sunt considerate dăunătoare? „
Este posibil, dar alternativele nu trebuie neapărat privite ca fiind mult mai bune.
Problema fundamentală este că există multe concepte diferite despre: glifi, caractere, puncte de cod și secvențe de octeți. Cartarea dintre fiecare dintre acestea este non-banală, chiar și cu ajutorul unei biblioteci de normalizare. (De exemplu, unele caractere în limbile europene care sunt scrise cu un script bazat pe latină nu sunt scrise cu un singur punct de cod Unicode. Și „este la capătul mai simplu al complexității!) Ceea ce înseamnă asta este că pentru a obține totul corect este destul de uimitor de dificil; sunt de așteptat erori bizare (și, în loc să vă plângeți doar despre ele aici, spuneți întreținătorilor software-ului în cauză).
Singurul mod în care UTF- 16 poate fi considerat dăunător, spre deosebire de, să zicem, UTF-8 este că are un mod diferit de codificare a punctelor de cod în afara BMP (ca o pereche de surogate). Dacă codul dorește să acceseze sau să itereze prin punct de cod, asta înseamnă că trebuie să fie conștient de diferență. OTOH, înseamnă că un corp substanțial de cod existent care presupune „caractere” poate fi întotdeauna încadrat într-o cantitate de doi octeți – o presupunere destul de comună, dacă este greșită – cel puțin continuați să lucrați fără a reconstrui totul. Cu alte cuvinte, cel puțin veți vedea acele personaje Nu sunt corect rezolvate!
Mi-aș întoarce întrebarea și aș spune că întregul blestem al lui Unicode ar trebui considerat dăunător și toată lumea ar trebui să folosească o codificare pe 8 biți, cu excepția Am văzut (în ultimii 20 de ani) unde duce: confuzie oribilă asupra diferitelor codificări ISO 8859, plus întregul set de coduri utilizate pentru chirilică și suita EBCDIC și … ei bine, Unicode pentru toate defectele sale . Dacă nu ar fi fost un „compromis atât de urât între diferite țări” neînțelegeri.
Comentarii