paulo1205
(usa Ubuntu)
Enviado em 20/11/2017 - 11:13h
Locales são um mecanismo para trazer
para dentro do seu programa algumas informações relacionadas a aspectos linguístico-culturais que podem afetar o modo como os usuários vão interagir com o programa.
Note esse limite, que eu destaquei em itálico. A linguagem C e sua biblioteca são especificados para um computador genérico, abstrato até. Tirando um conjunto mínimo de operações que devem estar disponíveis para que as computações escritas em C possam ser executadas, o padrão quase não se ocupa de definir a forma que esse computador deve ter. Em nenhum lugar do padrão você vai encontrar prescrições sobre dispositivos tais como teclado, mouse, tela de texto ou de gráficos, terminais, cores, sons, impressoras ou coisa parecida — no máximo, essas coisas mais físicas podem aparecer como exemplos de possíveis implementações ou casos de uso.
Em particular, o padrão do C não diz como nem quais caracteres o computador que executa um programa em C tem de exibir. Dados do tipo
char (ou
wchar_t, dado que você está aparentemente trabalhando com Unicode), do ponto de vista do programa em C, não têm necessariamente de estar ligados a uma representação física: para o C, o que interessa é seu valor lógico. Qualquer correspondência entre o lógico e o físico, inerente ao sistema de computação em que o programa está executando ou com o qual ele está interagindo, é algo fora do escopo da linguagem C e da biblioteca padrão que a acompanha. Se alguém quiser que essa correspondência seja feita de modo válido, é tarefa sua garantir que o sistema esteja devidamente preparado
antes de começar a executar ou interagir com o programa em C.
Você não deu detalhes do seu sistema, de modo que fica difícil apontar com precisão quais são exatamente as causas da sua dificuldade. No entanto, eis alguns erros comuns que talvez possam afetar o seu programa:
• O terminal que você está usando não suporta a exibição do caráter que você deseja exibir. Isso é um
show stopper, a não ser que você possa mudar o terminal ou suas configurações, de modo a habilitar tal exibição. Não há o que fazer logicamente, dentro do programa, para compensar uma inabilidade física do ambiente de execução. O console do MS-DOS (não o do Windows!), por exemplo, só suporta 256 caracteres diferentes, logo não tem como suportar plenamente chinês ou japonês (Kanji). Os emuladores de terminal de versões recentes do mundo Unix e do Windows podem suportar mais símbolos, mas precisam estar configurados adequadamente, tanto com uma codificação que permita um conjunto maior de caracteres, quanto com uma (ou mais de uma, a depender do caso) fonte tipográfica que possua os símbolos desejados (nem toda fonte suporta todos os símbolos definidos pelo Unicode).
• O terminal suporta os caracteres que você quer, mas o programa está se comunicando com ele por meio de uma codificação ou protocolo indevidos. Se, por exemplo, seu programa espera que o terminal trabalhe com símbolos do Unicode e codificação UTF-8, mas o terminal está programado para algo diferente, como ISO-8859-1, ISO-2022 ou CP437 (“CP” é a abreviação de
code page, que é a designação que a Microsoft usa para designar a correspondência entre códigos numéricos e os elementos de um conjunto de caracteres), provavelmente seus caracteres não serão exibidos corretamente. A codificação UTF-8, para uso de todos os caracteres possibilitados pelo Unicode, vem se popularizando graças à Internet, e tem sido adotada por praticamente toda a comunidade Linux. No Windows e em alguns sabores de Unix, além de plataformas populares de desenvolvimento, como Java, essa adoção ainda não aconteceu na mesma medida nem de modo uniforme. Mesmo assim, é possível executar o emulador de console do Windows com codificação CP65001, que é equivalente a UTF-8 (mas como não uso Windows, não sei quão bem isso funciona).
• O código fonte do programa usou um conjunto de caracteres para embutir caracteres incompatíveis com aquele do momento de execução do programa. Na verdade, este é apenas um caso particular do problema anterior. O uso de editores de texto que executam em interface gráfica geralmente facilitam o uso de caracteres estendidos, tais como letras acentuadas, símbolos estrangeiros, caracteres decorativos e outros caracteres especiais, induzindo o programador a inseri-los diretamente no seu código. Não raramente, tais editores podem ser configurados de modo independente de outras partes do sistema quanto a parâmetros ligados ao conjunto de caracteres e da codificação usada para representá-los. Se caracteres estendidos forem parte de uma
string de texto, o compilador geralmente não faz muito esforço para reinterpretá-los, embutindo-os no código executável do mesmo modo como dispostos no código fonte. Aí, quando aparecem coisas esquisitas na saída, o programador tenta voltar ao código fonte, e encontra o texto que ele gostaria que tivesse sido exibido, e demora a perceber que a causa da discrepância está na diferença de configuração de dois ambientes distintos (e.g. editor e terminal), embora estejam rodando, às vezes, ao mesmo tempo e na mesma máquina, e até de modo coordenado (e.g. o editor é parte de um ambiente de desenvolvimento, e a compilação e a execução do programa acontecem através de um comando chamado por dentro do próprio editor).
• A locale foi selecionada com erro ou o sistema não suporta a locale solicitada. Dois problemas distintos: num, o programador comete um erro ao selecionar a locale; no outro, o programador solicita uma locale que seria válida, mas que o sistema não suporta por alguma razão (e.g. as bibliotecas ou arquivos daquela locale em particular não estão instalados). Em ambos os casos, tal erro só pode ser detectado no momento da execução, pois a função
setlocale() é capaz de indicar quando não conseguiu executar corretamente (isso difere dos erros anteriores, porque a discrepância entre o lógico e o físico está além do escopo visível pelo programa em si). Dependendo do caso, pode ser mais interessante para o programa interromper prematuramente a execução do que executar com risco de produzir resultados incompreensíveis pelo usuário.
• Pouca compreensão dos limites do uso de locales. Incluir
setlocale() no começo do programa não é uma panaceia. Já mencionei acima que questões de configuração de ambiente estão fora de escopo das locales do C, mas há mais aspectos que também não são contemplados, mesmo do ponto de vista que se poderia chamar de “lógico”, e também aspectos que não são inteiramente tratados em nível de biblioteca. Por exemplo, a codificação de caracteres afeta o comportamento de algumas funções, mas não pode ser diretamente controlado pelo programa, a não ser por meio da seleção de outra locale. Aspectos semânticos, linguísticos, gramaticais (sintaxe, número, gênero etc.), culturais e situacionais estão completamente fora de escopo, assim como operações tais como traduções e transliterações. Algumas dessas funções são contempladas por outras bibliotecas voltadas para internacionalização (um problema do qual localização (locale) é apenas um aspecto), mas não existe nenhum padrão que governe escopo, forma ou uso de tais bibliotecas.