Entrada e saída básica
Esta aula aborda as funções básicas de entrada e saída em C, incluindo printf e seus especificadores de formato, scanf com cuidados necessários, putchar/getchar para caracteres, e o conceito de buffer. O aluno aprenderá a usar essas funções corretamente e evitar armadilhas comuns.
Nesta aula, vamos explorar as funções fundamentais de entrada e saída (E/S) em C, que permitem a comunicação entre o programa e o usuário ou outros dispositivos. Dominar printf e scanf é essencial para qualquer programador C, pois são as ferramentas mais comuns para exibir dados e ler entradas. Além disso, veremos funções mais simples como putchar e getchar, e entenderemos o papel do buffer no comportamento dessas funções.
Ao final, você será capaz de formatar saídas, ler entradas com segurança e compreender como os dados fluem entre o programa e o terminal.
printf e especificadores
A função printf é usada para exibir dados formatados na saída padrão (geralmente o terminal). Ela pertence à biblioteca padrão <stdio.h>. Sua sintaxe básica é: printf("string de formato", argumentos);. A string de formato contém texto literal e especificadores de formato (como %d para inteiros) que são substituídos pelos valores dos argumentos.
Os especificadores mais comuns incluem: %d (int), %f (float/double), %c (char), %s (string), %p (ponteiro), %x (hexadecimal). Você pode modificar a formatação com flags, largura e precisão, por exemplo: %5d (largura mínima 5), %.2f (duas casas decimais).
#include <stdio.h>
int main() {
int idade = 25;
float altura = 1.75;
char inicial = 'A';
char nome[] = "Ana";
printf("Idade: %d\n", idade);
printf("Altura: %.2f\n", altura);
printf("Inicial: %c\n", inicial);
printf("Nome: %s\n", nome);
printf("Idade: %5d\n", idade); // largura 5
return 0;
}scanf e cuidados
A função scanf lê dados formatados da entrada padrão (teclado). Sua sintaxe é scanf("string de formato", &variaveis);. É crucial usar o operador & antes das variáveis (exceto para strings, que já são ponteiros). Os especificadores são similares aos do printf, mas com algumas diferenças: %f lê float, %lf lê double.
Principais cuidados: (1) Verifique o retorno de scanf (número de itens lidos) para detectar erros. (2) Ao ler strings, %s não lê espaços e pode causar estouro de buffer; prefira fgets para strings. (3) O caractere de nova linha (\n deixado no buffer) pode interferir em leituras subsequentes; use um espaço antes de %c para consumir whitespace.
#include <stdio.h>
int main() {
int numero;
float decimal;
char letra;
char palavra[50];
printf("Digite um inteiro: ");
scanf("%d", &numero);
printf("Digite um float: ");
scanf("%f", &decimal);
printf("Digite um caractere: ");
scanf(" %c", &letra); // espaço antes de %c consome o \n
printf("Digite uma palavra: ");
scanf("%s", palavra); // sem & para string
printf("Você digitou: %d, %.2f, %c, %s\n", numero, decimal, letra, palavra);
return 0;
}putchar/getchar
putchar exibe um único caractere na saída padrão, enquanto getchar lê um caractere da entrada padrão. São funções mais simples que printf/scanf e úteis para processamento caractere a caractere. Ambas retornam um int (EOF em caso de erro ou fim de arquivo).
#include <stdio.h>
int main() {
char c;
printf("Digite um caractere: ");
c = getchar();
printf("Você digitou: ");
putchar(c);
putchar('\n');
return 0;
}Quando usamos getchar após scanf, o caractere de nova linha pode ser capturado. Por isso, muitas vezes é necessário limpar o buffer.
Buffer
O buffer é uma área de memória usada para armazenar temporariamente dados de E/S. Em C, a entrada padrão é geralmente buffered, ou seja, os caracteres são armazenados até que uma nova linha seja lida (buffer de linha). Isso afeta funções como getchar e scanf: elas só processam a entrada após o usuário pressionar Enter.
Por exemplo, se você usa scanf("%d") e depois getchar(), o getchar pode ler o \n deixado no buffer. Para evitar isso, você pode consumir o \n com um getchar extra ou usar scanf(" %c") (espaço antes de %c). Outra técnica é usar while(getchar() != '\n'); para limpar o buffer até a nova linha.
#include <stdio.h>
int main() {
int num;
char ch;
printf("Digite um número: ");
scanf("%d", &num);
// Limpa o buffer até a nova linha
while(getchar() != '\n');
printf("Digite um caractere: ");
ch = getchar();
printf("Número: %d, Caractere: %c\n", num, ch);
return 0;
}Boas práticas
Sempre verifique o retorno de scanf e getchar para tratar entradas inválidas. Prefira fgets para ler strings e depois converta com sscanf para maior segurança. Evite usar gets (obsoleto). Lembre-se de incluir <stdio.h> e usar \n para quebras de linha.
Exercícios
- Escreva um programa que leia um número inteiro e exiba seu quadrado usando printf.
- Leia dois números float e exiba a soma com duas casas decimais.
- Use getchar para ler uma string de até 10 caracteres (sem scanf) e exiba com putchar.
- Escreva um programa que leia um caractere e informe seu código ASCII usando %d.
- Demonstre o problema do buffer lendo um inteiro e depois um caractere sem limpar o buffer, e depois corrija.
#include <stdio.h>
int main() {
int num;
printf("Digite um inteiro: ");
scanf("%d", &num);
printf("Quadrado: %d\n", num * num);
return 0;
}#include <stdio.h>
int main() {
float a, b;
printf("Digite dois floats: ");
scanf("%f %f", &a, &b);
printf("Soma: %.2f\n", a + b);
return 0;
}#include <stdio.h>
int main() {
char str[11];
int i = 0;
char c;
printf("Digite até 10 caracteres: ");
while ((c = getchar()) != '\n' && i < 10) {
str[i++] = c;
}
str[i] = '\0';
printf("Você digitou: ");
for (int j = 0; str[j] != '\0'; j++) {
putchar(str[j]);
}
putchar('\n');
return 0;
}#include <stdio.h>
int main() {
char ch;
printf("Digite um caractere: ");
scanf(" %c", &ch);
printf("O caractere '%c' tem código ASCII %d\n", ch, ch);
return 0;
}// Versão com problema:
#include <stdio.h>
int main() {
int num;
char ch;
printf("Digite um número: ");
scanf("%d", &num);
printf("Digite um caractere: ");
scanf("%c", &ch); // lê o \n
printf("Número: %d, Caractere: %d\n", num, ch);
return 0;
}
// Correção:
#include <stdio.h>
int main() {
int num;
char ch;
printf("Digite um número: ");
scanf("%d", &num);
while(getchar() != '\n'); // limpa buffer
printf("Digite um caractere: ");
scanf("%c", &ch);
printf("Número: %d, Caractere: %c\n", num, ch);
return 0;
}