⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sta_9169.htm

📁 C++标准库 C++标准库 C++标准库 C++标准库
💻 HTM
📖 第 1 页 / 共 2 页
字号:
</TD><TD>String collation<BR></TD></TR><TR VALIGN=top><TD><SAMP>mblen()</SAMP>, <SAMP>mbtowc()</SAMP>, <SAMP>wctomb()</SAMP>, ...<BR></TD><TD>Multibyte functions<BR></TD></TR><TR VALIGN=top><TD><SAMP>cat_open()</SAMP>, <SAMP>catgets()</SAMP>, <SAMP>cat_close()</SAMP><BR></TD><TD>Message retrieval<BR></TD></TR></TABLE></CENTER><A NAME="1.3.2"><H3>1.3.2 The C++ Locales</H3></A><P>In C++, a locale is a class called <SAMP>locale</SAMP> provided by the Standard C++ Library.  The C++ class <SAMP>locale</SAMP> differs from the C locale because it is more than a language table, or data representation of the various culture and language dependencies.  It also includes the internationalization services, which in C are global functions.</P><P>In C++, internationalization semantics are broken out into separate classes called facets.  Each facet handles a set of internationalization services; for example, the formatting of monetary values.  Facets may also represent a set of culture and language dependencies, such as the rules and symbols for monetary information.</P><P>Each locale object maintains a set of facet objects.  In fact, you can think of a C++ locale as a container of facets, as illustrated in Figure 5 below:</P><H4>Figure 5.  A C++ locale is a container of facets</H4><BR><IMG SRC="images/image5.gif"><A NAME="1.3.3"><H3>1.3.3 Facets</H3></A><P>Facet classes encapsulate data that represents a set of culture and language dependencies, and offer a set of related internationalization services.  Facet classes are very flexible.  They can contain just about any internationalization service you can invent.  The <I>Standard C++ Library</I> offers a number of predefined <I>standard</I> <I>facets</I>, which provide services similar to those contained in the C library.  However, you could bundle additional internationalization services into a new facet class, or purchase a facet library.</P><A NAME="1.3.3.1"><H4>1.3.3.1 The Standard Facets</H4></A><P>As listed in Table 1, the C locale is composed of six categories of locale-dependent information:  <SAMP>LC_NUMERIC</SAMP> (rules and symbols for numbers), <SAMP>LC_TIME</SAMP> (values for date and time information), <SAMP>LC_MONETARY</SAMP> (rules and symbols for monetary information), <SAMP>LC_CTYPE</SAMP> (character classification and conversion), <SAMP>LC_COLLATE</SAMP> (collation sequence), and <SAMP>LC_MESSAGE</SAMP> (formats and values of messages).  </P><P>Similarly, there are six groups of standard facet classes.  A detailed description of these facets is contained in the <I>Class Reference</I>, but a brief overview is given below.  Note that an abbreviation like <SAMP>num_get &#60;charT,InputIterator></SAMP> means that <SAMP>num_get</SAMP> is a class template taking two template arguments, a character type, and an input iterator type.  The groups of the standard facets are:</P><UL><LI><P><B>Numeric.  </B>The facet classes <SAMP>num_get&#60;charT,InputIterator> </SAMP>and <SAMP>num_put&#60;charT, OutputIterator></SAMP> handle numeric formatting and parsing.  The facet classes provide <SAMP>get()</SAMP> and <SAMP>put()</SAMP> member functions for values of type <SAMP>long</SAMP>, <SAMP>double</SAMP>, etc.</P><P>The facet class <SAMP>numpunct&#60;charT></SAMP> specifies numeric punctuation.  It provides functions like <SAMP>decimal_point()</SAMP>, <SAMP>thousands_sep()</SAMP>, etc.</P></LI><LI><P><B>Monetary.  </B>The facet classes <SAMP>money_get&#60;charT,bool,InputIterator></SAMP> and <SAMP>money_put&#60;charT, bool, OutputIterator></SAMP> handle formatting and parsing of monetary values.  They provide <SAMP>get()</SAMP> and <SAMP>put()</SAMP> member functions that parse or produce a sequence of digits, representing a count of the smallest unit of the currency.  For example, the sequence $1,056.23 in a common US locale would yield 105623 units, or the character sequence "105623". </P><P>The facet class <SAMP>moneypunct &#60;charT, bool International></SAMP> handles monetary punctuation like the facet <SAMP>numpunct&#60;charT></SAMP> handles numeric punctuation.  It comes with functions like <SAMP>curr_symbol()</SAMP>, etc.</P></LI><LI><P><B>Time.  </B>The facet classees <SAMP>time_get&#60;charT,InputIterator></SAMP> and <SAMP>time_put&#60;charT, OutputIterator></SAMP> handle date and time formatting and parsing.  They provide functions like <SAMP>get_time()</SAMP>, <SAMP>get_date()</SAMP>, <SAMP>get_weekday()</SAMP>,etc.</P></LI><LI><P><B>Ctype.  </B>The facet class <SAMP>ctype&#60;charT></SAMP> encapsulates the Standard C++ Library <SAMP>ctype</SAMP> features for character classification, like <SAMP>tolower()</SAMP>, <SAMP>toupper()</SAMP>, <SAMP>isspace()</SAMP>, <SAMP>isprint()</SAMP>, etc.</P></LI><LI><P><B>Collate.  </B>The facet class <SAMP>collate&#60;charT></SAMP> provides features for string collation, including a <SAMP>compare()</SAMP> function used for string comparison.</P></LI><LI><P><B>Code Conversion.  </B>The facet class <SAMP>codecvt&#60;fromT,toT,stateT></SAMP> is used when converting from one encoding scheme to another, such as from the multibyte encoding JIS to the wide-character encoding Unicode.  Instances of this facet are typically used in pairs.  The main member function is <SAMP>convert()</SAMP>.  There are template specializations <SAMP>&#60;char, wchar_t, mbstate_t></SAMP> and <SAMP>&#60;wchar_t, char, mbstate_t></SAMP> for multibyte to wide character conversions.</P></LI><LI><P><B>Messages.  </B>The facet class <SAMP>messages&#60;charT></SAMP> implements the X/Open message retrieval.  It provides facilities to access message catalogues via <SAMP>open()</SAMP> and <SAMP>close(catalog)</SAMP>, and to retrieve messages via <SAMP>get(..., int msgid,...)</SAMP>.</P></LI></UL><P>The names of the standard facets obey certain naming rules.  The <SAMP>get</SAMP> facet classes, like <SAMP>num_get</SAMP> and <SAMP>time_get</SAMP>, handle parsing.  The <SAMP>put</SAMP> facet classes handle formatting.  The <SAMP>punct</SAMP> facet classes, like <SAMP>numpunct</SAMP> and <SAMP>moneypunct</SAMP>, represent rules and symbols.</P></LI></UL><A NAME="1.3.4"><H3>1.3.4 Differences between the C Locale and the C++ Locales</H3></A><P>As we have seen so far, the C locale and the C++ locale offer similar services.  However, the semantics of the C++ locale are different from the semantics of the C locale:</P><UL><LI><P>The <I>Standard C locale </I>is a global resource:  there is only one locale for the entire application.  This makes it hard to build an application that has to handle several locales at a time.</P></LI><LI><P>The <I>Standard C++ locale</I> is a class.  Numerous instances of class <SAMP>locale</SAMP> can be created at will, so you can have as many locale objects as you need. </P></LI></UL><P>To explore this difference in further detail, let us see how locales are typically used.</P></LI></UL><A NAME="1.3.4.1"><H4>1.3.4.1 Common Uses of the C locale</H4></A><P>The C locale is commonly used as a default locale, a native locale, or in multiple locale applications.</P><P><B>Default locale.  </B>As a developer, you may never require internationalization features, and thus never set a locale.  If you can safely assume that users of your applications are accommodated by the classic US English ASCII behavior, you have no need for localization.  Without even knowing it, you will always use the default locale, which is the US English ASCII locale.</P><P><B>Native locale.  </B>If you do plan on localizing your program, the appropriate strategy may be to retrieve the native locale once at the beginning of your program, and never, ever change this setting again.  This way your application will adapt itself to one particular locale, and use this throughout its entire run time.  Users of such applications can explicitly set their favorite locale before starting the application.  Usually the system's default settings will automatically activate the native locale.</P><P><B>Multiple locales.  </B>It may well happen that you do have to work with multiple locales.  For example, to implement an application for Switzerland, you might want to output messages in Italian, French, and German.  As the C locale is a global data structure, you will have to switch locales several times.</P><P>Let's look at an example of an application that works with multiple locales.  Imagine an application that prints invoices to be sent to customers all over the world.  Of course, the invoices must be printed in the customer's native language, so the application must write output in multiple languages.  Prices to be included in the invoice are taken from a single price list.  If we assume the application is used by a US company, the price list will be in US English.</P><P>The application reads input (the product price list) in US English, and writes output (the invoice) in the customer's native language, say German.  Since there is only one global locale in C that affects both input and output, the global locale must change between input and output operations.  Before a price is read from the English price list, the locale must be switched from the German locale used for printing the invoice to a US English locale.  Before inserting the price into the invoice, the global locale must be switched back to the German locale.  To read the next input from the price list, the locale must be switched back to English, and so forth.  Figure 6 summarizes this activity:</P><H4>Figure 6.  Multiple locales in C</H4><BR><IMG SRC="images/image6.gif"><P>Here is the C code that corresponds to the previous example<A HREF="endnote2.htm#fn7">[7]</A>:</P><PRE>double price;char buf[SZ];while ( _ )  // processing the German invoice{  setlocale(LC_ALL, "En_US");   fscanf(priceFile,"%fl",&#38;price);   // convert $ to DM according to the current exchange rate   setlocale(LC_ALL,"De_DE");   fprintf(invoiceFile,"%f",price);}</PRE><P>Using C++ locale objects dramatically simplifies the task of communicating between multiple locales.  The iostreams in the <I>Standard C++ Library</I> are internationalized so that streams can be <I>imbued</I> with separate locale objects.  For example, the input stream can be imbued with an English locale object, and the output stream can be imbued with a German locale object.  In this way, switching locales becomes unnecessary, as demonstrated in Figure 7:</P><H4>Figure 7.  Multiple locales in C++</H4><BR><IMG SRC="images/image7.gif"><P>Here is the C++ code corresponding to the previous example:</P><PRE>priceFile.imbue(locale("En_US"));invoiceFile.imbue(locale("De_DE");double price;while ( _ )  // processing the German invoice{  priceFile >> price;   // convert $ to DM according to the current exchange rate   invoiceFile &#60;&#60; price;}</PRE><P>Because the examples given above are brief, switching locales might look like a minor inconvenience.  However, it is a major problem once code conversions are involved.</P><P>To underscore the point, let us revisit the JIS encoding scheme using the shift sequence described in Figure 2, and repeated below.  With these encodings, you will recall that you must maintain a shift state while parsing a character sequence, as shown in Figure 8:</P><H4>Figure 8.  The Japanese text encoded in JIS from Figure 2</H4><BR><IMG SRC="images/image8.gif"><P>Suppose you are parsing input from a multibyte file which contains text that is encoded in JIS, as shown in Figure 9.  While you parse this file, you have to keep track of the current shift state so you know how to interpret the characters you read, and how to transform them into the appropriate internal wide character representation.</P><H4>Figure 9.  Parsing input from a multibyte file using the global C locale</H4><BR><IMG SRC="images/image9.gif"><P>The global C locale can be switched during parsing; for example, from a locale object specifying the input to be in JIS encoding, to a locale object using EUC encoding instead.  The current shift state becomes invalid each time the locale is switched, and you have to carefully maintain the shift state in an application that switches locales.</P><P>As long as the locale switches are intentional, this problem can presumably be solved.  However, in multithreaded environments, the global C locale may impose a severe problem, as it can be switched inadvertently by another otherwise unrelated thread of execution.  For this reason, internationalizing a C program for a multithreaded environment is difficult.</P><P>If you use C++ locales, on the other hand, the problem simply goes away.  You can imbue each stream with a separate locale object, making inadvertent switches impossible.</P><P>Let us now see how C++ locales are intended to be used.</P><A NAME="1.3.4.2"><H4>1.3.4.2 Common Uses of C++Locales</H4></A><P>The C++ locale is commonly used as a default locale, with multiple locales, and as a global locale.</P><P><B>Default locale.</B>  If you are not involved with internationalizing programs, you won't need C++ locales any more than you need C locales.  If you can safely assume that users of your applications are accommodated by classic US English ASCII behavior, you will not require localization features.  For you, the <I>Standard C++ Library</I> provides a predefined locale object, <SAMP>locale::classic()</SAMP>, that represents the US English ASCII locale. </P><P><B>Multiple locales.</B>  Working with many different locales becomes easy when you use C++ locales.  Switching locales, as you did in C, is no longer necessary in C++.  You can imbue each stream with a different locale object.  You can pass locale objects around and use them in multiple places.</P><P><B>Global locale.</B>  There is a global locale in C++, as there is in C.  You can make a given locale object global by calling <SAMP>locale::global()</SAMP>.  You can create snapshots of the current global locale by calling the default constructor for a locale <SAMP>locale::locale()</SAMP>.  Snapshots are immutable locale objects and are not affected by any subsequent changes to the global locale.  Internationalized components like iostreams use it as a default.  If you do not explicitly imbue your streams with any particular locale object, a snapshot of the global locale is used.</P><P>Using the global C++ locale, you can work much as you did in C.  You activate the native locale once at program start--in other words, you make it global--and use snapshots of it thereafter for all tasks that are locale-dependent.  The following code demonstrates this procedure:</P><PRE>locale::global(locale(""));                                   //1_string t = print_date(today, locale());                       //2_locale::global(locale("Fr_CH"));                              //3_cout &#60;&#60; something;                                            //4</PRE><TABLE CELLPADDING="3"><TR VALIGN="top"><TD>//1</TD><TD>Make the native locale global.</TD></TR><TR VALIGN="top"><TD>//2</TD><TD>Use snapshots of the global locale whenever you need a locale object.  Assume that <SAMP>print_date()</SAMP> is a function that formats dates.  You would provide the function with a snapshot of the global locale in order to do the formatting.  </TD></TR><TR VALIGN="top"><TD>//3</TD><TD>Switch the global locale; make a French locale global.</TD></TR><TR VALIGN="top"><TD>//4</TD><TD>Note that you need not explicitly imbue any streams with the global locale.  They use a snapshot of the global locale by default.</TD></TR></TABLE><A NAME="1.3.5"><H3>1.3.5 Relationship between the C Locale and the C++ Locale</H3></A><P>The C locale and the C++ locales are mostly unrelated.  However, making a C++ locale object global via <SAMP>locale::global()</SAMP> affects the global C locale and results in a call to <SAMP>setlocale()</SAMP>.  When this happens, locale-sensitive C functions called from within a C++ program will use the global C++ locale.</P><P>There is no way to affect the C++ locale from within a C program.</P><HR><A HREF="int_7592.htm"><IMG SRC="images/prev.gif"></A> <A HREF="booktoc2.htm"><IMG SRC="images/toc.gif"></A><A HREF="loc_1541.htm"><IMG SRC="images/next.gif"></A><P>&copy;Copyright 1996, Rogue Wave Software, Inc.</P></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -