UTF-8 בכל מקום

מניפסט

מטרת מסמך זה

מטרת מסמך זה היא לקדם את השימוש והתמיכה בקידוד UTF-8, ולשכנע שזו צריכה להיות ברירת המחדל לקידוד מחרוזות בזיכרון או על דיסק, בתקשורת וכל שאר השימושים. אנו מאמינים כי גישה זו משפרת ביצועים, מפשטת את התוכנה ומונעת באגים הקשורים ל-Unicode. אנו טוענים כי קידודים אחרים של Unicode (או טקסט בכלל) שייכים למקרי קצה נדירים של אופטימיזציה ומשתמשים רגילים צריכים להמנע מהם.

בפרט אנו מאמינים כי לקידוד UTF-16 הפופולרי (שלעיתים קרובות מכונה בשגוי ’widechar‘ או סתם ’Unicode‘ בעולם ה-Windows) אין מקום בממשקי הספריות מלבד ספריות המתמחות בעיבוד טקסט, כדוגמת ה-ICU.

כמו כן, מסמך זה ממליץ לבחור ב-UTF-8 לייצוג פנימי של מחרוזות ביישומי Windows, על אף שתקן זה פחות נפוץ שם, בשל סיבות היסטוריות וגם בשל העדר תמיכה מובנית ב-UTF-8 במערכת. אנו מאמינים כי גם בפלטפורמה זו הטיעונים הבאים עולים על העדר תמיכה מובנית. כמו כן, אנו ממליצים לשכוח לעד מה הם ’קידודי ANSI‘ ולמה שימשו. זוהי זכותו המלאה של המשתמש לשלב כל מספר של שפות בכל מחרוזת טקסט.

בתעשיית התוכנה, על באגים רבים הקשורים בלוקליזציה, מאשימים את אי בקיאות המתכנתים ב-Unicode. לעומת זאת, לדעתנו, ליישום שלא מתמקד בטקסט, התשתיות יכולות וצריכות לאפשר לתוכנה להתעלם מסוגיות הקידוד. לדוגמה, כלי להעתקת קבצים לא צריך להיכתב שונה על מנת לתמוך בשמות קבצים שלא באנגלית. בנוסף, במניפסט זה נסביר מה המתכנת צריך לעשות כדי לא להתעמק בכל מורכבויות Unicode ואם לא באמת אכפת לו מה יש בתוך המחרוזת.

יתרה מזאת, אנו טוענים כי ברוב תרחישי עיבוד טקסט אין לראות בספירה או איטרציה על נקודות קוד של Unicode משימה חשובה במיוחד. באופן מוטעה, מפתחים רבים רואים בנקודות קוד הכללה לתווי ASCII. זה מוביל להחלטות עיצוב תוכנה סגנון גישה בזמן O(1) לנקודות קוד בפייתון. עם זאת, האמת היא ש-Unicode מטבעו מורכב יותר, ואין בו מושג כללי של תו Unicode. אנו לא רואים סיבה מיוחדת להעדיף נקודות קוד של Unicode על פני מקבצי גרפמות של Unicode, יחידות קוד, או אולי אפילו מילים בשפה לשם כך. מצד שני, לראות ביחידות קוד של UTF-8 (בתים) יחידות בסיסיות של טקסט, הינו שימושי במיוחד למשימות רבות, כגון ניתוח פורמטים טקסטואלים נפוצים. וזאת בזכות תכונות מסויימות של קידוד זה. גרפמות, יחידות קוד, נקודות קוד ומונחי Unicode רלוונטיים אחרים מוסברים בחלק 5. בנוגע לפעולות על מחרוזות טקסט מקודדות אנו דנים בחלק 7.

רקע

בשנת 1988, ג'וזף ד. בקר פרסם את הטיוטה הראשונה של הצעת ה Unicode. הדיזיין שלו התבסס על ההנחה הנאיבית ש 16 ביטים לתו יספיקו. ב1991, פורסמה גרסאת הסטנדרט Unicode הראשונה, עם "תווים" מוגבלים ל 16 סיביות. בשנים הבאות מערכות רבות הוסיפו תמיכה ל Unicode ועברו לקידוד UCS-2. מהלך זה היה אטרקטיבי במיוחד לטכנולוגיות חדשות של התקופה כמו ה Qt framework מ-1992, Windows NT 3.1 מ-1993, וה Java מ-1995.

במהרה התגלה כי 16 ביטים לתו לא מספיקים ל Unicode. בעקבות כך, בשנת 1996 נוצר קידוד UTF-16, על מנת שמערכות קיימות יוכלו לעבוד עם תווים שהם לא 16 ביטים. חידוש זה למעשה ביטל את הרציונאל מאחורי בחירת קידוד 16 ביטים, כקידוד בגודל קבוע. כיום Unicode משתרע על פני 109,449 תווים, כאשר בערך 74,500 מהם אידיוגרפים של CJK.

A little child playing an encodings game in front of a large poster about encodings.
מוזיאון המדע, נאגויה. תמונה ע"י וודים זלוטניק.

לעיתים קרובות מייקרוסופט השתמשה באופן מוטעה, ב Unicode ו Widechar כמילים נרדפות ל 2 USC- ול- UTF-16. יתרה מכך, מכיוון ש UTF-8 לא יכול להיות מוגדר כקידוד של גרסאת Narrow WinAPI, חייבים לקמפל את הקוד הקיים עם הגדרות קבוע Unicode. מלמדים את מתכנתי ה ++Windows C שה Unicode חייב להעשות עם Widechars (או גרוע מכך: TCHAR שמשמעותו תלויה בהגדרת קומפילציה - המאפשר למתכנת שלא לתמוך בכל התווך של Unicode). כתוצאה מכך, כיום קיים בלבול רב אצל מתכנתי Windows לגבי מהו הדבר הנכון לעשות לגביי טקסט.

יחד עם זאת, בעולמות ה Linux וה- Web, קיימת הסכמה שקטה כי UTF-8 הוא הקידוד המוצלח ביותר ל Unicode. אף על פי שהוא מספק ייצוג קצר יותר לאנגלית ובשל כך לשפות המחשב (כגון C++, HTML, XML, ועוד...) מעל לכל טקסט אחר, הוא לעיתים רחוקות פחות יעיל מאשר ה UTF-16 גם לשפות אחרות.

העובדות

Opaque data argument

