LIBRERIA <locale>
Introducción
Tradicionalmente, desarrollar
aplicaciones para diversos mercados presentaba problemas de difícil solución.
Por ejemplo: Inglés-americano; Inglés del Reino Unido; Francés; Español;
Alemán, Etc. Cada cual utilizaba diversas técnicas para intentar mantener todas
estas versiones con un mínimo de esfuerzo. Una de ellas consistía en mantener
todos los mensajes y avisos textuales (ayudas, Etc.) en ficheros separados del
fuente, de forma que (con ayuda de traductores profesionales) fuese fácil
mantener versiones en los diversos lenguajes. Estas versiones eran compiladas
según el caso mediante directivas condicionales de preproceso. Sin embargo, esto
no era siempre factible, en especial en las rutinas de E/S formateadas. Las pantallas ("Screens") de
entrada/salida de datos y los listados de salida debían ser mantenidos en el
fuente en diversas versiones que eran igualmente mantenidas mediante complicadas
sentencias condicionales de preproceso.
Localismos del lenguaje:
Comprende el lenguaje natural
utilizado (español, inglés, francés griego, Etc.) y el juego de caracteres que
constituye su alfabeto, incluyendo los signos de puntuación.
Ejemplo:
Inglés americano: a-z; A-Z; signos de puntuación
Alemán: a-z;
A-Z; signos de puntuación; äöü ÄÖÜ ß
Griego: a-w;
A-W; signos de puntuación
Localismos numéricos:
La representación de las cantidades
numéricas depende de costumbres locales que varían de país en país. La más
conocida es quizás la distinta forma de representar la fracción decimal de los
números fraccionarios. En inglés americano se utiliza un punto . para separar
la parte entera de la decimal, mientras que en la mayor parte de Europa se
utiliza la coma , para este mismo fin [3]. Recíprocamente, en USA se utiliza la
coma para separar los grupos de tres cifras de las magnitudes grandes (símbolo
de separación de miles) y en Europa se utiliza el punto. Incluso la forma de
agrupar las cifras es distinta en las diversas culturas.
Ejemplo:
USA: 1,000,000,55
España: 1.000.000,55
Nepal: 10,00,000.55
Localismos de moneda:
Además de que el sistema monetario es
distinto en los diversos países del mundo, también existen importantes
diferencias en la forma en que son representadas las magnitudes monetarias,
incluyendo el símbolo de la moneda y la representación de los valores negativos.
Por ejemplo, existen dos formas de representar la misma cantidad de dólares
USA:
USA: $24.99
US
Resto de países del mundo: 24.99 USD
La posición del símbolo monetario
puede estar al principio, al final, o incluso en medio del valor numérico:
Japón: 155
España [4] : 13,50 Pts.
Alemania [4]: 13,50 DM.
Reino Unido [5]: #14 19s. 6d.
Localismos de fecha y
hora:
Las formas de representación de fecha
y hora varían grandemente entre los diversos grupos culturales. Algunos países
o grupos utilizan un sistema horario de 24 horas, mientras otros utilizan el de
12. Por supuesto en cada lengua varían las abreviaturas utilizadas para meses y
días de la semana, así como los símbolos utilizados para separarlas. A
continuación se muestran diversos ejemplos de representación de la misma fecha
en diferentes países.
USA: 10/29/96 Tuesday, October 29, 1996
Hungría: 1996. 10. 29. 1996. oktöber 29.
Italia: 29/10/96 martedì 29 ottobre 1996
Grecia: 29/10/1996 Trith, 29 Oktwbriou 1996
Alemania: 29.10.96 Dienstag,
29. Oktober 1996
España: 29-10-96 Martes 29 de Octubre de 1996
Localismos en C:
Tanto los programadores como los
fabricantes de compiladores fueron rápidamente conscientes que sería de gran
ayuda disponer en el propio lenguaje de
herramientas específicas que ayudaran a la internacionalización. La idea es que
la información correspondiente a las diferencias locales fuese de algún modo
accesible al programa, de forma que pudiera ser utilizada por las rutinas
afectadas (principalmente de E/S) de la forma más automática posible. En
respuesta a esta necesidad, el consorcio X/Open [8] estandarizó una serie de
servicios que proporcionan un soporte de estas características en el lenguaje
C. Estos servicios son conocidos como NLS ("Native Languaje Support")
o XPG4.
De acuerdo con el XPG4 los localismos
C están agrupados según su contenido en varias categorías, identificadas
internamente mediante seis constantes manifiestas, que coinciden
aproximadamente con las que hemos enunciado:
LC_NUMERIC
Reglas y símbolos para
localismos numéricos.
LC_TIME Detalles y reglas para fecha y
hora
LC_MONETARY Reglas y símbolos para localismos de
moneda.
LC_CTYPE Reglas de clasificación de
caracteres y conversión mayúsculas/minúsculas
LC_COLLATE
Reglas de ordenación
LC_MESSAGES
Formato y valor de los mensajes
Para el manejo de estas estructuras se
han provisto dos nuevas funciones: localeconv() , y setlocale()
para cargar los ficheros externos.
Es corriente referirse colectivamente a estos conjuntos de valores y
reglas como un locale. Inicialmente el compilador proporciona unos valores por
defecto a estos locales, pero se pueden cargar otros desde el fichero externo
correspondiente mediante setlocale.
A partir de su invocación, las reglas y criterios del nuevo locale quedan a
disposición de las funciones que los necesiten.
La definición y reglas de uso de
setlocale pueden ser consultadas en el manual de su compilador, pero
adelantaremos aquí que no solo permite establecer nuevos valores para los
localismos, también consultar los valores actuales. Su definición está en
<locale.h> o <clocale>, y existe en dos versiones: una para
caracteres normales y otra para caracteres anchos. La primera responde a la
declaración:
char* setlocale(int category, const char*
locale);
La función devuelve un puntero a
carácter que señala el principio de una cadena identificativa del localismo. El
argumento category es una constante manifiesta que permite definir que
categoría se fija/consulta. Puede ser cualquiera de las señaladas en la tabla
anterior o LC_ALL que afecta a todas las
categorías. El argumento locale es un
puntero a cadena de caracteres que identifica el locale que se desea
cargar. Este argumento acepta diversas
formas:
"lang[_country[.code_page]]" Establece el locale que se cargará
".code_page" Establece la
página de códigos que se debe cargar
"" Establece
el localismo establecido por defecto para el SO.
NULL Modo
consulta: devuelve el localismo actualmente en uso sin realizar
ningún cambio.
Localismo nativo
En ocasiones el programador no impone
un localismo específico, decidiendo que sea el usuario el que establezca el que
desea. En estos casos puede utilizarse al principio del programa una invocación
en la forma:
setlocale(LC_ALL, "");
Esta llamada establece el localismo establecido
por defecto en el SO.
Funciones dependiente
del localismo
De lo dicho anteriormente se desprende
que un número de funciones de la Librería Estándar C adaptan automáticamente
ciertos detalles de su funcionamiento de los valores del locale. Este tipo de
código se denomina adaptativo y a título de ejemplo podemos citar las
siguientes funciones:
Función Tipo de
información que maneja
isalpha(), isupper(), isdigit(), ... Información
sobre caracteres.
tolower(), toupper() Conversiones
mayúsculas/minúsculas
atof(),
atoi(), atol() Convertir cadenas de
caracteres a valores numéricos
strftime(), ... Fecha y hora
strfmon() Monetaria
printf(), scanf(), ... Análisis y formateos
numéricos
strcoll(), wcscoll(), ... Ordenación y
comparación alfabéticas de cadenas
mblen(), mbtowc(), wctomb(), ... Caracteres
multibyte.
catopen(), catgets(), catclose() Mensajes
textuales.
El ejemplo que sigue ilustra el
principio de funcionamiento y como el entorno local afecta el comportamiento de
la función printf().
#include <locale.h> // compilar como programa C #include
<stdio.h>
float fl = 1.2345F;
char* loc;
int main() { // ================ loc = setlocale(LC_ALL, NULL); // modo consulta
printf("locale actual: %s\n", loc);
printf("Valor de fl: %f\n", fl);
loc = setlocale(LC_ALL, ""); // localismo nativo
printf("locale actual:\n%s\n", loc);
printf("Valor de fl: %f\n", fl);
loc = setlocale(LC_ALL, "german"); // localismo específico
(alemán)
printf("locale actual:\n%s\n", loc);
printf("Valor de fl: %f\n", fl);
return 0;
}
Salida:
locale actual: C Valor de fl: 1.234500
locale
actual:
LC_MONETARY=Spanish_Spain.850
LC_TIME=Spanish_Spain.850
LC_NUMERIC=Spanish_Spain.850 LC_COLLATE=Spanish_Spain.850
LC_CTYPE=Spanish_Spain.850
Valor de fl: 1,234500
locale actual:
LC_MONETARY=German_Germany.850
LC_TIME=German_Germany.850
LC_NUMERIC=German_Germany.850 LC_COLLATE=German_Germany.850
LC_CTYPE=German_Germany.850
Valor de fl: 1,234500
Localismos en C++
Como veremos inmediatamente, el
esquema C de tratamiento de localismos se mantiene en C++ por compatibilidad
(las definiciones correspondientes al fichero clásico <locale.h> han sido
trasladadas a <clocale>), pero este lenguaje ofrece un tratamiento
particular y específico del problema de la internacionalización, mucho más
potente y versátil que su contrapartida C, pero también mucho más complejo y
sofisticado.
Los localismos C++ ofrecen servicios
similares a los de C, aunque los mecanismos involucrados difieren. Por ejemplo,
los localismos C son recursos globales, y hemos señalado que solo puede existir
un localismo para toda la aplicación; en consecuencia, es difícil conseguir que
pueda atender simultáneamente a diversos localismos. En cambio, como el
localismo C++ está definido en una clase, pueden instanciarse diversos objetos
que pueden coexistir y cada uno puede servir a una convención cultural
específica.
No hay comentarios:
Publicar un comentario