O tamanho exato de um campo no qual os dados são mostrados é especificado por um tamanho de campo.
Para representar o tamanho do campo desejado devemos inserir um inteiro entre o símbolo %
e o especificador da conversão (por exemplo, %5d
).
Caso o campo seja mais largo que os dados à serem mostrados, eles serão alinhados à direita do campo, e se for mais curto, só aparecerão os primeiros caracteres que ocuparão o espaço. Em ambos os casos, os espaços ocupados são os mesmos. Veja os exemplos abaixo:
printf("d: %d\n", 6);
printf("5d: %5d\n", 6);
printf("10d: %10d\n", 6);
printf("10d: %10d\n", 700);
printf("c: %c\n", 'T');
printf("1c: %1c\n", 'A');
printf("2c: %2c\n", 'B');
printf("3c: %3c\n", 'C');
printf("4c: %4c\n", 'D');
printf("10f: %10f\n", 23.8); // Os espaços continuam, do outro lado.
printf("-10d: %-10d (-10d)\n", 700); // Quando o número é negativo, alinha à esquerda.
PS: Quando usar máscaras para char, use sempre aspas simples somente nos valores.
A precisão com a qual os dados serão exibidos possuí significado diferente para cada tipo.
Quando usada com especificadores de conversão de inteiros, a precisão indica o número mínimo de dígitos à serem impressos. Caso o valor à ser mostrado tenha menos dígitos que a precisão especificada, serão prefixados zeros até totalizar o número de dígitos equivalentes.
Quando usada com especificadores de conversão de strings (s
), a precisão é o número máximo de caracteres que serão mostrados da cadeia.
Para usarmos a precisão, devemos inserir um ponto seguido de um número inteiro que representa a precisão desejada entre o sinal %
e o especificador de conversão.
int x = 450;
float f = 250.12345;
char s[] = "Isso é uma Frase!"; // Pode ser usado char* para evitar escrever arrays.
printf("Precisão em inteiros:\n");
printf("%d\n", x);
printf("%.5d\n", x);
printf("%.12d\n", x);
printf("\nPrecisão em ponto flutuante:\n");
printf("%f\n", f);
printf("%.2f\n", f);
printf("\n\nPrecisão em literais:\n");
printf("%s\n", s);
printf("%.5s\n", s);
printf("%.18s\n", s);
Isso é muito usado para limitar o número de casas decimais, mas pode ver que usamos em outros casos também.
PS: Podemos utilizar char* para strings, só não esqueça do ponteiro (*). Isso é pra evitar vetores.
Podemos também combinar os tamanhos de campos com as precisões, como por exemplo %10.5d
. No caso, o primeiro número é o tamanho e o segundo é a precisão.
Veja o mesmo código acima com alterações:
printf("Precisão em inteiros:\n");
printf("%10.5d\n", x); // 10 espaços e mostra 5 dados (só dentro deles tem zeros).
printf("%15.12d", x); // 15 espaços e mostra 12 dados (só dentro deles tem zeros).
printf("\n\nPrecisão em ponto flutuante:\n");
printf("%8.2f\n", f); // 8 espaços e mostra 2 casas decimais.
printf("\n\nPrecisão em literais:\n");
printf("%10.4s\n", s); // 10 espaços e mostra 4 caracteres da string.
PS: Tanto os tamanhos de campos quando a precisão de dados podem ser usadas em outras linguagens compatíveis com o printf como Java e PHP.
A maioria dos caracteres podem ser mostradas diretamente pela função de print, porém, há alguns caracteres que precisam de formatação especial para serem exibidos, como aspas, símbolos de tabulação e porcentagem, por serem caracteres de controle.
Uma sequência de escape é representada por uma barra invertida seguda por um caractere de escape.
Veja algumas das sequências mais usadas:
Sequência de Escape | Representa |
---|---|
\a | Emitir Campainha |
\b | Backspace |
\f | Avanço de Página |
\n | Coloca o Cursor numa Nova Linha |
\r | Coloca o Cursor no Início da Linha Atual |
\t | Inserir Tabulação Horizontal |
\v | Inserir Tabulação Vertical |
\' | Aspas Simples |
\" | Aspas Duplas |
\\ | Barra Invertida |
\? | Ponto de Interrogação Literal |
\000 | Caractere ASCII em Notação Octal |
\xhh | Caractere ASCII em Notação Hexadecimal |
\xhhhh | Caractere Unicode em Notação Hexadecimal |
\0 | Caractere Delimitador de Final de String |
Veja abaixo um exemplo com algumas delas:
printf("Aspas Simples: \' \n");
printf("Aspas Dupla: \" \n");
printf("Interrogação: \? \n");
printf("Barra Invertida: \\ \n");
printf("Mudar de Linha:\n \n");
printf("Tab: \t Tabulado \n");
printf("Cursor no Início da Linha:\r \n");
printf("Sinal Sonoro:\a \n");
PS: Caso precise exibir o símbolo de porcentagem num printf, use a sequência de dois símbolos, igual se faz num BAT, no caso %%
.
A função scanf
lê valores digitados no teclado, formata-os e os armazena em variáveis na memória. Veja um exemplo de sintaxe:
scanf("Digite algo: %d", &teste);
O que está entre aspas descreve os formatos de entradas, e os outros argumentos são endereços para variáveis nas quais as entradas serão armazenadas.
Ao usarmos o scanf precisamos indicar o endereço da variável de armazenamento do dado lido prefixando-a com o caractere &
.
Veja alguns dos especificadores de conversão, observe que a maioria se assemelham as máscaras:
Especificador | Descrição |
---|---|
%d | Lê um Número Inteiro Decimal com Sinal |
%c | Lê um Caractere Único. NULL não é Adicionado. |
%f, %e ou %E | Lê um Número Decimal (Real ou de Ponto Flutuante) |
%i | Lê um Número Inteiro Decimal, Octal ou Hexadecimal (Diferentes na Entrada e Saída de Dados) |
%o | Lê um Número Inteiro em Formato Octal sem Sinal |
%x ou %X | Lê um Número Inteiro em Formato Hexadecimal sem Sinal. |
%u | Lê um Número Inteiro Decimal sem Sinal |
%h ou %l | Colocado Antes de um Especificador Inteiro para Indicar Valor Short ou Long (por exemplo %ld) |
%L | Colocado Antes de um Especificador de Ponto Flutuante para indicar valor Long Double |
%s | Lê uma Cadeia de Caracteres (String ou Ponto pra char), incluindo o NULL. |
Veja um exemplo de uso:
int inteiro;
float f1, f2;
char letra;
char frase[15];
printf("Digite um Número Inteiro: ");
scanf("%d", &inteiro);
printf("Digite dois Números Reais: ");
scanf("%f%f", &f1, &f2);
fflush(stdin); // Isso limpa o buffer do teclado
printf("Digite uma letra: ");
scanf("\n%c", &letra); // Para evitar erros
fflush(stdin);
printf("Digite uma Frase: ");
scanf("\n"); // Para evitar erros
fgets(frase, 15, stdin);
// Isso é pra remover a quebra de linha:
size_t len;
len = strlen(frase); // Inclua string.h
if(frase[len - 1] == '\n') frase[--len] = 0;
printf("\nNúmero Inteiro: %d\n", inteiro);
printf("Ponto Flutuante: %.2f e %.2f\n", f1, f2);
printf("Letra: %c\n", letra);
printf("Frase: %s\n", frase);
PS: Por padrão, o scanf
só lê a primeira palavra de uma cadeia de caracteres, para ler palavras compostas use o fgets
, como indicado acima.
O procedimento fgets
permite ler uma string de outra variável, no caso, quando passamos o parâmetro stdin
, ele lê da entrada padrão do sistema, igual ao scanf, só que ele permite usar frases com espaços. Esse método, assim como o printf e o scanf, pertence a biblioteca stdio.h.
Em alguns casos, dependendo dos comandos do programa, o scanf pode ser ignorado. Nesse caso, basta apenas colocar uma sequência de escape \n antes da máscara para que ele seja identificado numa nova linha (por exemplo, "\n%d"
). Mas o recomendado é usar o fflush(stdin)
, como mostrado acima, o fflush limpa o buffer do teclado, mas tem casos que temos que usar a quebra de linha mesmo.
Veja outro exemplo:
int dia, mes, ano;
printf("Digite uma data no formato dd/mm/aa: ");
scanf("%d%*c%d%*c%d", &dia, &mes, &ano);
printf("Dia: %d\n", dia);
printf("Mês: %d\n", mes);
printf("Ano: %d\n", ano);
Você pode ver que ali, nós digitamos num formato de data de uma vez só, no caso, dia, mês e ano ficarão em variáveis separadas. As barras da data é ignorada com a máscara de caracteres %*c
, nesse caso, o asterisco significa "ignore".
PS: Quando estamos trabalhando com vetores de char, podemos colocar no scanf a variável sem o &, por exemplo:
char nome[20];
printf("Qual é o seu nome? ");
scanf("%s", nome);
printf("Olá %s, é um prazer te conhecer!\n", nome);
Os operadores aritméticos em C são os mesmos da maioria das linguagens: Multiplicação, divisão, módulo, adição e subtração (nessa ordem de procedência, os parênteses tem prioridade a todos esses operadores), assim como a maioria das funções.
O símbolo de divisão inteira e divisão comum são os mesmos, ele retorna uma divisão inteira se o numerador e o denominador são inteiros.
Veja algumas operações aritméricas sendo executadas:
int x, z, w, k, m, n;
float f;
x = -2 * 3;
z = 4 % 2;
w = 8 / 4;
k = 7 / 2;
f = 7.0 / 2.0;
m = w + x;
n = m - k;
printf("X: %d\n", x);
printf("Z: %d\n", z);
printf("W: %d\n", w);
printf("K: %d\n", k);
printf("F: %.2f\n", f);
printf("M: %d\n", m);
printf("N: %d\n", n);
Veja outro exemplo:
int x, y, z, w;
printf("Digite um número: ");
scanf("%d", &x);
printf("Digite o valor à somar: ");
scanf("%d", &y);
z = x + y;
w = pow(x, 3); // Adicione Biblioteca math.h
printf("\nA soma de %d com %d equivale à %d.\n", x, y, z);
printf("%d elevado ao cubo: %d", x, w);
PS: Para funções aritméricas, como o pow()
, é necessário adicionar a biblioteca math.h
.Veja algumas dessas funções abaixo:
abs()
para pegar o valor absoluto de um número.pow()
para criar uma potencialização entre dois números.sqrt()
para mostrar a raiz quadrada.cbrt()
para mostrar a raiz cúbica.round()
para mostrar o número arredondado para o inteiro mais próximo. Para cima se usa ceil()
e para baixo floor()
.rand()
para gerar um número aleatório, definindo o mínimo e o máximo.Só lembrando que para rand()
, o que se importa é o stdlib.h, e para ele gerar números aleatórios corretamente, precisamos "zerar" ele com srand, dessa forma:
int main() {
srand(time(NULL)); // Importe stdlib.h pro rand/srand e time.h pro time. Deverá estar fora de laços de repetição, caso existam.
printf("%d\n", rand() % 5); // Gera de 0 a 4.
rand() % 5 + 1; // Esse gera de 1 a 5.
12 + (rand() % (14 - (12 - 1))); // Gera de 12 a 14, a sintaxe é: mini + (rand() % (maxi - (mini - 1)))
// Para gerar reais aleatórios de 0.00 a 1.00:
float n = rand() % 100 + 1;
float ale = n / 100;
printf("%.2f\n", ale);
return 0;
}
Os operadores lógicos &&
(and), ||
(or) e !
(not), ou mais raramente o ^
(xor), também são usados no C. Assim como os operadores ternários, por exemplo:
int main() {
int idade;
char* maior;
printf("Digite sua idade: ");
scanf("%d", &idade);
maior = (idade >= 18 && idade < 70) ? "Voto Obrigatório!" : "Voto não-obrigatório!";
printf("%s", maior);
return 0;
}
PS: Podemos também colocar atribuição com algum valor, como por exemplo num += 2
ou num -= 3
, que faça a atribuição e a operação juntos no mesmo comando. Concatenação com atribuição também pode ser colocada com o +=
. O incremento de mais um é colocado apenas usando um ++
antes ou depois da variável desejada (e a posição faz toda a diferença), da mesma forma podemos decrementar menos um com --
. Veja um exemplo abaixo:
int num = 5;
printf("Número: %d\n", num);
num++; // Nesse caso pode usar o pós
printf("Número incrementado: %d\n", num);
num += 2;
printf("Número com mais 2: %d\n", num);
num--;
printf("Número decrementado: %d\n", num);
num -= 3;
printf("Número com menos 3: %d\n", num);
printf("Número com pré-incremento: %d\n", ++num); // Nesse caso usa o pré, que incrementa antes de exibir
printf("Número com pré-decremento: %d\n", --num);