A linguagem C oferece mecanismos distintos para a manipulação de entrada e saída de dados, que podem ser categorizados em operações de E/S padrão (formatada) e E/S de caracteres (não formatada). A escolha da abordagem correta depende do tipo de dado a ser processado e do contexto da aplicação, influenciando diretamente a flexibilidade e o desempenho do programa.
Funções de Entrada e Saída Padrão (Formatada)
As funções de E/S padrão são as mais difundidas em C para interagir com o usuário e exibir resultados. Elas operam sobre os fluxos padrão de entrada (geralmente o teclado) e saída (geralmente o console), permitindo a leitura e escrita de dados formatados como texto.
Função printf
A função printf, definida em <stdio.h>, é empregada para enviar dados formatados para o fluxo de saída padrão. Sua assinatura é:
int printf(const char *formato, ...);
Ela requer uma string de controle de formato (formato) e uma lista variável de argumentos correspondentes aos dados a serem impressos. O valor de retorno indica o número de caracteres impressos ou um valor negativo em caso de erro.
A string de formato utiliza especificadores que começam com % para determinar o tipo e a apresentação dos dados. Exemplos comuns incluem %d para inteiros, %f para números de ponto flutuante, %c para caracteres e %s para cadeias de caracteres.
Exemplo de Uso do printf
Considere o seguinte exemplo que demonstra a exibição de diferentes tipos de dados:
#include <stdio.h>
int main() {
int idade = 30;
float altura_metros = 1.75f;
char inicial = 'J';
const char* saudacao = "Olá, Mundo!";
printf("Dados do Usuário:\n");
printf(" Idade: %d anos\n", idade);
printf(" Altura: %.2f metros\n", altura_metros); // Formatação para 2 casas decimais
printf(" Inicial: %c\n", inicial);
printf(" Mensagem: %s\n", saudacao);
return 0;
}
Especificadores de Formato e Modificadores Comuns para printf
A flexibilidade do printf reside em seus especificadores de formato e modificadores:
%c: Exibe um único caractere.%dou%i: Para inteiros decimais com sinal.%u: Para inteiros decimais sem sinal.%o: Para inteiros em formato octal.%xou%X: Para intieros em formato hexadecimal (minúsculo ou maiúsculo, respectivamente).%f: Para números de ponto flutuante em formato decimal.%s: Para cadeias de caracteres (strings).%p: Para exibir o valor de um ponteiro.%%: Para imprimir o próprio caractere de percentual.
Modificadores podem ser usados para refinar a saída:
- Largura mínima: Um número antes do especificador (ex:
%5d) define a largura mínima do campo. - Precisão:
.Napós a largura (ex:%.2f) especifica a precisão para ponto flutuante ou o número máximo de caracteres para strings. - Alinhamento:
-(ex:%-10s) para alinhamento à esquerda. - Sinal:
+para exibir sempre o sinal para números (ex:%+d); um espaço para exibir um espaço se o número for positivo (ex:% d).
Sequências de Escape
As sequências de escape controlam a formatação do texto. Algumas das mais usadas são:
\n: Nova linha.\t: Tabulação horizontal.\b: Retrocesso (backspace).\r: Retorno de carro (move o cursor para o início da linha atual).\\: Imprime uma barra invertida.
#include <stdio.h>
int main() {
printf("Este é um texto em uma linha.\n");
printf("E este é em outra.\n");
printf("Item 1\tValor 1\n");
printf("Item 22\tValor 22\n");
return 0;
}
Função scanf
Para ler dados formatados do fluxo de entrada padrão, utiliza-se a função scanf, também definida em <stdio.h>. Sua sintaxe é:
int scanf(const char *formato, ...);
Assim como printf, ela recebe uma string de formato e uma lista variável de argumentos. Contudo, os argumentos devem ser ponteiros para as variáveis onde os dados lidos serão armazenados. O retorno da função é o número de itens lidos e atribuídos com sucesso, ou EOF se ocorrer um erro ou o fim do arquivo to alcançado.
Exemplo de Uso do scanf
#include <stdio.h>
int main() {
int codigo_produto;
float preco_unitario;
char escolha_opcao;
char nome_cliente[50]; // Tamanho fixo para string
printf("Entre com o código do produto (inteiro): ");
scanf("%d", &codigo_produto);
printf("Informe o preço unitário (float): ");
scanf("%f", &preco_unitario);
printf("Escolha uma opção (A/B/C): ");
// O espaço antes de %c é crucial para consumir qualquer caractere de nova linha pendente
scanf(" %c", &escolha_opcao);
printf("Digite o nome do cliente (sem espaços): ");
scanf("%s", nome_cliente); // Para strings, o array já é um ponteiro
printf("\n--- Dados Coletados ---\n");
printf("Produto: %d\n", codigo_produto);
printf("Preço: %.2f\n", preco_unitario);
printf("Opção: %c\n", escolha_opcao);
printf("Cliente: %s\n", nome_cliente);
return 0;
}
Funções de Entrada e Saída de Caracteres
Quando a necessidade é manipular caracteres individualmente, as funções de E/S de caracteres oferecem uma alternativa mais simples e direta, sem a complexidade da formatação. São ideais para processamento de fluxo de texto caractere por caractere.
Função putchar
A função putchar é utilizada para escrever um único caractere no fluxo de saída padrão. Sua definição é:
int putchar(int c);
Ela recebe um inteiro (que é interpretaod como o código ASCII do caractere) e o imprime. Retorna o caractere escrito ou EOF em caso de falha.
Exemplo de Uso do putchar
Para imprimir uma palavra caractere por caractere:
#include <stdio.h>
#include <string.h> // Para strlen
int main() {
char mensagem[] = "Caminho";
int i = 0;
printf("Exibindo a mensagem:\n");
while (mensagem[i] != '\0') {
putchar(mensagem[i]);
i++;
}
putchar('\n'); // Adiciona uma nova linha no final
return 0;
}
Função getchar
Para ler um único caractere do fluxo de entrada padrão, a função getchar é apropriada. Seu protótipo é:
int getchar(void);
Esta função não aceita argumentos e retorna o caractere lido como um int (ou EOF se o fim do arquivo for atingido ou ocorrer um erro). A leitura de um int é importante para poder distinguir um caractere válido de EOF, que geralmente é um valor negativo.
Exemplo de Uso do getchar
O seguinte programa lê e ecoa caracteres até encontrar uma nova linha ou o fim do fluxo de entrada:
#include <stdio.h>
int main() {
int caracter_lido;
int contador = 0;
printf("Digite algo (finalize com Enter):\n");
while ((caracter_lido = getchar()) != '\n' && caracter_lido != EOF) {
// Podemos processar o caracter_lido aqui, ou simplesmente contá-lo
// putchar(caracter_lido); // Descomente para ecoar o que foi digitado
contador++;
}
printf("Você digitou %d caracteres (excluindo a nova linha).\n", contador);
return 0;
}