Megjegyzések
- Nem igazán helyesek. Megmagyarázom, ha " שָׁ " azt az összetett karaktert írja, amely " ש ", " ָ " és " ׁ ", vovels, majd mindegyik eltávolítása logikus, egy kódpontot eltávolít, amikor megnyomja a " visszalépést " és távolítsa el az összes karaktert, beleértve a magánhangzókat is, ha megnyomja a " del " gombot. De soha nem hoz létre illegális szövegállapotot – illegális kódpontokat. Így helytelen az a helyzet, amikor megnyomja a visszalépést és az illegát szöveget kapja.
- CiscoIPPhone: Ha egy hibát " többször is jelentettek, sok ember által ", majd pár évvel később egy fejlesztő azt írja a dev blogon, hogy " Hiszed vagy sem, a viselkedés többnyire szándékos! ", akkor (finoman szólva) hajlamos vagyok azt gondolni, hogy ' valószínűleg nem ez a valaha született legjobb tervezési döntés. 🙂 Csak azért, mert ' szándékos nem ' nem azt jelenti, hogy ' nem egy hiba.
- Remek bejegyzés. Az UTF-16 valóban a " mindkét világ legrosszabbja ": Az UTF8 változó hosszúságú, az Unicode egészét lefedi, transzformációs algoritmust igényel a nyers kódpontokig és onnan, az ASCII-re korlátozódik, és endianitásbeli problémái nincsenek. Az UTF32 fix hosszúságú, nem igényel átalakítást, de több helyet foglal el, és endianitásbeli problémái vannak. Eddig nagyon jó, az UTF32-et belsőleg, az UTF8-at pedig a sorosításhoz használhatja. De az UTF16-nak nincsenek előnyei: ' endiánfüggő, ' változó hosszúságú, sok helyet foglal el, ez ' s nem ASCII-kompatibilis. Az UTF16 megfelelő kezeléséhez szükséges erőfeszítéseket jobban el lehetne költeni az UTF8-ra.
- @Ian: Az UTF-8 NEM ugyanazok a figyelmeztetések, mint az UTF-8. Az UTF-8-ban nem lehet helyettesítő. Az UTF-8 nem maszkírozza, mint valami, de az UTF-16-ot használó legtöbb programozó rosszul használja. Tudom. <
újra és újra és újra és újra figyeltem őket.
Válasz
Ez egy régi válasz.
Lásd: UTF-8 mindenhol a legfrissebb frissítésekért.
vélemény: Igen, az UTF-16-ot károsnak kell tekinteni . Éppen azért létezik, mert egy ideje téves vélekedés volt arról, hogy a widechar az lesz, ami most az UCS-4.
Az UTF-8 “anglo-centrizmusa” ellenére a szöveg egyetlen hasznos kódolásának kell tekinteni. Azt állíthatjuk, hogy a programok, weblapok és XML fájlok forráskódjainak, az operációs rendszer fájlneveinek és más számítógép-számítógép szöveges interfészeknek soha nem kellett volna létezniük. De amikor igen, akkor a szöveg nem csak az emberi olvasók számára szól.
Másrészt az UTF-8 rezsicsökkentés alacsony ár, miközben jelentős előnyökkel jár. Előnyök, például kompatibilitás a nem tudatos kódokkal, amelyek csak átengedik a karakterláncokat a char*
karakterlánccal. Ez nagyszerű dolog. Kevés olyan hasznos karakter van, amelyek RÖVIDEBBEK az UTF-16-ban, mint az UTF-8-ban.
Úgy gondolom, hogy az összes többi kódolás végül elpusztul. Ez magában foglalja az MS-Windows, Java, ICU, python ne használja tovább kedvencként. Hosszas kutatások és beszélgetések után a cégemnél alkalmazott fejlesztési egyezmények betiltják az UTF-16 használatát bárhol, kivéve az OS API hívásokat, és ez a fontosság ellenére az alkalmazásunk teljesítménye és a Windows használata. Konverziós függvényeket fejlesztettek ki a mindig feltételezett UTF8 std::string
s átalakítására natív UTF-16-ra, amelyet maga a Windows nem támogatja megfelelően .
Azoknak az embereknek, akik azt mondják, hogy „ használd, amire szükség van, ahol szükséges ”, azt mondom: óriási előnye van annak, ha mindenhol ugyanazt a kódolást használjuk, és nem látok elegendő okot arra, hogy tegyenek másként. Különösen azt gondolom, hogy a wchar_t
hozzáadása a C ++ -hoz hiba volt, és ugyanígy az Unicode-kiegészítések is a C ++ 0x-hez. Bár az STL-implementációktól meg kell követelni, hogy minden A std::string
vagy a char*
paraméter unicode-kompatibilisnek tekinthető.
Én is ellenzem a “ use” -t mit akarsz “megközelítés. Nem látok okot az ilyen szabadságra. Elég zavart a szöveg témájában, ami mindezt a megtört szoftvert eredményezi. Miután fentebb említettem, meg vagyok győződve arról, hogy a programozóknak végre egyetértésre kell jutniuk az UTF-8-mal kapcsolatban, mint az egyik megfelelő módon. (Nem aszkii nyelvű országból származom, és Windows rendszeren nőttem fel, így utoljára várhatóan az UTF-16 elleni támadást várnám vallási alapon).
Szeretnék több információt megosztani arról, hogyan csinálok szöveget a Windows rendszeren, és mit ajánlok mindenki másnak a fordítás idején ellenőrzött unicode helyességért, egyszerű használatért és a kód jobb multiplatformosságáért. A javaslat lényegesen eltér attól, amit általában az Unicode Windows rendszeren történő használatának megfelelő módjaként javasolnak. Mégis, ezen ajánlások alapos kutatása ugyanezt a következtetést vonta le. Így jár:
- Ne használja a
wchar_t
vagy astd::wstring
elemet a szomszédos ponttól eltérő helyen Az UTF-16-ot elfogadó API-k. - Ne használja
_T("")
vagyL""
UTF-16 literálokat (ezeket az IMO-t ki kell venni a szabványból , az UTF-16 megszüntetésének részeként). - Ne használja a
_UNICODE
konstansra érzékeny típusokat, függvényeket vagy származékaikat, például aLPTSTR
vagyCreateWindow()
. - Ennek ellenére
_UNICODE
mindig meghatározták kerülje achar*
karakterláncok átadását a WinAPI számára a csendes fordítás -
std::strings
éschar*
program bármely pontja UTF-8-nak számít (ha másként nem mondjuk) - Az összes karakterláncom
std::string
, bár a char * vagy string karakterláncot átadhatjaconvert(const std::string &)
. -
csak olyan Win32-függvényeket használjon, amelyek elfogadják a szélessávú karaktereket (
LPWSTR
). Soha ne fogadja el aLPTSTR
vagy aLPSTR
alkalmazást. A paramétereket így adja át:::SetWindowTextW(Utils::convert(someStdString or "string litteral").c_str())
(A házirend az alábbi konverziós függvényeket használja.)
-
MFC karakterláncokkal :
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);
-
Fájlokkal, fájlnevekkel és fstreamekkel való munka Windows rendszeren:
- Soha ne adja át a
std::string
vagyconst char*
fájlnév-argumentumok afstream
családhoz. Az MSVC STL nem támogatja az UTF-8 argumentumokat, de rendelkezik egy nem szabványos kiterjesztéssel, amelyet a következőképpen kell használni: -
std::string
argumentumok konvertálásastd::wstring
a következővel:Utils::Convert
:std::ifstream ifs(Utils::Convert("hello"), std::ios_base::in | std::ios_base::binary);
Manuálisan kell elvégeznünk távolítsa el a konvertálást, amikor az MSVC hozzáállása a
fstream
hez megváltozik. - Ez a kód nem több platformos, ezért előfordulhat, hogy manuálisan kell megváltoztatni a jövő
- További információért tekintse meg a
fstream
unicode 4215-ös kutatási / megbeszélési esetet. - Soha ne állítson elő szöveges kimeneti fájlokat nem UTF8 tartalommal
- RAII / OOD okokból kerülje az
fopen()
használatát. Ha szükséges, használja a fenti_wfopen()
és WinAPI konvenciókat.
- Soha ne adja át a
// 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 }
megjegyzések
- nem tudok ' egyetérteni. Az utf16 előnyei az utf8-mal szemben sok ázsiai nyelv esetében teljesen uralják az Ön által tett pontokat. Naivitás azt remélni, hogy a japánok, a thaiföldi, a kínai stb. Feladják ezt a kódolást. A karakterkészletek közötti problematikus ütközések akkor fordulnak elő, amikor a karakterek többnyire hasonlónak tűnnek, kivéve a különbségeket. Azt javaslom, hogy szabványosítsuk: fix 7 bites: iso-irv-170; 8 bites változó: utf8; 16 bites változó: utf16; 32 bites fix: ucs4.
- @Charles: köszönöm a közreműködést. Igaz, néhány BMP karakter hosszabb az UTF-8-ban, mint az UTF-16-ban. De nézzünk szembe ' vel: a probléma nem a BMP kínai karakterek által elfoglalt bájtokban van, hanem a felmerülő szoftvertervezés összetettségében. Ha egy kínai programozónak egyébként is változó hosszúságú karaktereket kell terveznie, úgy tűnik, hogy az UTF-8 még mindig alacsony árat fizet a rendszer többi változójához képest. Lehet, hogy az UTF-16-ot használja tömörítési algoritmusként, ha a tér annyira fontos, de akkor sem lesz megfelelő az LZ számára, és az LZ vagy más általános tömörítés után körülbelül ugyanolyan méretű és entrópia szükséges.
- Alapvetően azt mondom, hogy elképzelhetetlen az az egyszerűsítés, amelyet a One kódolás kínál, amely kompatibilis a meglévő char * programokkal, és manapság a legnépszerűbb is.Szinte olyan, mint a régi jó " plaintext " napokban. Meg akar nyitni egy nevet tartalmazó fájlt? Nem kell törődni azzal, hogy milyen unicode-ot csinálsz stb. Azt javaslom, hogy mi, fejlesztők, az UTF-16-ot csak a súlyos optimalizálás speciális eseteire korlátozzuk, ahol egy apró teljesítmény emberhónapos munkát ér.
- A Linuxnak sajátos követelménye volt, amikor az UTF-8 belső használatát választotta: kompatibilitás a Unixszal. A Windows-nak nem kellett ' erre szüksége, és így amikor a fejlesztők megvalósították az Unicode-ot, hozzáadták szinte az összes szövegkezelő funkció UCS-2 verzióját, és a többbájtosakat egyszerűen átalakították UCS-2-vé, és hívja a többieket. THey később az UCS-2-et UTF-16-ra cseréli. A Linux viszont tartotta a 8 bites kódolásokat, és így az UTF-8-at használta, mivel ' ez a megfelelő választás ebben az esetben.
- @Pavel Radzivilovsky : BTW, az írásaid a " -ről azt hiszem, hogy az összes többi kódolás végül meghal. Ez azt jelenti, hogy az MS-Windows, a Java, az ICU, a python nem használja kedvencként. " és " Különösen azt gondolom, hogy a wchar_t hozzáadása a C ++ -hoz hiba volt, és a C ++ Ox unicode-os kiegészítései is. " vagy elég naivak, vagy nagyon arrogánsak . És ez olyan embertől származik, aki otthon kódol Linux alatt, és aki elégedett az UTF-8 karakterekkel. Egyenesen fogalmazva: Nem fog ' megtörténni .
Válasz
Az Unicode kódpontok nem karakterek! Néha nem is karakterjelek (vizuális formák) .
Néhány példa:
- római számú kódpontok, például “ⅲ”. (Egyetlen karakter, amely úgy néz ki, mint a “iii”.)
- Kiemelt karakterek, mint az “á”, amelyek akár egyetlen kombinált karakterként “\ u00e1”, akár egy karakterként, és elválasztott diakritikusként “\ u0061 \ u0301 “.
- Olyan karakterek, mint a görög kisbetűs sigma, amelyeknek különböző formái vannak a szópozíciók középső (” σ “) és vége (” ς “) számára, de amelyeket a keresés szinonimáinak kell tekinteni.
- Unicode diszkrecionális kötőjel U + 00AD, amelyet vizuálisan megjeleníthet, vagy nem, a kontextustól függően, és amelyet a szemantikai keresésnél figyelmen kívül hagynak.
Az Unicode szerkesztésének egyetlen módja joga egy szakértő által írt könyvtár használata , vagy szakértővé válás és saját maga írása. Ha csak a kódpontokat számolja, akkor bűn állapotában él.
Megjegyzések
- Ez. Nagyon ezt. Az UTF-16 problémákat okozhat, de még az egész UTF-32 használata is problémákat okozhat (és fog is).
- Mi az a karakter? Meghatározhat egy kódpontot karakterként, és nagyjából jól boldogul. Ha a felhasználó által látható karakterjelre gondolsz, az valami más.
- @tchrist biztos abban, hogy helyet oszt ki, ez a meghatározás rendben van, de bármi másra? Nem túl sok. Ha a kombináló karaktert egyedüli karakterként kezeli (azaz törlés vagy " esetén vegye az első N karaktert " művelethez), akkor ' furcsa és helytelen viselkedést tapasztal. Ha egy kódpontnak csak akkor van jelentése, ha legalább egy másikkal kombináljuk, akkor ' nem kezelheti önmagában bármilyen értelmes módon.
- @Pacerier, ez késő a buliba, de ehhez hozzászólnom kell. Egyes nyelvekben nagyon nagy a kritikák lehetséges kombinációinak halmaza (vö. Vietnami, azaz mệt đừ). Nagyon hasznos, ha a diakritikusban egy karakter helyett kombinációk szerepelnek.
- egy kis megjegyzés a terminológiáról: kódpontok nem felelnek meg az unicode karaktereknek ; amiről Daniel itt beszél, azok a felhasználó által érzékelt karakterek , amelyek megfelelnek az unicode grafémaklasztereknek
Válasz
Egy egyszerű ökölszabály van arra vonatkozóan, hogy az Unicode Transformation Form (UTF) miként használható: – utf-8 tároláshoz és kommunikációhoz – utf-16 adatfeldolgozáshoz – lehet, hogy megy az utf-32-vel, ha a platform API-jainak nagy része utf-32 (a UNIX világában elterjedt).
A legtöbb rendszer ma az utf-16-ot használja (Windows, Mac OS, Java, .NET, ICU (Qt). Lásd még ezt a dokumentumot: http://unicode.org/notes/tn12/
Vissza az “UTF-16 mint káros” oldalra, Azt mondanám: határozottan nem.
Azok, akik félnek a helyettesítőktől (azt gondolva, hogy az Unicode-ot változó hosszúságú kódolássá alakítják át), nem értik a többi (sokkal nagyobb) bonyolultságot, amelyek a karakterek és a karakterek közötti feltérképezést teszik lehetővé. a Nagyon bonyolult Unicode kódpont: karakterek, ligatúrák, variációválasztók, vezérlő karakterek stb. kombinálása.
Olvassa el itt ezt a sorozatot http://www.siao2.com/2009/06/29/9800913.aspx , és megtudhatja, hogyan válik az UTF-16 egyszerű problémává.
Megjegyzések
- Adjon meg néhány példát, ahol az UTF-32 elterjedt a UNIX világában!
- Nem, nem az UTF-16-ot szeretné használni az adatfeldolgozáshoz. ' fájdalmat okoz a szamárban. Megvan az UTF-8 összes hátránya, de egyik előnye sincs. Az UTF-8 és az UTF-32 is egyértelműen felülmúlja a korábban Mrs. UTF-16 néven ismert rosszindulatú hacket, akinek leánykori neve UCS-2 volt.
- Tegnap nemrég találtam egy hibát a Java core String osztályban
equalsIgnoreCase
módszer (a sztring osztály többi tagja is), amely soha nem lett volna ott, ha a Java az UTF-8-at vagy az UTF-32-et használta volna. Ezeknek az alvó bombáknak milliói vannak minden olyan kódban, amely az UTF-16-ot használja, és én beteg vagyok és elegem van belőlük. Az UTF-16 egy gonosz pox, amely alattomos hibákkal sújtja szoftverünket örökkön örökké. Nyilvánvalóan káros, ezért el kell vetni és ki kell tiltani. - @tchrist Wow, tehát nem helyettesítő tudatosságú funkció (mert akkor írták, amikor még nem voltak, és sajnos olyan módon dokumentálják, hogy valószínűleg lehetetlen alkalmazkodni – megadja .toUpperCase (char)) helytelen viselkedést eredményez? ' tudatában van annak, hogy egy elavult kódponttérképpel rendelkező UTF-32 függvény nem kezelné ezt jobban? ' Szintén az egész Java API nem igazán jól kezeli a helyettesítőket, és az Unicode-ot érintő bonyolultabb pontok egyáltalán nem – és a későbbiekben a használt kódolás egyáltalán nem számítana.
- -1: A feltétel nélküli
.Substring(1)
a .NET-ben triviális példa valamire, amely megszakítja az összes nem BMP Unicode támogatást. Minden, ami UTF-16-ot használ, rendelkezik ezzel a problémával; ' túl könnyű fix szélességű kódolásként kezelni, és túl ritkán lát problémákat. Ez aktívan káros kódolássá teszi, ha támogatni kívánja az Unicode-ot.
Válasz
Igen, feltétlenül.
Miért? Ez a kód gyakorlása hoz kapcsolódik.
Ha megnézi ezeket a kódpont használati statisztikákat egy nagy korpuszon Tom Christiansen: látni fogja, hogy a transz-8 bites BMP kódpontokat több sorrendben használják, ha a nagyságrendjük meghaladja a nem BMP kódpontokat:
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
Vegyük a TDD dictumot: “A nem tesztelt kód meghibásodott kód”, és fogalmazza át úgy, hogy “a nem használt kód megszakadt kód”, és gondolja át, milyen gyakran kell a programozóknak megküzdeniük a nem BMP kódpontokkal.
Azok a hibák, amelyek az UTF-16, mint változó szélességű kódolás nem kezelésével kapcsolatosak, sokkal inkább észrevétlenek maradnak, mint az UTF-8 megfelelő hibái . Néhány programozási nyelv továbbra is nem garantálja, hogy az UCS-2 helyett UTF-16-ot kap, és néhány úgynevezett magas szintű programozási nyelv hozzáférést kínál a kódegységekhez a kódpontok helyett (még a C állítólag hozzáférést is biztosít a kódpontokhoz, ha használ wchar_t
, függetlenül attól, hogy egyes plat űrlapok megtehetik).
Megjegyzések
- " Az UTF-16-val nem foglalkozó hibák a változó szélességű kódolás sokkal valószínűbb, hogy észrevétlen marad, mint az UTF-8 megfelelő hibái. " Ez a kérdés lényege, és ezért a helyes válasz.
- Pontosan. Ha az UTF-8 kezelése hibás, ' azonnal nyilvánvaló lesz. Ha az UTF-8 kezelése hibás, ' csak akkor veszi észre, ha nem mindennapi Han karaktereket vagy matematikai szimbólumokat tartalmaz.
- Nagyon igaz, de másrészt kéz, mire szolgálnak az egységtesztek, ha a szerencsétől kell függenie, hogy hibákat talál-e ritkább esetekben?
- @musiphil: Tehát mikor készítettél utoljára egységtesztet nem BMP karakterekre?
- Korábbi kijelentésem részletezésére: még az UTF-8 esetében sem lehet biztos abban, hogy minden esetet lefedett, miután csak néhány működő példát látott. Ugyanez az UTF-16 esetében: tesztelnie kell, hogy a kódja működik-e mind helyettesítőkkel, mind helyettesítőkkel. (Valaki azt állíthatja, hogy az UTF-8-nak legalább négy fő esete van, míg az UTF-16-nak csak kettő van.)
Válasz
Azt javaslom, hogy az UTF-16 gondolkodása károsnak tekinthető, azt mondja, hogy jobban meg kell ismernie az unicode-ot .
Mivel a véleményem szubjektív kérdésben való ismertetésére visszavonultam, hadd fejtsem ki. Pontosan mi zavarja az UTF-16-ot? Szeretné, ha mindent az UTF-8 kódolna? UTF-7? Vagy Mi a helyzet az UCS-4-gyel? Természetesen bizonyos alkalmazásokat nem arra terveztek, hogy minden egyes karakterkódot kezeljenek odakinn – de ezekre szükség van, különösen a mai globális információs területen, a nemzetközi határok közötti kommunikációhoz.
De valójában, ha úgy érzi, hogy az UTF-16-ot károsnak kell tekinteni, mert zavaró vagy helytelenül implementálható (az unicode bizonyára lehet), akkor a karakterkódolás melyik módszere tekinthető nem károsnak?
SZERKESZTÉS: Annak tisztázása érdekében: Miért tekinthető a szabvány nem megfelelő megvalósításának a szabvány minőségének tükröződésének? Mint mások később megjegyezték, pusztán azért, mert egy alkalmazás nem megfelelő módon használ egy eszközt, nem jelenti azt, hogy az eszköz önmagában hibás. Ha ez lenne a helyzet, akkor valószínűleg mondhatnánk olyanokat, mint “ártalmasnak tekintett var kulcsszó” vagy “károsnak tekintett szálak”. Úgy gondolom, hogy a kérdés összekeveri a szabvány minőségét és jellegét a sok programozó nehézségeivel a megvalósítás során és megfelelő használata, ami úgy érzem, inkább abból fakad, hogy nem értik az unicode működését, nem pedig maga az unicode.
Megjegyzések
- -1: Mit szólnál, ha néhány Artyom ' objektumhoz fordulnál nem csak pártfogolni?
- BTW: Amikor elkezdtem írni ezt a cikket, majdnem meg akartam írni " Meg kell fontolóra venni Joelt az Unicode Softeare cikkén? káros ", mert sok hiba van. Például: az utf-8 kódolás legfeljebb 4 karakterből áll, és nem 6-ból. Ezenkívül nem tesz különbséget az UCS-2 és az UTF-16 között, amelyek valóban különböznek egymástól – és valójában okozzák azokat a problémákat, amelyekről beszélek.
- Azt is meg kell jegyezni, hogy amikor Joel megírta ezt a cikket, az UTF-8 szabvány WAS 6 bájt volt, nem pedig 4. Az RFC 3629 a cikk írása után néhány hónappal 4 bájtra változtatta a szabványt. Mint az interneten a legtöbb dolog, érdemes egynél több forrásból olvasni, és tisztában lenni a források korával. A link nem volt ' nem az, amelynek a " véget akarták lenni, hanem mindet " inkább kiindulópont.
- Azokat az utf-8 vagy utf-32 képeket ábrázolnám, amelyek: változó hosszúságú kódolás szinte minden esetben (beleértve a BMP-t is) vagy rögzített hosszúságú kódolás mindig.
- @iconiK: Ne hülyéskedj. Az UTF-16 abszolút nem a szöveg feldolgozásának de facto szabványa. Mutasson nekem egy szövegfeldolgozásra alkalmasabb programozási nyelvet, amelyet a Perl mindig (jól, több mint egy évtized) absztrakt karaktereket használt, amelyek mögöttes UTF-8 reprezentáció volt. Emiatt minden Perl program automatikusan kezeli az összes Unicode kódot anélkül, hogy a felhasználónak állandóan majmolnia kellene idióta helyettesítőkkel. A karakterlánc hossza a kódpontokban való szám, nem pedig a kódegységek száma. Bármi más puszta butaság, ami visszafele kompatibilitást biztosít.
Válasz
Az Utf- 16 kódolás. De azokat a nyelveket, amelyek a 16 bites egységeket karakterként kezelik, valószínűleg rosszul kell megtervezni. A “char
” nevű típus, amely nem mindig képvisel karaktert, meglehetősen zavaró. Mivel a legtöbb fejlesztő elvárja, hogy a char típus egy kódpontot vagy karaktert képviseljen, a kódok nagy része valószínűleg megszakad, ha a karakterek ki vannak téve a BMP-n kívül.
Vegye figyelembe, hogy még az utf-32 használata sem jelenti azt, hogy mindegyik 32- A bit kódpont mindig egy karaktert képvisel. A karakterek kombinálása miatt a tényleges karakter több kódpontból állhat. Az Unicode soha nem triviális.
BTW. Valószínűleg ugyanaz a hibakategória létezik olyan platformokkal és alkalmazásokkal, amelyek a karakterek 8 bitesre számítanak, és amelyeket az Utf-8 táplál.
Megjegyzések
- Java ' esetekben, ha megnézzük az idővonalukat ( java.com/en/javahistory/timeline.jsp), látja, hogy a String elsődleges fejlesztése akkor történt, amikor az Unicode 16 bit volt (1996-ban megváltozott). Rá kellett tenniük a nem BMP kódpontok kezelésének képességét, ezáltal a zavart.
- @Kathy: A C # azonban nem igazán mentség. Általában egyetértek azzal, hogy
CodePoint
típusúnak kell lennie, egyetlen kódponttal (21 bit),CodeUnit
típusúnak, egyetlen kódegységnek (16 bit az UTF-16-hoz) és egyCharacter
típusnak ideális esetben egy teljes grafémát kellene támogatnia. De ez funkcionálisan egyenértékűvé teszi aString
… - Ez a válasz majdnem két éves, de ' nem segítenek, de kommentálják. " ' char ' nevű típus, amely nem mindig képvisel karaktert, elég zavaró. " És mégis az emberek állandóan C-ben és hasonlókban használják az egész bájtban tárolható egész adatok ábrázolására.
- És I ' látott egy tétel C kódot, amely nem megfelelően kezeli a karakterkódolást '.
- A C # -nak más kifogása van: a Windows számára tervezték, a Windows pedig az UCS-2-re épült (ez ' nagyon bosszantó, hogy a Windows API-k ma sem képesek UTF-8 támogatás). Ráadásul azt gondolom, hogy a Microsoft Java kompatibilitást szeretett volna (a .NET 1.0-nak volt Java kompatibilitási könyvtárja, de nagyon gyorsan leállították a Java támogatást – én ' feltételezem, hogy ennek oka a Sun ' pert indítottak az MS ellen?)
Válasz
Személyes választásom: hogy mindig az UTF-8-at használja. Szinte mindenhol ez a szabvány a Linuxon. Visszafelé kompatibilis sok régi alkalmazással. A nem latin karakterekhez felhasznált extra hely nagysága nagyon minimális, szemben a többi UTF formátummal, és jelentős megtakarítás érhető el a latin karakterek számára. Az interneten a latin nyelvek uralkodnak, és azt hiszem, a belátható jövőben is így lesz. És hogy megválaszoljam az eredeti bejegyzés egyik fő érvét: szinte minden programozó tisztában van azzal, hogy az UTF-8 néha több bájtos karaktereket tartalmaz. Nem mindenki foglalkozik ezzel helyesen, de általában tisztában vannak vele, ami több, mint az UTF-16 esetében elmondható. De természetesen ki kell választania az alkalmazásának legmegfelelőbbet. Ez az oka annak, hogy eleve több is van.
Megjegyzések
- Az UTF-16 a BMP-n belül bármire egyszerűbb, hogy ' s miért használják ilyen széles körben. De ' rajongok az UTF-8-ban is, nincsenek problémái a bájtsorrenddel sem, ami az előnyére válik.
- Elméletileg igen. A gyakorlatban vannak olyan dolgok, mint mondjuk az UTF-16BE, ami BOM nélkül jelenti az UTF-16-ot nagy endániában. Ez nem valami, amit kitaláltam, ez egy tényleges kódolás, amelyet az ID3v2.4 címkék engedélyeznek (az ID3v2 címkék szívják, de sajnos széles körben használják őket). Ilyenkor pedig külsőleg kell meghatároznia az endiánságot, mert maga a szöveg nem tartalmaz ' nem BOM-ot. Az UTF-8 mindig egyféleképpen íródott, és ' nincs ilyen problémája.
- Nem, az UTF-16 nem egyszerűbb. Nehezebb. Félrevezeti és megtéveszti, ha azt gondolja, hogy rögzített szélességű. Minden ilyen kód megszakadt, és minden moreso, mert nem veszi észre, amíg nem késő. ESET PONTBAN: Tegnap találtam egy újabb hülye UTF-16 hibát a Java magkönyvtárakban, ezúttal a String.equalsIgnoreCase fájlban, amely az UCS-2 braindeath buggery-ben maradt, és így 16/17 érvényes Unicode kódponton nem sikerül. Mennyi ideje létezik ez a kód? Nincs mentség, hogy hibás. Az UTF-16 puszta ostobasághoz és balesethez vezet, amely bekövetkezik. Futtass sikoltozást az UTF-16-ról.
- @tchrist One nagyon tudatlan fejlesztőnek kell lennie ahhoz, hogy ne tudja, hogy az UTF-16 nem rögzített hosszúságú. Ha a Wikipedia használatával kezdi, akkor a következőket olvassa el a tetején: " Változó hosszúságú eredményt hoz létre, egy vagy két 16 bites kódegységből, kódpontonként id = “4292634e69″>
. Az Unicode GYIK ugyanezt mondja: unicode.org/faq//utf_bom.html#utf16-1 . Nem tudom ', hogy az UTF-16 hogyan csalhat meg senkit, ha mindenhol azt írják, hogy változó hosszúságú. Ami a módszert illeti, soha nem az UTF-16-hoz készült, és nem szabad, hogy ' ne tekinthető ilyen egyszerű Unicode-nak.
Válasz
Nos, van egy kódolás, amely rögzített méretű szimbólumokat használ. Minden bizonnyal az UTF-32-re gondolok. De minden egyes szimbólumhoz 4 bájt túl sok elpazarolt hely, miért használnánk mindennapi helyzetekben?
Véleményem szerint a legtöbb probléma abból adódik, hogy egyes szoftverek elestek az Unicode szabvány mögött, de nem tudták gyorsan kijavítani a helyzetet. Opera, Windows, Python, Qt – mindegyik azelőtt jelent meg, hogy az UTF-16 széles körben ismertté vált, vagy akár létrejött volna. Megerősíthetem azonban, hogy az Operában, a Windows Intézőben és a Jegyzettömbben már nincs probléma a BMP-n kívüli karakterekkel (legalábbis a PC-n). De különben is, ha a programok nem ismerik fel a helyettes párokat, akkor nem használják az UTF-16-ot. Bármilyen probléma is merül fel az ilyen programok kezelésében, semmi közük magához az UTF-16-hoz.
Úgy gondolom azonban, hogy a csak BMP-támogatással rendelkező örökölt szoftverek problémái némiképp túlzottak. A BMP-n kívüli karakterekkel csak nagyon meghatározott esetekben és területeken találkozhatunk. A Unicode hivatalos GYIK szerint “még a kelet-ázsiai szövegekben is a helyettesítő párok előfordulási gyakorisága jóval kevesebb, mint az összes szöveges tárolás 1% -a”.Természetesen a BMP-n kívüli karaktereket nem szabad elhanyagolni , mert egy program egyébként nem Unicode-konform, de a legtöbb programot nem ilyen karaktereket tartalmazó szövegekkel való együttműködésre szánják. Ezért van az, ha nem Támogassuk, kellemetlen, de nem katasztrófa.
Most vegyük fontolóra az alternatívát. Ha az UTF-16 nem létezik, akkor nem rendelkezünk olyan kódolással, amely jól illeszkedik a nem ASCII szövegekhez, és az UCS-2-hez létrehozott összes szoftvert teljesen át kell tervezni, hogy Unicode-kompatibilis maradjon. Ez utóbbi valószínűleg csak lassítja az Unicode elfogadását. Emellett nem tudtuk volna fenntartani az UCS-2 szöveggel való kompatibilitását, mint az UTF-8 az ASCII-vel kapcsolatban.
Most, eltekintve az összes régi problémától, mi az érv a kódolás ellen valójában kétlem, hogy a fejlesztők manapság nem tudják, hogy az UTF-16 változó hosszúságú-e, mindenhol a Wikipédiával kezdve írják. Az UTF-16-ot sokkal kevésbé nehéz elemezni, mint az UTF-8-at, ha valaki a bonyolultságot jelölte meg lehetséges problémaként. Szintén téves azt gondolni, hogy csak az UTF-16-ban könnyű elrontani a húrhossz meghatározásával. Ha UTF-8 vagy UTF-32 rendszert használ, akkor is tisztában kell lennie azzal, hogy egy Unicode kódpont nem feltétlenül jelent egy karaktert. Ezen kívül nem gondolom, hogy a kódolással szemben lenne valami lényeges.
Ezért nem hinném, hogy magát a kódolást is károsnak kellene tekinteni. Az UTF-16 kompromisszum az egyszerűség és a tömörség között, és nem árt abban, amire szükség van, ahol szükséges Bizonyos esetekben kompatibilisnek kell maradnia az ASCII-vel, és szüksége van az UTF-8-ra, egyes esetekben a Han ideográfusokkal szeretne dolgozni, és helyet takaríthat meg az UTF-16 használatával, egyes esetekben a karakterek univerzális reprezentációjára van szükség, amely fixet rögzít -hosszúságú kódolás. Használja a megfelelőbbeket, csak tegye megfelelően.
Megjegyzések
- Ez ' egy meglehetősen pislogott, angolközpontú nézetet, Malcolm. Az " szinte egyenrangú ASCII elég jó az USA számára – a világ többi részének be kellene illeszkednie hozzánk ".
- Valójában én ' m Oroszországból származom, és állandóan cirillákkal találkozom (a saját programjaimat is beleértve), ezért nem ' nem hiszem, hogy anglo-központú nézetem van. 🙂 Az ASCII megemlítése nem egészen helyénvaló, mert ' nem Unicode és nem ' nem támogatja az adott karaktereket. Az UTF-8, UTF-16, UTF-32 ugyanazt a nemzetközi karakterkészletet támogatja, csak a saját területükön való használatra szánják őket. És pontosan ez az én véleményem: ha főleg angolul használ, akkor használja az UTF-8-at, ha főleg cirill betűt, akkor az UTF-16-ot, ha ősi nyelveket, akkor az UTF-32-et. Nagyon egyszerű.
- " Nem igaz, az ázsiai szkriptek, mint például a japán, a kínai vagy az arab, szintén a BMP-hez tartoznak. Maga a BMP valójában nagyon nagy és minden bizonnyal elég nagy ahhoz, hogy tartalmazzon minden manapság használt szkriptet " Ez mind annyira helytelen. A BMP 0xFFFF karaktert tartalmaz (65536). Csak a kínaiaknak van ennél több. A kínai szabványoknak (GB 18030) ennél több van. Az Unicode 5.1 már több mint 100 000 karaktert osztott ki.
- @Marcolm: " Maga a BMP valójában nagyon nagy és bizony elég nagy ahhoz, hogy az összes manapság használt szkriptet tartalmazhassa " Nem igaz. Ezen a ponton az Unicode már körülbelül 100K karaktert rendelt el, vagyis sokkal több, mint a BMP képes elhelyezni. A BMP-n kívül nagy darab kínai karakter található. Néhányukat a GB-18030 (kötelező kínai szabvány) írja elő. Egyéb követelményeket a (nem kötelező) japán és koreai szabványok előírnak. Tehát, ha bármit megpróbál eladni ezeken a piacokon, szüksége van a BMP támogatására.
- Bármi, ami UTF-16-ot használ, de csak keskeny BMP karaktereket képes kezelni, valójában nem használja az UTF-16-ot. Bugos és törött. Az OP előfeltétele megalapozott: az UTF-16 káros, mert na ï ráveszi az embereket a törött kód megírására. Vagy kezelheti az Unicode szöveget, vagy nem. Ha nem tudsz, akkor egy részhalmazt választasz, ami ugyanolyan hülye, mint a csak ASCII-szintű szövegfeldolgozás.
Válasz
A Windows évek óta tartó futtatása, különösen a kelet-ázsiai nyelveken, korrupciót okozhatott, de az UTF-16 felé hajlok a húrok programon belüli megjelenítéséért, az UTF-8 pedig a sima szöveg hálózati vagy fájl tárolásáért. mint a dokumentumok. Az UTF-16 általában gyorsabban feldolgozható Windows rendszeren, így ez az elsődleges előnye az UTF-16 használatának a Windows rendszerben.
Az UTF-16-ra való ugrás drámai módon javította az átlagos termékkezelés megfelelőségét. nemzetközi szöveg.Csak néhány szűk eset van, amikor a helyettes párokat figyelembe kell venni (törlések, beillesztések és vonalvezetés, alapvetően), és az átlagos eset többnyire egyenes áthaladás. És az olyan korábbi kódolásoktól eltérően, mint a JIS-változatok, az UTF-16 nagyon szűk tartományra korlátozza a helyettes párokat, így az ellenőrzés nagyon gyors, előre és hátra működik.
Meg kell adni, hogy nagyjából olyan gyorsan megy be helyesen- kódolt UTF-8 is. De sok olyan megszakadt UTF-8 alkalmazás is van, amelyek helytelenül kódolják a pótpárokat két UTF-8 szekvenciaként. Tehát az UTF-8 sem garantálja az üdvösséget.
Az IE viszonylag jól kezeli a helyettes párokat 2000 óta, annak ellenére, hogy általában az UTF-8 oldalakról belső UTF-16 ábrázolásra konvertálja őket; “Biztos vagyok benne, hogy a Firefox is jól találja, ezért nem igazán érdekel, hogy az Opera mit csinál. szóval nagyjából nem indul.
Megjegyzések
- Nem értettem ' megjegyzést fűzni az UTF-8 és a helyettes párokhoz. A helyettesítő párok csak egy olyan koncepció, amely értelmes az UTF-16 kódolásban, igaz? Talán ezt a hibát okozhatja az a kód, amely közvetlenül az UTF-16 kódolástól UTF-8 kódolássá konvertálja, és ebben esetben a probléma az UTF-16 helytelen olvasása, nem az UTF-8 írása. Ez így van?
- Amiről Jason ' beszél, az az szoftver szándékosan úgy valósítja meg az UTF-8-at: hozzon létre egy helyettes párost, majd az UTF-8 hu mindkét felét külön kódolja. A kódolás helyes neve CESU-8, de az Oracle (pl.) Hamisan UTF-8 néven jeleníti meg. A Java hasonló sémát alkalmaz az objektumok sorosítására, de ' egyértelműen " módosított UTF-8 és csak belső használatra. (Most, ha csak arra késztetnénk az embereket, hogy olvassák el a dokumentációt, és abbahagyják a DataInputStream # readUTF () és a DataOutputStream # writeUTF () nem megfelelő használatát …)
- AFAIK, az UTF-32 még mindig változó hosszúságú kódolás, és nem egyenlő az UCS4-sel, amely a kódpont specifikus tartománya.
- @Eonil, az UTF-32 csak akkor lesz megkülönböztethető az UCS4-től, ha van egy Unicode-szabványunk, amely valami hasonlót tartalmaz, mint egy UCS5 vagy nagyobb. li>
- @JasonTrue Ennek ellenére csak az eredmények egybeesnek egybeesve, a tervezés nem garantálja. Ugyanez történt a 32 bites memóriacímzésnél, az Y2K, az UTF16 / UCS2 esetében is. Vagy van valamilyen garanciánk erre az egyenlőségre? Ha van, akkor ezt szívesen felhasználnám. De nem ' nem akarok lehetséges törhető kódot írni. Karakter szintű kódot írok, és az UTF < – > kódpont közötti átkódolás garantált módjának hiánya sokat hibázik .
Válasz
Az UTF-8 feltétlenül a megfelelő út, valószínűleg belső UTF-32 kíséretében felhasználás olyan algoritmusokban, amelyek nagy teljesítményű véletlenszerű hozzáférést igényelnek (de figyelmen kívül hagyja a karakterek kombinálását).
Az UTF-16 és az UTF-32 (valamint LE / BE variánsaik) egyaránt végzetes problémákkal küzdenek, ezért érdemes soha ne használjuk külsőleg.
Megjegyzések
- Az UTF-8-mal is állandó állandó véletlenszerű hozzáférés lehetséges, csak kódegységeket használjon a kódpontok helyett. Talán valódi véletlenszerű kódpont-hozzáférésre van szüksége, de ' még soha nem láttam használati esetet, és ' ugyanolyan valószínűséggel akar véletlenszerű grafémafürt-hozzáférés.
Válasz
UTF-16? határozottan káros. Csak itt a sós szemem, de pontosan három elfogadható kódolás van a szöveghez egy programban:
- ASCII: alacsony szintű dolgokkal (pl .: mikrokontrollerek) foglalkozva, amelyek “nem engedhetnek meg maguknak jobbat”
- UTF8: tárolás rögzített szélességű adathordozókban, például fájlokban
-
integer codepoint (“CP”?): a legnagyobb egész számok tömbje, amely kényelmes a programozási nyelv számára és platform (ASCII-re bomlik az alacsony reszorenciák határában). Régebbi számítógépeken int32-nek kell lennie, és 64 bites címzésű bárminek az int64-nek.
-
Nyilvánvalóan kapcsolódnak a régi kódhasználathoz. milyen kódolás szükséges a régi kód megfelelő működéséhez.
Megjegyzések
- @simon buchan, a
U+10ffff
max akkor megy ki az ablakon, ha (nem ha) elfogynak a kódpontok. Ez azt jelenti, hogy valószínűleg biztonságos az int32 használata p64 rendszeren, mivel kétlem, hogy ' ll meghaladja aU+ffffffff
-t, mielőtt 2050 körül kénytelen átírni a kódot 128 bites rendszerekhez. (Ez az " lényege, hogy használja a legnagyobb int, ami kényelmes " ellentétben a " legnagyobb elérhető " -vel (ami valószínűleg int256 vagy bignums vagy valami hasonló lenne.) - @David: Az Unicode 5.2 107 361 kódpontot kódol.867 169 kihasználatlan kódpont van. " amikor a " csak butaság. Egy Unicode kódpontot definiálunk 0 és 0x10FFFF közötti számként, amely tulajdonság az UTF-16 függ. (Ugyancsak 2050-es érték tűnik alacsonynak a 128 bites rendszerek becslésénél, amikor egy 64 bites rendszer az Internet teljes részét el tudja tartani benne ' s címterében.)
- @David: ", amikor " az Unicode kódpontok elfogyására utalt, nem pedig egy 128 bites kapcsolóra, ami igen, a következő évszázadokban lesz. A memóriával ellentétben a karakterek nem növekednek exponenciálisan, ezért az Unicode konzorcium kifejezetten garantálta, hogy soha nem osztanak ki kódpontot
U+10FFFF
. Ez valóban egyike azoknak a helyzeteknek, amikor 21 bit elég bárkinek. - @Simon Buchan: Legalább az első kapcsolatfelvételig. 🙂
- Unicode arra használták, hogy garantálják, hogy az U + FFFF felett sincsenek kódpontok.
Válasz
Unicode kódpontokat határoz meg 0x10FFFF-ig (1 114 112 kód), az összes alkalmazás többnyelvű környezetben fut karakterláncokkal / fájlnevekkel stb. ezt helyesen kell kezelnie.
Utf-16 : csak 1 112 064 terjed ki kódok. Bár a Unicode végén található 15-16-os (Magánfelhasználási terület) repülőgépekről van szó. A jövőben nem nőhet tovább, kivéve az Utf-16 koncepciót.
Utf-8 : elméletileg 2 216 757 376 kódot fed le. A Unicode kódok aktuális tartománya maximum 4 bájtos szekvenciával reprezentálható. Nem szenved bájtsorrend problémával, “kompatibilis” az ascii-val.
Utf-32 : elméletileg 2 ^ 32 = 4 294 967 296 kódot fed le. Jelenleg nem változó hosszúságú kódolású, és valószínűleg a jövőben sem lesz.
Ezek a tények magától értetődőek. Nem értem a Utf-16 általános használatának támogatását. Változó hosszúságú kódolású (index alapján nem érhető el), problémái vannak az egész Unicode tartomány lefedésével még jelenleg is, a bájt sorrendet kezelni kell, stb. Nem látok semmilyen előnyt, kivéve, hogy natív módon használják a Windows rendszerben és más helyeken. Annak ellenére, hogy többplatformos kód írásakor valószínűleg jobb az Utf-8
natív használata, és csak a végpontokon kell konverziót végrehajtani platformfüggő módon (amint azt már javasoltuk). Ha szükséges az index szerinti közvetlen hozzáférés, és a memória nem jelent problémát, a Utf-32 -t kell használni.
A fő probléma az, hogy sok Windows Unicode = Utf-16 programmal foglalkozó programozó nem is tudja, vagy figyelmen kívül hagyja azt a tényt, hogy változó hosszúságú kódolású.
A * nix platformon általában nagyon jó, c karakterláncok (char *) Utf-8 kódolással, széles c karakterláncok (wchar_t *) Utf-32 .
Megjegyzések
- Megjegyzés: UTF A -16 valóban lefedi az összes Unicode-ot, mivel az Unicode konzorcium úgy döntött, hogy a 10FFFF az Unicode TOP tartománya, és meghatározta az UTF-8 maximális 4 bájt hosszúságát és kifejezetten kizárta a 0xD800-0xDFFF tartományt az érvényes kódpontok tartományából, és ezt a tartományt használják a helyettesítő létrehozására párok. Tehát bármely érvényes Unicode szöveg megjeleníthető a kódolások egyikével. A jövőre való növekedésről is. Nem úgy tűnik, hogy ' nem tűnik úgy, hogy 1 millió kódpont a jövőben sem lenne elég.
- @Kerrek: Helytelen: Az UCS-2 nem érvényes Unicode kódolás. Definíció szerint az összes UTF- * kódolás bármely Unicode kódpontot képviselhet, amely legális csere. Az UCS-2 ennél jóval kevesebbet képviselhet, plusz még néhányat. Ismétlés: Az UCS-2 nem érvényes Unicode kódolás, az ASCII-nél is több.
- " Nem értem az Utf- általános használatának támogatását. 8 . Változó hosszúságú kódolású (index alapján nem érhető el) "
- @Ian Boyd, a karakterlánc egyedi karakterének véletlen hozzáférési mintában történő elérésének szükségessége: hihetetlenül túlértékelt. Körülbelül olyan gyakori, mint egy karaktermátrix átlójának kiszámítása, ami nagyon ritka. A karakterláncokat gyakorlatilag mindig egymás után dolgozzuk fel és mivel az UTF-8 karakter N + 1 elérése, tekintettel arra, hogy az UTF-8 karakteren tartózkodik, N értéke O (1), ezért nincs probléma. Meglepően kevés szükség van a húrok véletlenszerű elérésére. Az, hogy szerinted megéri-e a tárhelyet az UTF-8 helyett az UTF-32-re menni, az a saját véleményed, de számomra ez egyáltalán nem kérdés.
- @tchrist, megadom a karaktersorozatokat gyakorlatilag mindig egymás után dolgozzuk fel, ha a fordított iterációt " szekvenciális " néven szerepeltetjük, és ezt még egy kicsit tovább nyújtjuk. egy karakterlánc egy ismert karakterláncra. Két nagyon gyakori forgatókönyv: a szóköz szűkítése a karakterláncok végétől és a fájlkiterjesztés ellenőrzése az útvonal végén.
Válasz
Ezt adja hozzá a listához:
A bemutatott forgatókönyv egyszerű (még egyszerűbb, mivel itt bemutatom, mint eredetileg volt! ): 1. A WinForms TextBox üres egy űrlapon ül. MaxLength értéke 20 .
2. A felhasználó begépeli a TextBox-ot, vagy talán beilleszti a szöveget.
3. Nem számít, hogy mit ír be vagy illeszt be a TextBoxba, 20-ra korlátozódik, bár szimpatikusan csipog a 20-nál nagyobb szövegnél (itt YMMV; megváltoztattam a hangsémámat hogy ezt a hatást kapjam!).
4. Ezután a kis szövegcsomagot máshová küldik, hogy izgalmas kalandot indítsanak.
Most ez egy egyszerű forgatókönyv, és ezt bárki felírhatja, szabadidejében. Csak magam írtam fel több programozási nyelven WinForms segítségével, mert unatkoztam, és még soha nem próbáltam. És több tényleges nyelvű szöveggel, mert így vagyok bekötve, és több billentyűzetkiosztásom van, mint bárki másnak az egész rohadt univerzumban.
Meg is neveztem a Magic Carpet Ride formát, hogy segítsek az unalom enyhítésében.
Ez nem működött, mert mit ér.
Tehát ehelyett beírtam a következő 20 karakterek a varázsszőnyeg-lovaglás űrlapomba:
0123401234012340123 𠀀
Ó, ó.
Ez az utolsó karakter U + 20000, az első Az Unicode (más néven U + d840 U + dc00, B kiterjesztésű) ideográfja közeli barátainak, akiket nem szégyelli, hogy lebuktatják, mintha csak előtte lennének) ….
És most van egy labdajátékunk.
Mert amikor TextBox. A MaxLength a következőkről szól:
Megkapja vagy beállítja a maximális karakterszámot, amelyet manuálisan be lehet írni a szövegmezőbe.
amit valójában ez jelent:
kap vagy beállít az UTF-16 LE kód maximális száma Azok az egységek, amelyeket manuálisan be lehet írni a szövegmezőbe, és kíméletlenül csonkítják az élő baromságokat minden olyan karaktersorozatból, amely aranyos játékokat próbál játszani, azzal a nyelvi karakterfelfogással, amelyet csak olyan megszállottja talál sértőnek, mint az a Kaplan-fickó. szerezzen be többet!).
Megpróbálom megismerni a dokumentum frissítését …
Rendszeres olvasók, akik ne feledje, hogy az UCS-2 – UTF-16 sorozatom meg fogja állapítani a boldogtalanságomat a TextBox.MaxLength és hogyan kell kezelnie legalább ezt az esetet, amikor drakonikus viselkedése illegális sorrendet hoz létre, amelyet a .Net Framework más részei dobhatnak
- System.Text.EncoderFallbackException : Nem lehet lefordítani a 0 indexben lévő Unicode karaktert \ uD850 a megadott kódlapra. *
kivétel, ha ezt a karakterláncot a .Net Framework másutt adja át (ahogy kollégám, Dan Thompson tette).
Most rendben van, talán a teljes UCS-2 – UTF-16 sorozat sokak számára elérhető.
De nem “Ésszerű azt várni, hogy a TextBox.Text nem fog létrehozni egy System.String -et, amely nem fogja a .Net Framework újabb darabjait dobni? Úgy értem, nincs esély valamilyen esemény formájában a vezérlőn, amely elmondja a közelgő csonkolást, ahol könnyedén hozzáadhatja az intelligensebb ellenőrzést – olyan érvényesítést, amelyet maga a vezérlő nem bán. menj el odáig, hogy azt mondd, hogy ez a punk vezérlés megszakít egy biztonsági szerződést, amely akár biztonsági problémákhoz is vezethet, ha osztályozhatsz váratlan kivételeket az alkalmazás megszüntetésére, mint egyfajta szolgáltatásmegtagadás. Miért kellene a WinForms-nak folyamatot vagy módszert vagy algoritmus vagy technika érvénytelen eredményeket produkál?
Forrás: Michael S.Kaplan MSDN blog
Megjegyzések
- Köszönöm, nagyon jó link! ' hozzáadtam a kérdés kérdéslistájához.
Válasz
Nem feltétlenül mondanám, hogy az UTF-16 káros. Nem elegáns, de azt a célt szolgálja, hogy visszafelé kompatibilis legyen az UCS-2-vel, csakúgy, mint a GB18030 a GB2312-tel, az UTF-8 pedig a ASCII.
Ám az alapvető változtatás az Unicode felépítésében a közepén, miután a Microsoft és a Sun hatalmas API-kat építettek a 16 bites karakterek köré, káros volt. A változás tudatosításának elmulasztása sokkal károsabb volt.
Megjegyzések
- Az UTF-8 az ASCII felülhalmaza , de az UTF-16 NEM az UCS-2 szuperhalmaza. Bár szinte szuperhalmaz, az UCS-2 helyes kódolása az UTF-8-ba a CESU-8 néven ismert utálatot eredményezi; Az UCS-2-nek nincsenek ' t helyettesítői, csak hétköznapi kódpontok, ezért ezeket úgy kell lefordítani. Az UTF-16 igazi előnye, hogy ' könnyebb frissíteni az UCS-2 kódbázist, mint az UTF-8 teljes átírása. Vicces, mi?
- Persze, az UTF-16 technikailag nem ' az UCS-2 szuperhalmaza, de mikor volt valaha az U + D800 és az U + DFFF között másra használják, kivéve az UTF-16 helyetteseket?
- Nem számít ' t. A bytream-en keresztüli vakon való áthaladás kivételével bármilyen művelet megköveteli a helyettesítő párok dekódolását, amit ' nem tehet meg, ha ' újra kezeli UCS-2 néven.
Válasz
Az UTF-16 a a legjobb kompromisszum a kezelés és a tér között , és ezért használja a legtöbb főbb platform (Win32, Java, .NET) a karakterláncok belső ábrázolásához.
Megjegyzések
- -1, mert az UTF-8 valószínűleg kisebb vagy nem tér el jelentősen. Bizonyos ázsiai szkriptek esetén az UTF-8 karakterenként három bájt, míg az UTF-16 csak kettő, de ez egyensúlyban van azzal, hogy az UTF-8 csak egy bájt az ASCII számára (ami gyakran még az ázsiai nyelveken belül is megjelenik a terméknevekben, parancsokban és ilyesmiben). Ezenkívül az említett nyelvekben a karakterjel több információt közvetít, mint egy latin karakter, így indokolt hogy több helyet foglaljon.
- Nem nevezném a wor kombinálásának mindkét opció első oldala jó kompromisszumot jelent.
- Ez ' nem könnyebb, mint az UTF-8. ' változó hosszúságú.
- Félretéve az UTF-16 előnyeiről szóló vitákat: Amit idézett, az nem ok az UTF-16-ot használó Windows, Java vagy .NET használatára. A Windows és a Java arra az időre nyúlik vissza, amikor az Unicode 16 bites kódolás volt. Az UCS-2 akkor ésszerű választás volt. Amikor az Unicode 21 bites kódolássá vált, az UTF-16-ra való áttérés volt a legjobb választás a meglévő platformokon. Ennek semmi köze sem a könnyű kezelhetőséghez, sem a hely kompromisszumához. ' csak örökség kérdése.
- A .NET itt örökli a Windows örökségét.
Válasz
Sosem értettem az UTF-16 értelmét. Ha a lehető leghatékonyabban szeretné megjeleníteni a helyet, használja az UTF-8-at. Ha azt szeretné, hogy kezelje a szöveget fix hosszúságúként, használja az UTF-32-et. Ha egyiket sem szeretné, használja az UTF-16-ot. Még rosszabb, mert az UTF-16 összes általános (többnyelvű sík) karaktere egyetlen kódpontba illeszkedik, hibákat feltételezve hogy az UTF-16 fix hosszúságú, finom és nehéz megtalálni, míg ha ezt megpróbálja megtenni az UTF-8-tal, akkor a kód gyorsan és hangosan meghibásodik, amint megpróbálja nemzetközivé tenni.
Válasz
Mivel még nem tudok hozzászólni, ezt válaszként teszem közzé, mivel úgy tűnik, másképp nem tudok kapcsolatba lépni a utf8everywhere.org
. Nem szégyen, hogy nem kapom meg automatikusan a megjegyzéshez fűződő jogosultságot, mivel elegendő hírnevem van a többi stackexchangeban.
Ezt a vélemény megjegyzésének szánják: Igen, az UTF-16-ot káros válasznak kell tekinteni.
Egy kis javítás:
Annak megakadályozására, hogy véletlenül átadjon egy UTF-8 char*
t a Windows-API függvények ANSI-karakterlánc-verzióinak, definiálja UNICODE
, nem pedig _UNICODE
. A _UNICODE
olyan funkciók, mint a _tcslen
, a wcslen
, és nem a MessageBox
– MessageBoxW
. Ehelyett a UNICODE
definíció gondoskodik ez utóbbiról. Bizonyításképpen: ez az MS Visual Studio 2005 “s WinUser.h
fejlécétől származik:
#ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif // !UNICODE
Legalább, ezt a hibát ki kell javítani a utf8everywhere.org
oldalon.
Javaslat:
Talán az útmutatónak tartalmaznia kell egy példát a Wide- egy adatstruktúra string változata, hogy kevésbé könnyű kihagyni / elfelejteni.Az adatstruktúrák széles karaktersorozatú verzióinak használata a függvények széles karaktersorozatú verzióinak használata mellett még kevésbé valószínű, hogy véletlenül meghívja az ilyen függvény ANSI karaktersorozatú verzióját.
Példa a példára:
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); }
Megjegyzések
- Egyetértettek; köszönöm! Frissíteni fogjuk a dokumentumot. A dokumentum még további fejlesztésre szorul, és információkat kell hozzáadnia az adatbázisokról. Örülünk, hogy megfogalmazásokat kaptunk.
- @PavelRadzivilovsky
_UNICODE
még mindig ott van 🙁 - köszönöm, hogy emlékeztetted. Cubus, Jelle, Szeretne egy felhasználót az SVN-hez?
- @Pavel Persze, nagyra értékelné!
- @JelleGeerts: Elnézést kérek ezért a késésért. Mindig kapcsolatba léphetett velünk e-mailjeinkkel (linkelve) a kiáltványból) vagy a Facebook. Könnyen megtalálhatók. Bár úgy gondolom, hogy kijavítottuk a problémát, amelyet idehoztál (és ott jóváírtalak téged), az UTF-8 és az UTF-16 közötti viták továbbra is relevánsak. Ha még járuljon hozzá, bátran lépjen velünk kapcsolatba ezeken a privát csatornákon keresztül.
Válasz
Valaki szerint az UCS4 és az UTF-32 ugyanúgy. De nem, de tudom, mire gondolsz. Az egyik azonban a másik kódolása. Bárcsak gondolnák, hogy az elsőtől kezdve meghatározzák az endianitást, így itt sem vívnánk az endianess csatát. Nem látták, hogy jön? Legalább az UTF-8 mindenhol ugyanaz re (hacsak valaki nem követi az eredeti specifikációt 6 bájttal).
Ha az UTF-16-ot használja, kell beillesztenie a többbájtos karakterek kezelését is. Nem mehet az N-edik karakterhez úgy, hogy 2N-t indexel egy bájt tömbbe. Be kell járnia, vagy karakterindexekkel kell rendelkeznie. Ellenkező esetben hibát írt.
A C ++ aktuális specifikációja azt mondja hogy az UTF-32-nek és az UTF-16-nak lehetnek kis endián, nagy endián és nem specifikált változatai. Igazán? Ha az Unicode megadta volna, hogy mindenkinek a kezdetektől fogva kis endiánt kell tennie, akkor mindez egyszerűbb lett volna. (Jól lettem volna a big-endiánnal is.) Ehelyett egyesek egyféleképpen, mások meg másképp valósították meg, és most a semmiért ragadtunk a butaságokkal. Néha kínos szoftvermérnöknek lenni.
Megjegyzések
- A meghatározatlan végességnek fel kell tüntetnie a BOM-ot első karakterként, amely meghatározza, hogy a karakterláncot milyen módon kell olvasni. Az UCS-4 és az UTF-32 manapság valóban ugyanaz, azaz 0 és 0x10FFFF közötti numerikus UCS-érték tárolva egy 32 bites egész számban.
- @Tronic: Technikailag ez nem igaz. Bár az UCS-4 bármilyen 32 bites egész számot képes tárolni, az UTF-32-nek tilos tárolni azokat a nem karakteres kódpontokat, amelyek illegálisak a cserére, például 0xFFFF, 0xFFFE és az összes helyettesítőt. Az UTF egy transzportkódolás, nem egy belső.
- Az endianitás problémái elkerülhetetlenek, amíg a különböző processzorok továbbra is különböző bájtrendeket használnak. Jó lehet azonban, ha az UTF-16 fájl tárolásához " preferált " bájtos sorrend van.
- Annak ellenére, hogy az UTF-32 fix szélességű a kódpontoknál , a karaktereknél nem rögzített szélességű. (Hallottam valamit, amit úgy hívtak, hogy " egyesíti a karaktereket "?) Tehát ' nem mehet az N ' th karakter hez egyszerűen a 4N indexelésével a byte tömbbe.
Válasz
Nem hiszem, hogy káros, ha a fejlesztő elég körültekintő.
És el kell fogadniuk ezt a cserét, ha ők is jól tudják.
Japán szoftverfejlesztőként elég nagynak találom az UCS-2-t, és a hely korlátozása nyilvánvalóan leegyszerűsíti a logikát és csökkenti a futásidejű memóriát, így az utf-16 használata UCS-2 korlátozás alatt elég jó.
Vannak fájlrendszerek vagy más alkalmazások, amelyek feltételezik, hogy a kódpontok és a bájtok arányosak legyenek, így garantálható, hogy a nyers kódpontok száma illeszkedik valamilyen rögzített méretű tárhelyhez.
Az egyik példa az NTFS és a VFAT, amelyek az UCS-2 -et adják meg fájlnév-tároló kódolásukként. garantálja a méretet hossz szerint (az adatméret és a kódpont hossza arányos)
A jövőben, amikor a memória / a feldolgozási teljesítmény még bármely beágyazott eszköznél is olcsó, elfogadhatjuk, hogy az eszköz kissé lassú az extra gyorsítótárhiányok, oldalhibák és extra memória esetén azt hiszem, ez a közeljövőben nem fog megtörténni …
Megjegyzések
- A megjegyzést olvasók számára érdemes megjegyezni, hogy az UCS- A 2 nem ugyanaz, mint az UTF-16. Kérjük, keresse meg a különbségeket, hogy megértse.
Válasz
“Az egyik legnépszerűbb az UTF-16 kódolások károsnak tekinthetők? “
Valószínűleg, de az alternatívákat nem feltétlenül kell sokkal jobbnak tekinteni.
Az alapvető kérdés az, hogy sokféle fogalom létezik: karakterjelek, karakterek, kódpontok és bájtsorozatok. Ezek közötti térképezés nem triviális, még egy normalizáló könyvtár segítségével sem. (Például egyes, az európai nyelveken szereplő, latin alapú szkriptekkel írt karaktereket nem egyetlen Unicode kódponttal írnak. És ez a bonyolultság egyszerűbb végén van!) Ez azt jelenti, hogy minden rendben van: elképesztően nehéz; furcsa hibákra kell számítani (és ahelyett, hogy itt csak nyögne róluk, mondja el az érintett szoftver karbantartóinak ).
Az egyetlen mód, ahogyan az UTF- A 16-ot károsnak tekinthetjük, mondjuk az UTF-8-tal szemben, hogy más módon kódolhatja a BMP-n kívüli kódpontokat (helyettesítő párként). Ha a kód hozzáférni vagy kódpontonként szeretne iterálni, Ez azt jelenti, hogy tisztában kell lennie a különbséggel. OTOH, ez azt jelenti, hogy a létező kódok jelentős része, amelyek “karaktereket” vesznek fel, mindig beilleszthetők egy kétbájtos mennyiségbe – meglehetősen általános, ha téves feltételezés – legkevésbé folytassa a munkát anélkül, hogy mindezt újjáépítené. Más szavakkal, legalább meglátja ezeket a karaktereket s ezeket nem kezelik jól!
A fejére fordítanám a kérdését, és azt mondanám, hogy az Unicode egész rohadt sejkjét károsnak kell tekinteni, és mindenkinek 8 bites kódolást kell használnia, kivéve Láttam (az elmúlt 20 évben), hogy ez hová vezet: szörnyű zavartság a különféle ISO 8859 kódolásokban, plusz a cirill betűkészlet és az EBCDIC csomag egésze, és… nos, az Unicode minden hibája miatt . Ha csak “nem lenne ilyen csúnya kompromisszum a különböző országok között” félreértések.
Megjegyzések
- Szerencsénk ismeretében néhány év múlva ' úgy találjuk, hogy az UTF-16-ban kifogytunk a helyből. Meh.
- Alapvető kérdés, hogy a szöveg megtévesztően kemény. Az információ digitális módon történő képviseletének semmilyen megközelítése nem lehet bonyolult. ' ugyanaz az oka, hogy a dátumok nehézek, a naptárak nehézek, az idő nehéz, a személynevek kemények, a postacímek nehézek: amikor a digitális gépek keresztezik az emberi kulturális konstrukciókat, összetett kitör. Ez az élet ténye. Az emberek nem a digitális logikán működnek.