03.06
2020
Já vi muita gente que sabe orientação a objetos, programa bem em C++, usa STL, mas na hora de formatar a saída utiliza printf.
Quem aprendeu C antes de aprender C++ normalmente prefere utilizar printf para formatar a saída. Com printf vai bem, mas e se a saída for num arquivo? E se os padrões de desenvolvimento da equipe exigir a utilização de std::cout? Pra isso que devemos conhecer as funções de formatação do iomanip.
Fazendo Errado
Vamos começar com um exemplo corriqueiro: datas. É comum termos que formatar a data no formato YYYY-MM-DD, o que sigifica que dia 7 de Setembro de 1822 será formatado da seguinte forma: 1822-09-07. E pra isso o código abaixo não funciona:
unsigned year = 1822;
unsigned month = 9;
unsigned mday = 7;
std::cout << year << "-" << month << "-" << mday << std::endl;
A saída será:
1822-9-7
Que não é o formato esperado
Acertando em C e C++
Quem está acostumado com printf vai dar a seguinte solução:
printf("%04d-%02d-%02d\n", year, month, mday);
Mas nem sempre é viável utilizar printf. Então temos que utilizar os formatadores de iostream.
std::cout << setfill('0') <<
setw(4) << year << "-" <<
setw(2) << month << "-" <<
setw(2) << mday << std::endl;
Tanto o printf, como o cout acima entregam o mesmo resultado:
1822-09-07
Modificadores Comuns
Os modificadores mais comuns são os seguintes:
- std::dec, std::oct, std::hex – base numérica para formatação
- std::endl – caracter de fim de linha (normalmente ‘\n’)
- std::ends – caracter de fim de string (normalmente ‘\0)
- std::fixed, std::scientific, std::setprecision – formatação de casas de ponto flutuante
- std::left, std::right – alinhamento à esquerda ou à direita, respectivamente
- std::setw – tamanho da formatação
Vamos a um exemplo, que tal uma tabela de preços?
std::map<std::string, double> listings;
listings["Sabonete"] = 0.75;
listings["Shampoo"] = 7.59;
listings["Condicionador"] = 7.09;
listings["Odorizador"] = 11.12;
std::cout << "*** Tabela de Precos ***" << std::endl;
for (
std::map<std::string, double>::iterator it = listings.begin();
it != listings.end();
it++
)
std::cout <<
std::setfill('.') << std::setw(20) << std::left << it->first <<
" $ " << std::setfill(' ') << std::setw(8) << std::right <<
std::fixed << std::setprecision(2) << it->second << std::endl;
A saída será:
*** Tabela de Precos ***
Condicionador....... $ 7.09
Odorizador.......... $ 11.12
Sabonete............ $ 0.75
Shampoo............. $ 7.59
Poderíamos, inclusive ter um pouco mais de capricho e controlar, em tempo de execução, qual a largura do preenchimento com . entre o nome do produto e o preço. Ou ainda calcular qual o espaço entre $ e os números. Mas aí fica pra cada um tentar fazer algo mais bacana.]
Sempre que aplicável todo post conta com um código de exemplo. O post de hoje pode ser encontrado no github.
Comentários
[…] No Lab C++ não é utilizado using, pelo fato que é necessário ser didático e deixar bem claro os namespaces, portanto não estranhe quando ver o seguinte código: […]