אם נסתכל על תוכנית שמעתיקה קבצים; בעולם ה- UNIX, מחרוזות צרות (Narrow string) נחשבות ל UTF-8 כברירת מחדל כמעט בכל מקום. בשל עובדה זאת, היוצר של שרותי העתקת קובץ לא יצטרך לדאוג לגביי Unicode. קוד שייבדק על מחרוזות ASCII לפרמטר שם קובץ, יעבוד באופן תקין לקבצי שם בכל שפה, הרי הוא מתייחס לפרמטרים כאל Cookies. הקוד של שרותי העתקה של הקובץ לא יצטרך להשתנות כלל על מנת לתמוך בשפות זרות. ()fopen יקבל Unicode באופן שקוף, וכך גם argv.

ניתן לעשות זאת במייקרוסופט, Windows שהיא ארכיטקטורה מבוססת על UTF-16, באופן הבא: כדי ליצור שרות העתקת קובץ שיכול לקבל שמות קבצים מתוך ערבוב של בלוקים (שפות) Unicode שונות, נשתמש בתכסיסים משוכללים. ראשית, האפליקציה חייבת להיות מקומפלת כ Unicode - aware. במקרה זה, לא יכולה להיות לה פונקציית ()main עם פרמטרים סטנדרטיים של C. באופן זה היא תאפשר argv מקודד ב UTF-16. על מנת להמיר תוכנות Windows הכתובות בהנחה של טקסט צר לתמוך ב Unicode, יש לעשות רפקטורינג עמוק, ולטפל במשתנה של כל מחרוזת בנפרד.

הסיפריות הסטנדרטיות שנשלחות עם MSVC מיושמות באופן גרוע בהתייחס לתמיכת Unicode. זאת בין היתר משום שהן מעבירות פרמטרים צרי- מחרוזת ישירות ל OS ANSI API ולא קיימת דרך לעקוף את זה. שינוי של std::locale לא עובד. בלתי אפשרי לפתוח קובץ בעל שם Unicode על MSVC על ידי שימוש בכלים סטנדרטיים של ++C. הדרך הסטנדרטית לפתוח קובץ הוא:

std::fstream fout("abc.txt");

אך זה לא יעבוד נכון. הדרך המוצעת לעקוף זאת היא ע"י שימוש ב Hack תוצרת עצמית של מייקרוסופט, שמאפשר פרמטרים של מחרוזות רחבות. זאת לא הרחבה סטנדרטית.

ב Windows, מפתח רג'יסטרי HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage\ACP מאפשר קבלת תווים שאינם מסוג ASCII ב- Narrow API, אבל רק codepage ANSI יחיד. ערך לא ממומש של 65,001 ככל הנראה היה פותר את נושא ה Cookies, ב Windows. אם מייקרוסופט תתמוך בערך ACP זה, זה יעזור באימוץ רחב יותר של UTF-8 על בפלטפורמת Windows. למתכנתי Windows וספקי סיפריות רב שכבתיות, אנו מעמיקים בדיון לגביי גישתנו בטיפול מחרוזות טקסט ושיפור תוכנות לתמיכת Unicode טובה יותר, בפרק "איך לעשות טקסט ב Windows" .

Glyphs, Graphemes ויצורים נוספים ב Unicode

להלן חלק מההגדרות שמתייחסות לתווים, Code Points, יחידות קידוד ו Grapheme Clusters לפי הסטנדרט של ה Unicode, עם ההערות שלנו. אנו מעודדים אתכם לפנות לפרקים רלוונטיים בסטנדרט להרחבה נוספת.

Code point
כל ערך נומרי במרחב הכרכים של Unicode.[§3.4, D10] לדוגמא: U+3243F.
יחידות קידוד
אוסף סיביות שיכול לייצג יחידה של טקסט מקודד. [§3.9, D77] לדוגמא: UTF-8 ,UTF-16 ו UTF-32 משתמשים ביחידות קידוד של 8 ביטים, 16 ביטים ו 32 ביטים בהתאמה. ה Code point לעיל תקודד כארבע יחידות קידוד ‘f0 b2 90 bf’ ב UTF-8, שתי יחידות קידוד ‘d889 dc3f’ ב UTF-16 ויחידת קידוד אחת ‘0003243f’ ב UTF-32. שימו לב, אלו רק רצפים של קבוצות של ביטים; איך הם מאוחסנים כרצף בתים תלוי בסדר הבתים של קידוד ספציפי. כאשר מאחסנים את יחידות הקידוד של UTF-16 שמוזכר לעיל, הם יומרו ל ‘d8 89 dc 3f’ ב UTF-16BE ול ‘89 d8 3f dc ’ ב UTF-16LE.
תו מופשט – Abstract character

יחידת מידע המשמשת ארגון, בקרה, או ייצוג של נתוני טקסט. [§3.4, D7] בהמשך, הסטנדרט מציין ב§3.1.:

"בשביל התקן של ה Unicode, [...] הרפרטואר פתוח מטבעו. בגלל שה Unicode הוא קידוד אוניברסלי, כל תו מופשט שאי פעם היה יכול להיות מקודד, הוא מועמד פוטנציאלי להיות מקודד, ללא קשר להאם התו מוכר כרגע."

ההגדרה בהחלט מופשטת. כל מה שניתן לחשוב עליו כעל תו- הוא התו המופשט. לדוגמא: tengwar letter ungwe הוא תו מופשט למרות שהוא עדיין לא ניתן לייצוג ב Unicode.

תו מקודד Encoded character

מיפוי בין Code Points ותו מופשט. [§3.4, D11] לדוגמא, U+1F428 הוא תו מקודד אשר מייצג את התו המופשט: 🐨 koala.

מיפוי זה אינו מלא, חד-חד ערכי ולא "על":

  • ל Surragates ,noncharacters ו Code Points לא משוייכים, אין תווים מופשטים מתאימים כלל.
  • יש תווים מופשטים שיכולים להיות מקודדים ע"י Code Points שונים; האות היוונית הגדולה אומגה U+03A9 וסימן של יחידת אוהם U+2126 תואמים לאותו תו מופשט ‘Ω’, וחייבים להתייחס אליהם באופן זהה.
  • חלק מהתווים המופשטים אינם יכולים להיות מקודדים ע"י Code Point יחיד. אלו מיוצגים ע"י רצפים של תוים מקודדים. לדוגמא, הדרך היחידה בה אפשר לייצג את התו המופשט של האות הקירילית הקטנה "יו" עם הטעמה (ю́) היא ע"י הרצף: U+044E cyrillic small letter yu, ולאחריו: U+0301 combining acute accent.

מעבר לכך, לחלק מהתווים המופשטים, קיים ייצוג ע"י Code Points מרובים, בנוסף לייצוג של התו המקודד הבודד. התו המופשט ǵ יכול להיות מקודד ע"י נקודת קוד בודדה: U+01F5 Latin small letter g with acute או ע"י הרצף: <U+0067 latin small letter g, U+0301 combining acute accent>.

