[Tarsis Azevedo] Aprendendo C - formatação do printf


Recentemente comecei a aprender C. Sim eu não sei C, não tive na faculdade e sempre senti falta de saber melhor como as coisas funionavam por dentro do computador, já que minha maior experiencia em programação é com python, que é uma linguagem de altissimo nivel.

Com C voce trabalha mais perto da maquina, direto com bytes, alocação de memoria, tem que fazer as estruturas de dados.

E pra aprender eu escolhi estudar pelo livro Learn C The Hard Way do Zed Shaw. É um livro que te instiga a estudar os conceitos por voce mesmo, ensina em cima de exemplos bem praticos e eficientes, te adiciona ao ecossistema da linguagem, apresentando ferramentas e tecnicas que vao te ajudar a pensar em C.

Uma das coisas que ele me instigou a estudar foi todos os possiveis formatos e suas variações para o printf, a função que escreve na saida padrão (o print do python).

#include 

int main() {
    printf("%s\n", "Hello World!");

    return 0;
}

#output

Hello World!

formatando a saida do printf

O printf recebe 2 parametros: uma string com os formatos mapeados e um minimo de valores igual ao mapeado.

#include 

int main() {
    printf("%d %s\n", 1, "Hello again!");

    return 0;
}

#output

1 Hello again!

Esta função é capaz de imprimir diferentes tipos de dados (char, string, int, float, octal, hexa, outros aqui) de acordo com a formatação que voce usar.

#include 

int main() {
    printf("Char: %c %c \n", 'b', 65); // char pode receber um int referente a Tabela ASCII (http://www.asciitable.com/).
    printf("Decimais: %d %ld\n", 1988, 650000L);
    printf("Precedido com espaços em branco: %10d\n", 1988);
    printf("Precedido com zeros: %010d\n", 1988);
    printf("Numeros com base diferente: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
    printf("Floats: %4.2f %+.0e %E \n", 3.14554, 3.3214, 3.1234);
    printf("Truque de tamanho: %*d\n", 5, 10);
    printf("String simples %s\n", "Oi!");

    return 0;
}

#output
Char: b A
Decimais: 1988 650000
Precedido com espaços em branco:       1988
Precedido com zeros: 0000001988
Numeros com base diferente: 100 64 144 0x64 0144
Floats: 3.15 +3e+00 3.123400E+00
Truque de tamanho:    10
String simples Oi!

Tabela de Formatos

Os formatos seguem o seguinte prototipo: %[flags][tamanho][.precisao][quantidade]formato

Flags, largura, .precisão, tamanho são opcionais.

Formatos:

Formato Saida Exemplo
c char a
d ou i signed int 1
e Notação Cientifica usando o caracter e 3.9265e+2
E Notação Cientifica usando o caracter E 3.9265E+2
f float 3.4
g usa o menor numero possivel de f e e 3.54
G usa o menor numero possivel de f e E 3.54
o unsigned octal 610
s string Hello World
u unsigned int 2345
x unsigned hexa 7fa
X unsigned hexa com letras maiusculas 7FA
p ponteiro de endereço B800:0000
n Nada impresso. O argumento deve ser um ponteiro para um int assinado, onde o número de caracteres escritos até então é armazenado.
% % seguido de outro % irá printar % na saida %

Flags


Flag Descrição
- Alinhado a esquerda dentro do tamanho definido. Alinhamento a direita é o padrão (veja a tabela de formatação de tamanho).
+ Força a o resultado ser mostrado com um simbolo de + ou -. Por padrão, somente numeros negativos são mostrados com -.
# Usado com o, x e X indica que o valor será precedido de 0, 0x ou 0X respectivamente, para valores diferentes de 0.
Usado com e, E e f, força o output para mostrar um ponto decimal mesmo sem numeros depois dele. Por padrão, se nenhum numero estiver depois do ponto decimal ele nao é mostrado.
Usado com g e G o resultado é mostrado com zeros a direita.
0 Numero 0 é printado ao invés de espaços em branco quando o tamanho é especificado. (veja a tabela de formatação de tamanho).

Modificadores de Tamanho


Tamanho Descrição
(Numero) Número minimo de caracteres a serem printados. Se o valor a ser printado for menor que o numero, será adicionado espaços em branco para atigir o numero limite. O valor nao é trucado caso seja maior que o limite.
* O tamanho nao é especificado na formatação da string, mas é passado como argumento precedendo o argumento a ser formatado

Modificadores de Precisão


.precisão Descrição
.numero Para formatos inteiros (i, d, u, o, x, X): precisão especifica o numero minimo de digitos a serem mostrados. Se a quantidade de digitos for menor que o limite, entao serão acrescentados zeros ao final. O valor nao é truncado se a quantidade de digitos for maior que o limite. Precisão 0 significa que o nenhum valor é printado se o numero for 0.

Para formatos e, E, f: é o numero de digitos que serão mostrados depois do ponto decimal.

Para formatos g e G: é o numero maximo de digitos significantes a serem mostrados.

Para s: é o numero maximo de caracteres a serem mostrados. Por padrão, todos os caracteres serão mostrados até o caracter nulo que finaliza uma string (por exemplo \n)

Para c: não tem efeito.

Quando nenhuma precisão é especificada, o padrão é 1. Se o periodo é especificado sem um valor explicito para precisão, 0 é assumido.

.* A precisão nao é especificada na formatação da string, mas é passado como argumento precedendo o argumento a ser formatado.

Modificadores de Quantidade


quantidade Descrição
h O argumento é interpretado como um short int ou unsigned short int (só se aplica aos formatadores de inteiro: i, d, o, u, x, X).
l O argumento é interpretado como um long int ou unsigned long int (só se aplica aos formatadores de inteiro: i, d, o, u, x, X) e como um caractere de largura ou cadeia de caracteres de largura para formatadores c e s.
L O argumento é interpretado como um long double (somente para formatadores de float: e, E, f, g e G).

O printf é muito poderoso, e espero ter ajudado a conhece-lo melhor.

Obrigado, até a proxima!