A codificação UTF-8 é multibyte, ou seja, cada caractere pode ser composto por um ou mais bytes.
- A letra
a é composta por um byte
- A letra
á é composta por dois bytes
- O símbolo
♥ é composto por três bytes
Confira:
$ printf 'a' | od -t x1
0000000 61
0000001
$ printf 'á' | od -t x1
0000000 c3 a1
0000002
$ printf '♥' | od -t x1
0000000 e2 99 a5
0000003
$
Quando você usa o printf para alinhar colunas, definindo uma largura fixa, as coisas não funcionam como se espera, pois o printf %<número>s conta bytes e não caracteres:
$ printf '|%5s|\n' a m z á ú ♥ ★ # Comportamento esperado
| a|
| m|
| z|
| á|
| ú|
| ♥|
| ★|
$ printf '|%5s|\n' a m z á ú ♥ ★ # Vida real :(
| a|
| m|
| z|
| á|
| ú|
| ♥|
| ★|
Por isso a saída de algumas funções aparece desalinhada quando há letras acentuadas no resultado. Cada letra acentuada do português vale por dois :/ Exemplos de funções problemáticas:
- zzfutebol
- zzpais
- zzquimica
Talvez no futuro o printf seja atualizado para levar em conta a contagem de caracteres e não de bytes, mas como Unicode é um assunto bem complexo, isso pode demorar bastante. Para ter uma ideia do tamanho do problema, veja esta resposta: http://stackoverflow.com/a/9325750/1623438
Bem, este é o problema. Abri este issue para discutirmos possíveis soluções. Lembrando que nosso universo se restringe ao português, então uma solução meia-boca somente para caracteres Latin-1 já é suficiente.
- Como garantir uma saída alinhada das funções que hoje usam
printf?
- Como contar caracteres e não bytes?
A codificação UTF-8 é multibyte, ou seja, cada caractere pode ser composto por um ou mais bytes.
aé composta por um byteáé composta por dois bytes♥é composto por três bytesConfira:
Quando você usa o
printfpara alinhar colunas, definindo uma largura fixa, as coisas não funcionam como se espera, pois oprintf %<número>sconta bytes e não caracteres:Por isso a saída de algumas funções aparece desalinhada quando há letras acentuadas no resultado. Cada letra acentuada do português vale por dois :/ Exemplos de funções problemáticas:
Talvez no futuro o
printfseja atualizado para levar em conta a contagem de caracteres e não de bytes, mas como Unicode é um assunto bem complexo, isso pode demorar bastante. Para ter uma ideia do tamanho do problema, veja esta resposta: http://stackoverflow.com/a/9325750/1623438Bem, este é o problema. Abri este issue para discutirmos possíveis soluções. Lembrando que nosso universo se restringe ao português, então uma solução meia-boca somente para caracteres Latin-1 já é suficiente.
printf?