תו- בתפיסת המשתמש – User – perceived character
כל מה שהמשתמש הסופי מתאר לעצמו כתו. הגדרה זאת תלוית שפה. למשל, “ch” אלו הן שתי אותיות בלטינית ואנגלית, אבל נחשבות לאות אחת בצ'כית וסלובקית.
Grapheme Cluster
רצף של תוים מקודדים ש"אמורים להיות יחד כל הזמן". [§2.11] איגוד הגראפמות אומד את חשיבת "תו בתפיסת המשתמש" לעיל, באופן שלא תלוי בשפה. משתמשים בהם למשל בשביל תנועת הסמן ובחירה בשיטת Cut-and-paste.
Glyph
צורה ספציפית בתוך גופן. גופנים הם אוסף של Glyph המעוצבים ע"י "מעצב סוג גופנים". זוהי האחראיות של מנוע עיבוד ורינדור של טקסט להמיר רצף של Code Points לרצף של Glyphs בגופן ספציפי. התנאים להמרה זו עלולים להיות מורכבים, תלויי הגדרות מיקום (Locale), והם מעבר להקף התקן של Unicode.

המילה "תו" יכולה להתייחס לכל אחד מהסעיפים לעיל. תקן ה Unicode משתמש ב"תו" כשם נרדף ל"תו מקודד". [§3.4] כאשר שפת התכנות או תיעוד של ספרייה מתייחסת ל"תו", היא בדרך כלל מתכוונת ליחידת קוד. כאשר המשתמש הסופי נשאל לגבי מספר התווים במחרוזת, הוא יספור את "תפיסת המשתמש" כתווים. מתכנת עלול לספור תווים כיחידות קידוד, Code Points, או Grapheme Clusters לפי מידת התמקצעותו ב Unicode. לדוגמא, ראה איך טוויטר סופר תווים. לדעתנו, פונקציית האורך של מחרוזת לא בהכרח אמורה להחזיר 1 בשביל המחרוזת ‘🐨’ על מנת שתחשב כתואמת Unicode.

טקסט אסייתי: UTF-8 לאומת UTF-16

רוב נקודות הקוד Unicode משתמשות באותו מספר של בתים ב UTF-8 וב UTF-16. זה כולל עברית, רוסית, יוונית וכל היחידות קידוד שהן לא ב BMP שמשתמשות ב2 או 4 בתים בשני הקידודים. אותיות לטיניות, יחד עם סימני פיסוק ושאר ה ASCII דורשים יותר מקום ב UTF-16, בעוד שתווים אסיאתיים מסויימים דורשים יותר מקום ב UTF-8. האם לא יכלו המתכנתים האסיאתיים, באופן תאורטי, להתנגד להשלכת UTF-16, אשר חוסך להם 50% זיכרון לתו?

המציאות היא כזאת: חיסכון של מחצית מהמקום בזיכרון מתקיים רק בדוגמאות המורכבות באופן מלאכותי המכילות רק תווים בטווח ה U+0800 עד U+FFFF . עם זאת, ממשקי טקסט מחשב-למחשב הם הדומיננטיים בהשוואה לכל שימושים האחרים של טקסט. זה כולל XML ,HTTP filesystem paths וקבצי קונפיגורציה – כל אלו, באופן כמעט מוחלט, משתמשים בתווי ASCII, ולמעשה UTF-8 מאוד פופולארי בארצות אסיאתיות רלוונטיות.

עבור אחסון ייעודי של ספרים סיניים, עדיין ניתן להשתמש ב UTF-16 כאופטימיזציה הגיונית. ברגע שהטקסט נשלף מאחסון כזה, הוא אמור להיות מומר לסטנדרט שעומד בקנה מידה אחד עם שאר העולם. בכל מקרה, אם האחסון חשוב כל כך, עדיף להשתמש בדחיסה. במקרים כאלו, UTF-8 ו- UTF-16 יצרכו בערך את אותה כמות של מקום. מעבר לכך: "בשפות אלה, ה Glyph מכיל יותר אינפורמציה מאשר תו לטיני כך שזה מוצדק שהוא ידרוש יותר מקום". ( UTF-16 נחשב כמזיק , Tronic).

מוצגות לפניכם תוצאות מניסוי פשוט. בעמודה הראשונה מוצג המקום שתופס מקור HTML של דף אינטרנט מסויים (מאמר "יפן" ששוחזר מוויקיפדיה יפנית ב 01-01-2012). העמודה השניה מראה את התוצאות של טקסט שה Markup שלו הוסר, כלומר "בחר הכל, העתק, הדבק לתוך קובץ טקסט ריק".

HTML Source (Δ UTF-8)Dense text (Δ UTF-8)
UTF-8767 KB (0%)222 KB (0%)
UTF-161 186 KB (+55%)176 KB (−21%)
UTF-8 zipped179 KB (−77%)83 KB (−63%)
UTF-16LE zipped192 KB (−75%)76 KB (−66%)
UTF-16BE zipped194 KB (−75%)77 KB (−65%)

ניתן לראות כי UTF-16 צורך בערך 50% יותר מקום מאשר UTF-8 בנתונים אמיתיים, חוסך רק 20% יותר לטקסט אסיאתי דחוס, ובקושי עומד בתחרות עם אלגוריתמי דחיסה למטרות כלליות. התרגום הסיני של מסמך זה שנתרם לנו ע"י קבוצת מתנדבים, תופס 58.8KB ב UTF-16 ורק 51.7KB ב UTF-8.

פעולות טקסט על מחרוזת מקודדת

הפורמטים הפופולאריים מבוססי טקסט (כמו: CSV ,XML ,HTML ,JSON ,RTF וקוד מקור של תוכנות מחשב) לעתים קרובות מכילים תווי ASCII כאלמנטי בקרת מבנה, ויכולים להכיל גם מחרוזות מתווים של ASCII ותווים שאינם ASCII. עבודה עם קידודים באורך משתנה, היכן תווי ASCII קצרים יותר מ Code Points אחרות, עלולה להראות כמשימה קשה במיוחד, מכיוון שהגבולות של התווים המקודדים בתוך המחרוזת לא ידועים מייד. זה דחף את מהנדסי התוכנה לבחור בקידוד קבוע רוחב USC-4 (לדוגמא Python v3.3). למעשה, זה לא הכרחי ולא פותר אף בעיה אמיתית שאנחנו מכירים.

