Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 229
Текст из файла (страница 229)
*/); Г.4.7. Сообщения Большинство пользователей предпочитают взаимодействовать с программой на своем родном языке. Однако мы не можем предложить стандартный механизм, обеспечивающий в общем виде зависящее от локализации взаимодействие с программой. Вместо этого, библиотека предоставляет нехитрый механизм хранения зависящих от локализации наборов строк, из которых программист может создавать простые сообщения. В сущности, класс текяадея (сообщения) реализует тривиальную базу данных, доступную только для чтения: с1аяя ятйэтеккауея Ьаяе ( риЫ)а '(о~о Приложение Г Локализация 1уреде/!п1 са1а(од, // спи « иденгпификатора каталога В 1етр(аге <с1аяя СЬ> с1аяя вЫ:тевяауея: риЫк !оса!е; Гасе!, р«Ы/с тезвауея Ьаяе ( риб!!а 1урес)е) СЬ оба г 1уре; 1уре>1е/Ьаз(с я1г1«у<СИ> зМ«у 1уре; ехр!!с!1 теввауея(з!ее 1 г = 0); си1а!оу орел(солз1базгс ягг(ад<сбое>й/л, сопя1 1оса1ей) соля!, вгг/пу 1уре уе1(са1а)оу с, !«1 яе1,1п1 тзугд, сопя! в1ппд 1урей с/) солей ооЫ с!ояе(са1а!ау с) сопв1, Ыа1сс(оса1е..Ы!И, //идентификатор фасети (у Г2, у Г3, Ч ГЗ.1) рго1есгес(: -теяяадея() // вирту«льне>е до функ>(ии" (сл>.
Ч Г 4.1) я1гис1 Яе1 ( оесгог<в1г/пу> тзуя; ), яггис1 Си1 ( оес1ог<йе1> веге; ); с)аяз Му тевяауея: риЫсс теяяауея<сбаг> ( иесИ>г Сас>й са1а!оуя; рибйс. ехр11с11 Му теяяауея(иее 1= О): са1а(оув(*пел> иес1ог Саг>) ( си1а1оу Ио орел(сопягз1ппуй в, со»в1 !оса!ей 1ос) сопя!; я1г>пуйо уе1(с«1а!оде, тгя, >п1т, сопыя1ппуй) сопя!, // ооЫ с(о с/ове(са1а(оу сай соля1 ( Яса1а1оуя.я(ее() >с) са1а!оув.егазе(са1а!одв.беу!п()»с) открыть ка>полог я пояунигпь сообщение (в,т) е с Вызов орел(з, 1ос) открывает «каталог» (сага) он) по имени в сообщений для локализации 1ос, Каталог — это набор строк, организованных зависящим от реализации способом и доступных посредством функции >пеззауезсде1(). Если открыть каталог по имени в невозможно, возвращается отрицательное значение.
Каталог должен бвят открыт до первого использования де!(). Вызов с1ояе(са1) закрывает каталог, идентифицируемый через са1, и освобождает все ресурсы, связанные с данным каталогом. Вызов зе1(са1, зе1, Ы, 'ме выи>ло1') осуществляет поиск сообщения (зе1, Ы) в каталоге са1. Если строка найдсна, де!() возвращает зту строку в противном случае Ь>е1() возвращает строку по умолчанию (здесь -- з1г!лй("ме вь>мяло)')).
Приведем пример фасета тезвауез для реализации, в которой каталог сообщений выполнен в виде вектора множеств «сообщений», а само «сообщение» является строкой: Г4, Стандартные фасеты -Му тевяауея() ( йе1е1е йса1а!одя; ) Все функции-члены тевяадез объявлены сопз1, поэтому структура данных каталога (оес1ог<5е1>) хранится вне фасета.
Сообщение выбирается путем задания каталога, множества внутри каталога и строки сообщения во множестве. Строка, передаваемая в качестве аргумента, используется в качестве результата по умолчанию в случае, если в каталоге не найдено сообщение: зптпу Му теявауек йо уе1(си1а!оу са1, !п1 яе1, !п1 тву, сопя1 в1г!пуй йе/) сопя1 !1 (сага!одя.в/хе()<=са1) ге1игп Не/) Сагй с = сага!пуз[си!]; !/(с.зегз.з/ве()<=зе1) геввгп йеЯ Весй з = с яе1з(яе1] !! (з,тздя изе()<=тку) ге1игп дел ге!ига в.
тзуя(тяу]' Открытие каталога состоит в считывании текстового представления с диска в структуру Са1. В примере я выбрал тривиально читаемое представление. Множество ограничено «< и»>, а каждое сообщение является строкой текста: теяяауея<сЬаг>гсага1оуМу теяяауежзбо ореп(сопя!я!с/пуйп, сопя11оса1е8 1ос) сопя1 ( зге/пд па = и + !оса!е(). пате(). узг еатЯпп.с згг()) (/((/) ге1игп — 1; сиса!оуз.рияЬ басу(Са1()).
Сабу с = си1а!оув. басу(). згг(пуз; тЬ11е (/»я йй з== «< ) ( // чтение множество 5е1 с.яе1крияЬ Ьасу(бе1()'! Зегй яя = с.зегз.басу() игЬ1!е(дег!!пеЯз) ййз (= '»>') яя.тяуя.ризЬ Ьасй(я); // чтение сооби!ения ге!игл са1а!оукяове() — 1; Пример тривиального использования: !п1 та(п() ( !/()Ьаз ~асе1<Му теязауез>(!оса!е())) ( сегг«не найден фасет сообщений в ' «!оса!е().патеч «'~,п', ех11(1); сопя! теязауез<сЬаг>й т = изе ~асе1<Му тезвауез>(!оса!е()) ехсега я!ггпу теязауе сигессогу; // место, где я храню свои сообщения т1са1 = т.ореа(тевяауе й/гес1огу, !оса!е()). 1/(со 1<0) ( 1012 Приложение Г. Локализация сегг « 'не найден каталог~,п', ех!1(!); сои! «тяе1(са1, О, О, "А вот и не нашел р) «епд1; сои1 «т.ие1(саг, 1, 2, А вот и не нашел!" ) «епд1; сои! «т яе1(са1, !, 3, ' А вот и не нашел !") «епь!1; сои! «т.яе1(саг, 3, О, 'А вот и не нашел!") «епй1; ) Если каталог выглядит следующим образом: «< привет! пока! »> «< да нет может быть »> на выходс этой программы будет: привет! можеьп быть А вот и не нашел! А вот и не нашел! Г.4.7.1.
Использование сообщений из других фасетое Кроме того, что сообщения являются хранилищем зависящих от локализации строк, предназначенных для общения с пользователями, класс тевваяев может содержать строки для других фасетов. Например, фасет оеаяоп !о Я Г.3.2) можно написать так: с!азз Зеояоп ьо: риЬОс !оса!е: Гасе! ( сопя! тезяаяея<сйаг>З т; // справочник сообщений (днвсIогр) тсса1; // каталог сообщении (са1а!оо) риЫ!с: с!азз М!яв!пи тевяаяез ( ); Зеазоп !о(т1 ! = 0) : !осиIе: /осе!(!), т(изе Хасе1<Зеаяоп теяяаиея>(!оса!е())), са1(т.орел(теяяаяе й!гес1огу, !оса!е())) ( !Г(со!<0) 1Ьгош М!яя!пя теяяаяея() ) -Зеавоп !о() () // чтобы иметь возможность Оничьпожить обьекты // Яеаяоп !о ЦО" Г.З) сопя! згг!пай 1о я1г(Беаяоп х) сопз1; // строковое предспгавление х Ьоо!/гот яв(сопя! ягппОЬ я, Зеазопйх) соляр // поместить Яеизоп, // соответствующий я, в х зтаяс IосаIесЫ Ы; //идентификатор фасета Я Г2, 3 ГЗ, 3" ГЗ.I) 1013 Г5.
Советы !оса!еси( Беазоп 1оспб // определение обьекти идентификатора сопз1з1г(пуй Беазоп 1осго зп(Беазопх) сапы ( ге!игп т — >де1(са1, х, неги такого времени года'); ) Ьоо! Беазоп !о;:Яот зв(сопз1 з(ггпуй з, Беазопй х) сопзг ( /ог (1п1 1 = Беазопсзрг!пд; 1«=Беазопспш1ег; 1++) у«т-уег(са1, Ь нет такого времени года' ) == з) ( х = Беазопй); ге1игп Ьие; ге1игп~а!зе; Решение с использованием сообщений отличается от исходного (з Г.3.2) тем, что у разработчика набора строк Беазоп для новой локализации должна быть возможность добавлять их в справочник теззадез.
Это не представляет сложности для того, кто включает новую локализацию в среду исполнения. Однако, поскольку теззадез предоставляют интерфейс только для чтения, добавление нового набора названий времен года может оказаться за рамками возможностей прикладного программиста. Имеется и версия теззайез вида булате Я Г,4, з Г.4.1): 1етр!а1е<с!азз СЬ> с(азз згдстеззауез Ьупате риЬ11с телешев<СИ> ( /* ... */ ); Г.5. Советы [1] Готовьтесь к тому, что каждая нетривиальная программа или система, непосредственно взаимодействующая с людьми, будет использована в нескольких странах; Б Г.1. [2] Не полагайтесь на то, что все используют тот же набор символов, что и вы; з ГА.1. [3] Предпочитайте 1оса1ез написанию специального («аб 11ось) кода национально- зависимого ввода/вывода; Б Г.1.
[4] Избегайте прямого упоминания в тексте программы строковых имен локализаций; ~ 1".2.1. [б] Мипимнзируйте использование глобальной информации о формате; Б 1'.2З, з 1АА,7. [6] Отдавайте предпочтение зависящему от локализации сравнению строк и сортировке; Б Г.2А, З Г.4.1. [7] Делайте фасеты неизменяемыми; Б Г.2.2, Б ГЗ. [8] Сосредоточьте смену 1оса1е в нескольких фрагментах программы; 4 Г.2.3. [9] Предоставьте локализации управлять временем жизни фасетов; З Г.З. [10] При написании функций ввода/вывода, зависящих от локализации, не забывайте обрабатывать исключения, генерируемые предоставляемыми пользователями (замешенными) функциями; Б ГА.2.2. [11] Пользуйтесь простым типом Мопеу для хранения денежных величин; Б Г.4.3.
1014 Приложение Г Локализация (12) Пользуйтесь простыми определяемыми пользователем типами для хранения значений, требующих завнсяв1его от локализации ввода/вывода (в противовес приведению значений встроенных типов нли приведению к встроенным типам); з ГА.З. (131 Не верьте замерам времени исполнения, пока не оцените все влияющие на них фактор ы; 9 Г.
4 А. 1, 1141 Помните об ограни*.нпях, наклалываемых 1(те 8 9 Г 4А.1, 9 Г 44 5. 115) Пользуйтесь процедурой ввода даты, воспринимающей различные входные форматы; 9 ГА.4.5. (161 Отдавайте прсдпочтсние функциям классификации, в которых локализация присутствует явно; 9 Г.4.5, з ГА.5.1. Г.6. Упражнения 1.
(*2.5) Определите Яеазол (о (9 Г.3.2) для языка, отличного от американского английского, 2. (*2) Определите класс Зеазол ьв (9 Г,3.2), принимающий набор строк названий времен года в качестве аргумента конструктора, так чтобы названия времен года различных локализаций могли быть представлены в виде объектов этого класса. 3.
(*3) Напишите функцию со((а1е«сдпг>хсотраге1) со словарным упорядочиванием. Предпо ггнтельно сделать зто для языка типа немецкого или французского, в алфавитах которых букв больше, чем в английском, 4. (*2) Напишите программу, которая чиз ает н пишет логические значения в виде чисел, английских слов ц слов любого другого языка по вашему выбору. 5. ('2.5) Определите тип Т(те для представления времени дня.
Определите пш Тза1е алг) рте (дата и время) с помощью типов Т(те и 1)а(е. Обсудитс плюсы и минусы этого подхода цо сравнению с 1)а(е из (9 ГА.4). Реализуйте зависящий от локализации ввод/вывод для Т(те и Т)а1е алг1 1(те. 6. (*2.5) Спроектируйте и реализуйте фасст почтового индекса. Сделайте это как минимум для двух стран с непохожими соглашениями относительно написания адресов. 1!апрнмер: л0'07932 и СВ21ЯА.