על פי הדיזיין של קידוד זה, UTF-8 מבטיח שערך תווים או תתי-מחרוזת ASCII לעולם לא יתאימו לחלק של תווי מקודד שתופס מספר בתים. אותו הדבר נכון לגביי ה UTF-16. בשני הקידודים, בכל יחידות הקוד של Code Points המקודדות למספר חלקים, הסיבית המשמעותית ביותר (MSB) תהיה שווה ל-1.

כדי למצוא, למשל, סימן "<" המגדיר את התחלתו של תג HTML, או גרש (') במשפט SQL מקודד UTF-8, כדי להגן מפני SQL injection עשו כפי שהייתם עושים לכל מחרוזת ASCII רגילה שכולה אנגלית. הקידוד מבטיח שזה יעבוד. כלומר, כל תו שהוא לא ASCII יקודד ב UTF-8 כרצף של בתים, שלכל אחד ערך גבוה מ 127. זה אינו משאיר מקום להתנגשות באלגוריתם נאיבי - פשוט, מהיר, אלגנטי ומבטל את הצורך לדאוג לגביי גבולות של תווים מקודדים.

כמו כן, הנך יכול לחפש תת מחרוזת שאינה ASCII מקודדת ב UTF-8 כאילו היא מערך ביתים פשוט – אין צורך להתייחס לגבולות Code Points. זה הודות לתכנון רכיב אחר של UTF-8 – בית מוביל של נקודת קוד מוצפנת לעולם לא יוכל להיות בעל ערך זהה לאחד מהבתים המסיימים של אף Code point אחרת.

מיתוסים נוספים לגביי ספירת תווים

כפי שהוזכר קודם לכן, קיימת מחשבה נפוצה על פיה ספירה, פיצול, אופרציות אינדקס או חזרה על Code Points במחרוזת Unicode צריכים להחשב כפעולה חשובה ותכופה. בחלק זה אנו נבחן זאת לעומק.

1. ספירת תווים יכולה להתבצע בזמן קבוע עם UTF-16.

זוהי טעות נפוצה אצל אלו המאמינים כי UTF-16 היא קידוד קבועת רוחב. הוא לא. למעשה, UTF-16 הוא קידוד עם אורך משתנה. אם אתה מתכחש לקיום של תווים מחוץ ל BMP, ראה סעיף זה ב "שאלות נפוצות".

2. ספירת תווים יכולה להתבצע בזמן קבוע עם UTF-32.

זה תלוי במשמעות המילה "תו", שלרוב טועים במשמעותה. זה נכון שאפשר לספור יחידות קידוד ו Code Points בזמן קבוע ב UTF-32. עם זאת, Code Points אינן קשורות לאיך שתו נתפס ע"י המשתמש. אפילו בהקשר של ה Unicode , חלק מנקודות הקוד קשורות לתו מקודד וחלק ל"לא –תווים" .

3. ספירת תווים או Code Points מקודדים זה חשוב.

אנו מאמינים כי החשיבות שמייחסים ל Code Points, לעיתים קרובות מוגזמת. זה קורה הודות לחוסר הבנה נפוצה לגביי המורכבות של ה Unicode, שבסך הכל משקף את המורכבות של השפות האנושיות. אין זאת בעיה לציין כמה תווים יש במילה "Abracadabra", אך בואו נחזור למחרוזת הבאה: Приве́т नमस्ते שָׁלוֹם, היא מורכבת מ-22 (!) Code Points, אך רק 16 Grapheme Clusters. ניתן להקטין את מספר נקודות הקוד ל-20 אם תומר ל NFC. עם זאת, מספר נקודות הקוד בתוכה אינו רלוונטי לרוב משימות הנדסת תוכנה, עם יוצא הדופן היחיד: המרת המחרוזת ל UTF-32. לדוגמא:

4. ב NFC, כל נקודת קוד מתאימה לתו יחיד הנתפס כתו ע"י המשתמש.

לא, מכיוון שמספר התווים "איך שנתפסים ע"י המשתמש" הניתנים לייצוג ב Unicode הוא למעשה אינסופי. אפילו בפרקטיקה, לרוב התווים אין מבנה מורכב במלואו. לדוגמא, מחרוזת ה NFD מהדוגמא לעיל, אשר מורכבת משלוש מילים אמיתיות בשלוש שפות אמיתיות, תהיה בנויה מ 20 Code Points ב NFC. זה עדיין יותר מה 16 תווים שנתפסים ע"י המשתמש.

5. פעולת ה ()length של המחרוזת חייבת לספור את התווים הנתפסים ע"י המשתמש או תווים מקודדים. אם לא, היא לא תומכת ב Unicode כמו שצריך.

תמיכת ה Unicode בסיפריות ובשפות תכנות נאמדת לעיתים קרובות ע"י הערך שמוחזר מפעולת "אורך המחרוזת". לפי אומדן זה לתמיכת ה Unicode, השפות הכי פופולאריות, כמו למשל: C# ,Java ואפילו ICU בעצמו, לא יתמכו ב Unicode. לדוגמא: אורך של המחרוזת בעלת תו יחיד ‘🐨’ לעיתים קרובות תדווח כשני תווים היכן שמשתמשים ב UTF-16 כייצוג פנימי של המחרוזת, וכארבעה תווים לשפות שמבוססות על ייצוג פנימי של UTF-8. המקור לטעות הוא שאפיון של שפות אלו משתמשות במילה "תו" כדי להגדיר יחידת קידוד בעוד שהמתכנת מצפה שזה יהיה משהו אחר.

עם זאת, ספירת יחידות הקוד המוחזר ע"י API אלו, בעל משמעות מעשית גבוהה. כאשר כותבים מחרוזת UTF-8 לתוך תיקייה, החשוב הוא האורך בבתים. ספירת כל סוג אחר של תווים, לעומת זאת, לא באמת שימושית.

מסקנות

UTF-16 הוא הגרוע בשני העולמות, מכיוון שהוא גם בעל אורך משתנה וגם רחב מידי. הוא קיים אך ורק מסיבות היסטוריות ויוצר בלבול רב, לכן אנו מקווים כי השימוש בו ימשיך לדעוך.

ניידות חוצה פלטפורמות ופשטות יותר חשובות מאשר תקלות העבודה עם API של פלטפורמות קיימות. אי לכן, הגישה הטובה ביותר היא שימוש בלעדי במחרוזות צרות UTF-8 והמרה שלהן, הלוך וחזור, כאשר משתמשים ב API של פלטפורמה שלא תומכת ב UTF-8 ומקבלים מחרוזות רחבות (כדוגמאת Windows API). לעיתים רחוקות הביצועים בהמרת מחרוזות הן שיקול כאשר מתמודדים עם מערכות API שמקבלים מחרוזות במערכות (כדוגמאת, API של ממשקי משתמש או מערכות קבצים), וקיים יתרון משמעותי לשימוש בקידוד זהה בכל מקום בתוכנה. לכן לעניות דעתנו, אין סיבה מספיק טובה לעשות זאת באופן שונה.

בהתייחס לביצועים, לעיתים קרובות מכונות עושות שימוש במחרוזות לצרכי תקשורת (כדוגמאת HTTP Headers ,XML ,SOAP). רבים רואים בכך טעות לכשעצמה, אך בהתעלם מכך, זה כמעט תמיד מתבצע באנגלית ותווי ASCII, מה שנותן יתרון נוסף ל UTF-8. שימוש בקידודים שונים למחרוזות מסוגים שונים מעלה באופן משמעותי את המורכבות והיווצרות באגים.

בפרט, אנו מאמינים כי זאת היתה טעות להוסיף wchar_t לתקן של ++C, וכך גם תוספות הUnicode ל C++11. עם זאת יש לדרוש מהיישומים שכל קידוד תווים שמשתמשים בו יוכל לשמור כל נתון מה Unicode. כך כל std::string או פרמטר מסוג *char יוכל להיות תואם ל Unicode. "אם זה מקבל טקסט, זה צריך להיות תואם Unicode" – וזה קל ליישום עם UTF-8.

ב ++C קיימים פגמי דיזיין רבים ב facets של הסטנדרט. הם כוללים בין היתר את העובדה ש: std::numpunct, std::moneypunct ו- std::ctype לא תומכים בתווים המקודדים באורכים משתנים (non-ASCII UTF-8 ו- non-BMP UTF-16), או שחסר להם מידע לביצוע של ההמרות הדרושות. מן ההכרח לתקן אותם:

איך לעבוד עם טקסט על Windows?

חלק זה מוקדש לפיתוח ספריות פורטביליות (Class platform) ולתכנות Windows. הבעיה עם הפלטפורמה של Windows שהיא לא תומכת (עדיין) ב Unicode בגרסאת ה API של מחרוזות צרות. הדרך היחידה להעביר מחרוזות Unicode ל Windows API היא ע"י המרת UTF-16 (הידוע גם כמחרוזת רחבה).

יש לציין כי ההנחיות המוצגות כאן, שונות באופן משמעותי מהמדריך המקורי של מייקרוסופט לטיפול ב Unicode. הגישה שלנו מבוססת על ביצוע המרת המחרוזת לרחבות כמה שיותר קרוב לקריאות ל API , ולעולם לא להחזיק נתונים של המחרוזת הרחבה. בחלקים הקודמים הסברנו שהתוצאה של זה היא בדרך כלל ביצועים טובים יותר, יציבות, פשטות של הקוד, ותאימות לתוכנות אחרות.

עבודה עם קבצים, Filenames ו- fstreams על Windows

פונקציות המרה ב ++C

בהנחיות אלו אנו משתמשים בפונקציות המרה מה Boost.Nowide library (אין זה עדיין חלק מה BOOST):

std::string narrow(const wchar_t *s);
std::wstring widen(const char *s);
std::string narrow(const std::wstring &s);
std::wstring widen(const std::string &s);

הסיפריה גם מספקת עטיפות לפונקציות הספריה הסטנדרטיות של C ו ++C, של טיפול בקבצים, וכן אמצעים של קריאה וכתיבה של UTF-8 דרך Iostreams.

פונקציות ו-wrappers אלו קלים למימוש על ידי שימוש בפונקציות Windows ה MultiByteToWideChar ו WideCharToMultiByte. ניתן להשתמש בכל רוטינת המרה אחרת.

שאלות נפוצות

  1. ש: האם אתה לינוקסר? האם זהו מאבק דתי מוסווה ב Windows?

    ת: לא, גדלתי על Windows, ואני בראש ובראשונה מפתח Windows. אנו מאמינים כי מייקרוסופט עשתה בחירת דיזיין מוטעית בתחום הטקסט, מכיוון שהם עשו זאת לפני כל השאר.

  2. ש: האם אתה אנגלופילים? האם אתה חושב בסתר כי האלפבית והתרבות האנגלית עדיפים על כל האחרים?

    ת: לא, וארצנו לא דוברת ASCII. איננו חושבים ששימוש בפורמט המקודד תווי ASCII בבית יחיד הוא "אנגלו- צנטרי", או שיש לזה איזה שהוא קשר לתקשורת בין בני אנוש. אף על פי שאפשר לטעון כי קודי מקור של תוכנות, דפי אינטרנט וקבצי XML, שמות קבצים של מערכת הפעלה וממשקי טקסט מחשב-למחשב אחרים, לא היו צריכים להיות קיימים. אך כל עוד הם קיימים, הטקסט אינו מיועד רק לקורא אנושי.

  3. ש: למה אכפת לכם? אני מתכנת ב #C ו/או ב Java ואני לא צריך לדאוג לקידוד כלל.

    ת: אין זה נכון. גם ב #C וגם ב Java יש טיפוס char בעל 16 ביטים, שזה פחות מתו Unicode, מזל טוב. האינדקסר str[i] של NET. עובד ביחידות של ייצוג פנימי, וזאת שוב "אבסטרקציה דולפת". פונקציות SUBSTRING יחזירו בשמחה מחרוזת לא חוקית, ויחתכו את התו הלא BMP לחלקים ב #C.

    מעבר לכך, צריך לשים לב לקידוד כשאתה כותב את הטקסט שלך לקבצים על דיסק, תקשורת, מכשירים חיצוניים, או כל מקום אחר ממנו תוכנה יכולה לקרוא. במקרים אלו בבקשה תשתדל להשתמש ב (System.Text.Encoding.UTF8 (.NET ולעולם לא ב Encoding.ASCII ,UTF-16 או ב cellphone PDU, ללא קשר להנחות לגביי התוכן.

    מערכות WEB כמו ASP.NET אכן סובלות מהבחירה הלא מוצלחת של ייצוג מחרוזת פנימית בתשתית עליה בנויות: פלט המחרוזת הצפוי (והקלט) של אפליקציית אינטרנט כמעט תמיד UTF-8, מה שיוצר תקורת המרה משמעותית ביישומי אינטרנט ושרותי אינטרנט המיועדים לביצועים גבוהים.

  4. ש: האם ה UTF-8 הוא לא אלא ניסיון להיות תואם ASCII? למה לשמור מאובן ישן זה?

    ת: ללא קשר להאם UTF-8 נוצר במקור כ Hack תאימות, כיום זהו הקידוד הטוב והפופולארי ביותר של Unicode מכל קידוד אחר.

  5. ש: תווי UTF-16 שתופסים יותר מ-2 בתים, נדירים מאד בעולם האמיתי. זה באופן פרקטי גורם ל UTF-16 להיות קידוד של רוחב קבוע עם כל היתרונות. אי אפשר פשוט להזניח את התווים האלו?

    ת: האם אתה רציני לגביי לא לתמוך בכל ה Unicode בדיזיין של התוכנה שלך? ואם אתה כן מתכוון לתמוך בה בכל מקרה, איך העובדה שתווים שהם לא BMP נדירים משנה משהו, חוץ מלהקשות על בדיקות התוכנה? מה שכן משנה, לעומת זאת, הוא שמניפולציות טקסט הן נדירות יחסית באפליקציות אמיתיות- בהשוואה לסתם העברה של מחרוזות כמו שהן. המשמעות של זה של "רוחב כמעט קבוע" אין יתרון ביצועי גדול (ראה ביצועים), בעוד שלמחרוזות קצרות יותר יכול דווקא להיות יתרון משמעותי.

  6. ש: למה לא לאפשר לכל מתכנת להשתמש בשיטת קידוד פנימי המועדפת עליו, כל עוד הוא יודע איך להשתמש בה?

    ת: אין לנו בעיה עם שימוש נכון בכל סוג של קידוד. עם זאת, יש בעיה כאשר לאותו הטיפוס, למשל std::string, יש משמעויות שונות בהקשרים שונים. לחלק המשמעות היא ‘ANSI codepage’ בעוד שלאחרים המשמעות היא "הקוד הזה שבור ולא תומך בטקסט שלא באנגלית". בתוכנות שלנו המשמעות של זה היא מחרוזת תומכת Unicode בקידוד UTF-8. המגוון הזה הוא מקור לבאגים ותסכול. המורכבות הנוספת הזאת היא משהו שהעולם לא באמת צריך. התוצאה היא הרבה תוכנות שבורות Unicode, לכל רוחב התעשייה. JoelOnSoftware מציע כי הפתרון לכל התוכנות שבורות ה Unicode הוא לגרום לכל המתכנתים להיות מודעים לקידוד. אנו מאמינים שבהמצא קידוד אחד שיהפוך לברירת מחדל של ה API, כל אחד יוכל לכתוב תוכנה להעתקת קובץ בצורה נכונה מבלי להיות מומחה לענייני טקסט ושפות.

  7. (7) ש: האפליקצייה שלי היא ממשק משתמש (GUI) בלבד. היא לא מבצעת תקשורת IP או קלט/פלט של קבצים. למה שאני אמיר מחרוזות הלוך ושוב כל הזמן בשביל קריאות API של Windows, במקום פשוט להשתמש במשתני מחרוזות רחבים?

    ת: זהו קיצור דרך תקף. בהחלט יכול להיות שזהו מצב סביר להשתמש במחרוזות רחבות. אבל אם אתה מתכנן להוסיף קובץ קונפיגורציה כלשהוא או כתיבה לקובץ לוג בעתיד, בבקשה תשקול להמיר את הכל למחרוזות לצרות. זה יחסוך צרות.

  8. ש: לשם מה אתם מדליקים את ה Unicode Define, אם אתם לא מתכננים להשתמש במאקרואים LPTSTR/TCHAR/וכ"ו של Windows?

    ת: זהו אמצעי הגנה נוסף כנגד הכנסה של מחרוזת ה *UTF-8 char כפרמטר לפונקציה של Windows API שמצפה ANSI. אנחנו רוצים שזה ייצר שגיאת קומפילציה. זהו באג שקשה למצוא מאותו סוג כמו העברה של מחרוזת []argv ל ()fopen על Windows: ההנחה היא שהמשתמש לעולם לא יעביר קבצים עם שמות שהם לא מה codepage הנוכחי. סביר להניח שלא תמצא באג מסוג זה בבדיקה ידנית, אלא אם הבודקים שלך אומנו לספק קבצי עם שמות סיניים מידי פעם, ועם זאת מדובר בלוגיקה שבורה של התוכנה. הודות ל Unicode Define, תקבל שגיאת קומפיצליה במקרה זה.

  9. ש: האם זה לא תמים במידת מה להאמין שמייקרוסופט יפסיקו להשתמש יום אחד ב widechars ?

    ת: בואו נראה תחילה מתי הם יתחילו לתמוך ב CP_UTF8 כ codepage תקף. זה לא יהיה קשה לביצוע. לאחר מכן אנו לא רואים שום סיבה שבגינה ימשיכו מפתחי Windows להשתמש ב Widechar APIs. בנוסף, הוספת תמיכה ל CP_UTF8 יתקן חלק מהתוכנות והספריות השבורות בUnicode.

    יש האומרים כי הוספת תמיכת CP_UTF8 תשבור אפליקציות קיימות המשתמשות ב ANSI API, ושזה לכאורה הסיבה לכך שמייקרוסופט נזקקה ליצירת API מחרוזת רחבה. זה לא נכון. אפילו חלק מקידודי ANSI פופולאריים הם בעלי אורכים משתנים (למשל Shift JIS), כך שאף קוד נכון לא יהפוך לתקול. הסיבה לכך שמייקרוסופט בחרה ב UCS-2 היסטורית גרידא. בזמנים ההם UTF-8 עוד לא היה קיים, Unicode נחשב רק כ "ASCII רחב יותר", וזה נחשב חשוב להשתמש בקידוד קבוע רוחב.

  10. ש: מה אתם חושבים על BOM" Byte Order Marks" ?

    ת: לפי הסטנדרט של ה Unicode (v6.2, p.30): "השימוש ב BOM לא נדרש ולא מומלץ ל UTF-8". ענייני סדר הבתים הם סיבה נוספת להמנע מ UTF-16. ל- UTF-8 אין בעיות סדר הבתים (Endianness), וה UTF-8 BOM קיים רק כדי להצהיר כי זוהי מחרוזת UTF-8. אם UTF-8 יישאר הקידוד הפופולארי היחיד (כמו שהוא כבר בעולם האינטרנט), ה BOM הופך למיותר. למעשה, כיום רוב קבצי טקסט UTF-8 משמיטים את ה BOM.

    שימוש ב BOMים ידרוש מכל קוד קיים כיום להיות מודעים אליהם, אפילו בתרחישים פשוטים כמו שרשור מחרוזות. זה לא מקובל.

  11. ש: מה אתם חושבים על מעברי שורה?

    ת: תמיד תשתמשו במעברי שורה n (0x0a) line endings\ אפילו ב Windows. קבצים צריכים להכתב ולהקרא בBinary mode, אשר מבטיח פורטביליות- התוכנה תמיד תיתן את אותו הפלט בכל מערכת ההפעלה. מאחר והסטנדרטים של C ו ++C משתמשים במעביר שורה n\ למחרוזות השמורות בזיכרון, זה יגרום לכל הקבצים להכתב בקונבנציות POSIX. זה עלול לגרום לבעיות כשהקובץ נפתח בNotepad ב Windows; עם זאת כל עורך טקסטים ראוי מבין במעברי שורה אלו.

    כמו כן, אנו מעדיפים יחידות SI, פורמט התאריך הבינלאומי ISO-8601 ונקודה צפה על פני פסיק צף .

  12. ש: אבל מה לגבי הביצועים של אלגוריתמי עיבוד טקסט, יישור בתים (Alignment) וכו'?

    ת: האם זה באמת יותר טוב עם UTF-16? אולי כן. ICU משתמש ב UTF-16 מסיבות היסטוריות, ולכן די קשה לאמוד את זה. עם זאת, רוב הזמן מחרוזות נחשבות ל Cookies, לא ממוינות או נהפכות בכל שימוש שני. לכן קידוד דחוס יותר מועדף בשביל ביצועים.

  13. ש: האם זאת באמת אשמתו של UTF-16 שאנשים לא משתמשים בו נכונה, כשהם מניחים שהוא קידוד 16 ביטים לתו?

    ת: לא באמת. אבל כן, בטיחות היא מאפיין מאד חשוב של כל דיזיין, וקידודי תווים אינם יוצאים מן הכלל.

  14. ש: אם std::string משמעו UTF-8, האם לא יתבלבלו בין זה לבין קוד המאחסן "טקסט רגיל" ב std::string?

    ת: אין דבר כזה "טקסט רגיל". אין שום סיבה לאחסן codepage-ANSI או טקסט מוגבל ל ASCII – בתוך אובייקט מסוג String.

  15. ש: האם ההמרות בין UTF-8 ל UTF-16 כאשר מעבירים מחרוזת ל Windows לא יאטו את האפליקציה שלי?

    ת: ראשית, אתה תעשה איזה שהיא המרה בכל מקרה. זה יהיה או בזמן הקריאות למערכת או בתקשורת עם שאר העולם, למשל כשנשלחת מחרוזת טקסט דרך TCP. כמו כן, אלו מה OS API שמקבלים מחרוזות, לעיתים קרובות מבצעים משימות איטיות מטבען, כמו ממשק משתמש או פעולות במערכת הקבצים. אם האינטראקציה שלך עם API של מערכת ההפעלה היא רוב האפליקציה שלך, הנה ניסוי קטן:

    אחד השימושים האופייניים של ה OS API הוא לפתוח קבצים. הפונקציה הזאת רצה ב (184 ± 3)μs על המחשב שלי:

    void f(const wchar_t* name)
    {
        HANDLE f = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
        DWORD written;
        WriteFile(f, "Hello world!\n", 13, &written, 0);
        CloseHandle(f);
    }

    בעוד שזה רץ ב (186 ± 0.7)μs:

    void f(const char* name)
    {
        HANDLE f = CreateFile(widen(name).c_str(), GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
        DWORD written;
        WriteFile(f, "Hello world!\n", 13, &written, 0);
        CloseHandle(f);
    }

    רץ בשני המקרים עם name="D:\\a\\test\\subdir\\subsubdir\\this is the sub dir\\a.txt" ונעשה ממוצע לחמש הרצות.

    זוהי תקורה של %(1 ± 2) בלבד. בנוסף, MultiByteToWideChar אינה פונקציית ההמרה UTF-16 ↔ UTF-8 הכי מהירה.

  16. ש: איך אני כותב קבוע מחרוזת (string literal) ב UTF-8 בקוד ה ++C שלי?

    אם עשית לוקליזציה לתוכנה שלך, אז כל המחרוזות שהן לא ASCII יועלו ממסד נתוני תרגום חיצוני, כך שאין זו בעיה.

    אם אתה עדיין רוצה להכניס תו מיוחד אתה יכול לעשות את זה כדלקמן:

    עם C++11:

    u8"∃y ∀x ¬(x ≺ y)"

    עם מקבצים שאינם תומכים ב ‘u8’ אתה יכול לבצע hard-code ליחידות קידוד של ה UTF-8:

    "\xE2\x88\x83y \xE2\x88\x80x \xC2\xAC(x \xE2\x89\xBA y)"

    עם זאת הדרך הפשוטה ביותר היא פשוט לכתוב את המחרוזת כפי שהיא ולשמור את קובץ המקור המקודד ב UTF-8:

    "∃y ∀x ¬(x ≺ y)"

    לצערנו, MSVC ממיר את זה לאיזה שהוא ANSI codepage, ומשחית את המחרוזת. כדי לעקוף בעיה זו,שמור את הקובץ ב UTF-8 בלי BOM .MSVC יניח שזה ה codepage הנכון ולא יגע במחרוזת שלך. עם זאת, לאחר הפעולה, לא יהיה ניתן להשתמש ב Identifiers ב Unicode וב wide string literals (שלא תשתמש בהם בכל אופן).

  17. ש: יש לי אפליקציית Windows מבוססת CHAR גדולה ומורכבת. מה היא הדרך הקלה ביותר להפוך אותה ל "תומכת Unicode"?

    ת: תשאיר את ה CHARים. תגדיר Unicode ו Unicode_ כדי לקבל שגיאות קומפילציה היכן שאמורים להשתמש ב narrow()/()widen (זה נעשה אוטומטית ע"י הגדרת Use Unicode Character Set בהגדרות פרוייקט של Visual Studio). מצא את כל שימושי ה fstream וה ()fopen, ותשתמש ב wide overloads כמתואר לעיל. בזאת כמעט סיימת את העבודה.

    אם אתה משתמש בסיפריות צד ג שלא תומכות ב Unicode, לדוגמא, שמעבירות מחרוזת שם קובץ כמו שהיא ל ()fopen, אזי תצטרך לעקוף את זה עם כלים כמו ()GetShortPathName, כמתואר לעיל.

  18. ש: מה לגבי פייתון? שמעתי שהם עבדו קשה ב v3.3 כדי לתמוך טוב יותר בUnicode.

    ת: אולי עדיף שהיו עושים פחות כך שהתמיכה היתה טובה יותר. ביישום הסימוכין CPython v3.3, ייצוג המחרוזת הפנימית שונה. ה UTF-16 הוחלף ע"י אחד מהקידודים האפשריים: ISO-8859-1 ,UCS-2 או UCS, כתלות בתוכן המחרוזת. כדי להוסיף תו בודד שלא ASCII או BMP, כל המחרוזת תומר לקידוד אחר. הקידוד הפנימי שקוף לסקריפט. מטרת דיזיין זה היא לשפר את הביצוע אופרציות אינדקס (שליפה לפי מספר) של Unicode Code Points. עם זאת, אנו טוענים כי ספירה או אינדוקס דווקא של Code Points לא אמורות להיות פעולות חשובות למרבית השימושים - בהשוואה, לדוגמא, ל Grapheme Clusters, שאליו למיטב ידיעתנו, פייתון איננה מספקת תמיכה.

    על כך, אנו מתנגדים לטיפול הבלתי תלוי בייצוג מחרוזות לטובת API שקוף לייצוגי עם ייצוגי פנימי ב UTF-8. פעולות אינדקס תספורנה יחידות קידוד במקום Code Points, כפי שאכן עשו לפני השינוי. זה גם יפשט את היישום וגם ישפר את הביצועים, כדוגמת scripts שמתעסקים עם אינטרנט, שכבר גם ככה נשלט ע"י טקסט מקודד UTF-8, ולכן הופכת את תכנות השפה של הפייתון ליותר אטרקטיבית בתכנות צד-שרת. ניתן להתווכח על בטיחות אופרציות חותכות מחרוזות ע"י מתכנתי סקריפטים, מצד שני אותו טיעון תקף גם לגביי חלוקת Grapheme Clusters. אפילו למרות שכיום ה Unicode נתמך לגמריי, אנחנו מאמינים שפייתון, ככלי מודרני ללא נטל היסטורי, חייב לעשות עבודה טובה יותר בתפעול טקסט.

    מעבר לכך, JPython ו- IronPython ממשיכים להסתמך על הקידוד הפחות מוצלח בו משתמשת הפלטפורמה המארחת שלהם (NET. ו- Java בהתאמה) וצריך להקפיד לטפל ב Surrogate Pairs שם כהלכה.

  19. ש: אבל למה std::string? האם לא עדיף היה שתהיה מחלקה אמיתית תומכת UTF-8 כמקובל בתכנות מונחה עצמים?

    ת: לא כל חלק בקוד שמתמודד עם מחרוזות מעורב בעיבוד וולידציה של טקסט. התוכנית להעתקת קבצים ממקודם, שמקבלת קבצים עם שמות Unicode ומעבירה אותם לפוננקציות IO, תיהיה בסדר גמור עם byte buffer פשוט. אם אתה מתכנן סיפרייה שמקבלת מחרוזות כפרמטרים, ה std::string הסטנדרטי, קל המשקל, והפשוט יספיק. עם זאת, זאת תהיה טעות להמציא מחדש מחלקה חדשה של מחרוזת ולהכריח את כולם לעבור עם הממשק המוזר שלך. כמובן שאם מישהו צריך יותר מאשר להעביר מחרוזות, הוא צריך להשתמש בכלים מתאימים לעיבוד טקסט. עם זאת, עדיף שכלים אלו יהיו בלתי תלויים בסוג האחסון בו משתמשים, ברוח הפרדת ה container/algorithm ב STL. למעשה, יש הרואים בממשק ה std::string כיותר מידי נפוח, מאחר והיה עדיף להוציא את רובו מחוץ למחלקת ה std::string.

  20. ש: אני כבר משתמש בגישה זו, ואני רוצה להגשים את החזון שלנו. מה אני יכול לעשות?

    ת: הפץ את הבשורה. תעבור על הקוד שלך ותבדוק איזו ספרייה הכי כואבת לשימוש בקוד פורטבילי תומך Unicode. דווח על באג לממציא הסיפרייה. אם אתה בונה סיפריית C או ++C, השתמש ב *char וב std::string עם הנחה של UTF-8, וסרב לתמוך בדפי קוד ANSI – מאחר והם שבורי Unicode באופן טבעי.

    אם אתה עובד של מייקרוסופט, דחוף ליישום תמיכה של ה CP_UTF8 כאחד מדפי הקוד של narrow API.

    רעיונות נוספים:

    • צור מאגר פאטצים של סיפריות צד ג נפוצות שימוש לתמיכת UTF-8 (למשל, PugiXML ,LibTIFF וכו') אלו נכתבים בסטנדרט C ו Windows לא מעניינת אותם.
    • צור פאטצ' link-time לפונקציות סטנדרטיות של סיפרייה (()fopen) ב Windows, שיבצע את ההמרה לפרמטר הנכון. זה יכול להעשות גם ל ()main ולמשתני הסביבה הגלובאליים.

על המחברים

מסמך זה נכתב ע"י פבל רדזיוילובסקי, יעקב גלקה וסלבה נובגורודוב. מסמך זה הוא תוצאה של מחקר וניסיון בהתמודדות עם בעיות אמיתיות של נושאים הקשורים ל Unicode טעויות שנעשו ע"י מתכנתים. מטרתנו היא להגדיל את המודעות לבעיות של טקסט ולעורר שינויים בתעשייה כולה כדי לגרום לתכנות תומך Unicode להיות קל יותר, ובסופו של דבר לשפר את חווית המשתמש של תוכנות אלו שנכתבו ע"י בני אדם. אף אחד מאיתנו לא חלק מה Unicode consortium.

תודות מיוחדות ל: גלן לינדרמן שסיפק מידע לגביי פייתון. קון, ג'ל גירטס, לייזי רוי וג'אן רוג שדיווחו על באגים ושגיאות הדפסה במסמך זה. כמו כן, לקארינה שכטמן שעזרה בעריכת הטקסט ככלל ובעריכתו לעברית בפרט.

מסמך זה נכתב בעיקר בהשראת דיונים בtackOverflow , שפותחו ע"י ארתיום בייליס, הממציא של Boost.Locale. השראה נוספת הגיעה מקונבנציות הפיתוח ב VisionMap וה tauday.org של מייקל הרטל.

קישורים חיצוניים

אתם מוזמנים להשאיר משוב/הערות בדף הפייסבוק שלנו UTF-8 Everywhere. אנו נעריך מאד את משובכם והערותיכם.

1UTF8gQmvChQ4MwUHT6XmydjUt9TsuDRn
תרומת ביטקוין ל 1UTF8gQmvChQ4MwUHT6XmydjUt9TsuDRn
התרומות ישמשו להמשך מחקר וקידום.

שינוי אחרון: 1970-01-01