Curso de C

Gabarito de Lista de Exercícios

Aula 8: Entradas e Saídas Personalizadas

Clique aqui para acessar a Lista 8

 
Exercício 1: Página c930.html
Enunciado:
Escreva um programa que leia nomes pelo teclado e os imprima na tela. Use as funções puts e gets para a leitura e impressão na tela.

Solução:
#include <stdio.h>
void main()
{
char nome[30];
printf("\n\nEscreva um Nome: ");
gets(nome);
puts("\nO nome escrito foi:");
puts(nome);
}
 

Exercício 2: Página c940.html
Enunciado:
Escreva um programa que leia (via teclado) e apresente na tela uma matriz 3X3 de inteiros. Utilize os novos códigos de formato aprendidos para que a matriz se apresente corretamente identada. Altere os tipos de dados da matriz (int, float, double) e verifique a formatação correta para a identação. Verifique também a leitura e impressão de números hexadecimais.

Solução 1: Números inteiros
/* Versao 1.0: Inteiros
   Leitura e Impressao de Hexadecimais
   Identacao a esquereda.              */
#include <stdio.h>
void main()
{
int mat[3][3];
int i,j;
/* Leitura da Matriz: */
printf("\n\nEntre com os valores para a matriz:");
for (i=0; i<3; i++)
  {
  printf("\nLinha %d: ",i+1);
  for (j=0; j<3; j++)
    scanf("%X", &mat[i][j]);
  }
/* Impressao: */
printf("\n");
for (i=0; i<3; i++)
  {
  printf("\n|");
  for (j=0; j<3; j++)
    printf("%-6X|", mat[i][j]);
  }
}
 

Solução 2: Para floats
/* -------------------
   Versao 1.1: Floats
   Leitura e Impressao
   Identacao a esquereda.  */
#include <stdio.h>
void main()
{
float mat[3][3];
int i,j;
/* Leitura da Matriz: */
printf("\n\nEntre com os valores para a matriz:");
for (i=0; i<3; i++)
  {
  printf("\nLinha %d: ",i+1);
  for (j=0; j<3; j++)
    scanf("%f", &mat[i][j]);
  }
/* Impressao: */
printf("\n");
for (i=0; i<3; i++)
  {
  printf("\n|");
  for (j=0; j<3; j++)
    printf("%10.2e|", mat[i][j]);
  }
}

Comentários:
Preste atenção na versão para os float. Verifique como o programa reage para números de ordem de grandeza diferentes (i.e. 124345123.1 e 0.12433; 12.3 e 0.001).

Exercício 3: Página c980.html
Enunciado:
Escreva um programa que leia uma lista de nomes e idades de um arquivo texto. Prepare um arquivo para ser lido com nomes e idades (use um flag para encerrar). Apresente os dados lidos em forma de tabela na tela. Use as funções de sua preferência (experimente tentar usar mais de uma!).

Solução:
#include <stdio.h>
void main()
{
char nome[30], narq[30];
FILE *arq;
int idade;
printf("\nArquivo fonte: ");
gets(narq);
/* Tenta abrir o arquivo: */
if ((arq = fopen(narq, "r")) == NULL)
  {
  printf("\n Erro: Nao e possivel abrir %s!!", narq);
  exit(1);
  }
printf("\nConteudo de %s:\n", narq);
while (!feof(arq))
  {
  fgets(nome, 29, arq);
  fscanf(arq,"%d\n",&idade);
  printf("Nome: %s   | Idade: %d\n", nome, idade);
  }
fclose(arq);
}

Comentários:
O programa lê o nome e a idade e só então testa o final de arquivo. Ocorre então que, caso exista um nome sem idade no final do arquivo, ocorrerá um erro na leitura da idade. O arquivo com o qual o programa foi testado é do tipo:
Nome1 sobrenome1
idade1
nome2 sobrenome2
idade 2
...
nomeN sobrenomeN
idadeN
 

Exercícios de Fixação:

Exercício 1:
Escreva um programa que leia um arquivo do tipo base de dados em .txt, retire e apresente informações importantes na tela. Você pode criar o arquivo no EDIT do DOS, ou no NOTEPAD do Windows, ou no PICO, no UNIX. O arquivo pode ser do tipo:

Nome:     Joao da Silva             Telefone: +55 00 000-0000
Endereco: Rua do Joao, 168
$
Nome:     Maria da Silva            Telefone: +55 99 999-9999
Endereco: Rua da Vila, 093
$
...
O símbolo $ (dólar) entre os dados é só para informar que acabou uma sequência de dados, e pode ser usado para restabelecer o sincronismo, caso o programa se perca em algum ponto. Você pode usar um flag para encerrar, mas e melhor que use feof() (é mais elegante...).

Solução:
#include <stdio.h>
#define NOME_TAM 26
#define ENDER_TAM 30
#define TELE_TAM 20

void main()
{
FILE *arq;
char nome[NOME_TAM+1], ender[ENDER_TAM+1], tele[TELE_TAM+1], arq_nome[30];
char c;

printf("\n\nArquivo de entrada: ");
gets(arq_nome);
if ((arq = fopen(arq_nome, "r")) == NULL)
  {
  printf("\nErro ao abrir o arquivo %s!",arq_nome);
  exit(1);
  }

printf("\n\nImprimindo dados do arquivo: %s\n", arq_nome);
while (!feof(arq))  /* Enquanto nao encontra o fim do arquivo */
  {
  c =0;
  /* Leitura sincronizada.. */
  fscanf(arq, "%s", nome);     /* Salta a palavra: 'Nome:' */
  fgets(nome, NOME_TAM, arq);
  fscanf(arq, "%s", tele);     /* Salta a palavra: 'Telefone:' */
  fgets(tele, TELE_TAM, arq);
  fscanf(arq, "\n%s", ender);  /* Salta a palavra: 'Endereco:' */
  fgets(ender, ENDER_TAM, arq);
  printf("\nNome: %s\nEndereco: %sTelefone: %s", nome, ender, tele);

  /* Caso alguma parte se perca, e o ponteiro no arquivo fique parado
     em alguma parte do registro, esta rotina fara a sincronizacao. */
  while(c != '$')
    {
    c = getc(arq);
    if (feof(arq)) break;
    }
  }
fclose(arq);
}

Comentários:
O programa lê sempre primeiro o título do registro a ser lido primeiro, com o único intuito de posicionar o ponteiro
de posição do arquivo na posição correta para a leitura do dado interessante.
No final da leitura de um registro, ele sempre procura o caracter de sincronização '$'. Caso o ponteiro se perca no meio do arquivo, este procedimento é utilizado para sincronização, com o preço de se perder um registro.
O maior desafio neste programa é pegar a informação correta na hora correta. Para isto é fundamental manter o cursor de leitura do arquivo (o ponteiro que aponta para a posição a ser lida no momento) no lugar certo, e ler a quantidade certa de dados.

OBS: Segue a listagem do arquivo usado para o teste:
Nome:     Joao da Silva             Telefone: +55 00 000-0000
Endereco: Rua do Joao, 168
$
Nome:     Maria da Silva            Telefone: +55 99 999-9999
Endereco: Rua da Vila, 093
$
Nome:     Joaquim Oliveira          Telefone: +55 00 000-0000
Endereco: Rua do Ouro, 148
$
Nome:     Rute  da Silva            Telefone: +55 99 999-9999
Endereco: Rua da Comadre, 1086
$
Nome:     Mauricio Alencar          Telefone: +55 00 000-0000
Endereco: Rua das Promessas, 23
$
Nome:     Ana Ribeiro               Telefone: +55 99 999-9999
Endereco: Rua das Perolas, 120/101
 

Exercício 2:
Escreva um programa que compare 2 arquivos texto. Imprima a primeira linha onde eles se diferem.
#include <stdio.h>
#include <string.h>
#define LINHA_LEN 80
void main()
{
char narq1[30], narq2[30], linha1[LINHA_LEN], linha2[LINHA_LEN];
FILE *arq1, *arq2;
int count, sai;

printf("\nPrimeiro arquivo: ");
gets(narq1);
/* Tenta abrir o arquivo: */
if ((arq1 = fopen(narq1, "r")) == NULL)
  {
  printf("\n Erro: Nao e possivel abrir %s!!", narq1);
  exit(1);
  }
printf("\nSegundo arquivo: ");
gets(narq2);
/* Tenta abrir o arquivo: */
if ((arq2 = fopen(narq2, "r")) == NULL)  /*20*/
  {
  printf("\n Erro: Nao e possivel abrir %s!!", narq2);
  exit(1);
  }
printf("\nComparando o conteudo de %s e %s:\n", narq1, narq2);
count = 0;
sai = 0;
while (!sai)
  {
  if (feof(arq1) || feof(arq2))
    break;
  count++;
  fgets(linha1, LINHA_LEN-1, arq1);
  fgets(linha2, LINHA_LEN-1, arq2);
  if (strcmp(linha1, linha2) == 0)
    printf("Linha %d ok!\n", count);
    else
      {
      printf("Linhas diferentes!! Linha %d:\n%s\n%s\n", count, linha1, linha2);
      sai = 1;
      }
  }
fclose(arq1);
fclose(arq2);
}

Comentários:
Uma utilização da função de biblioteca strcmp() é apresentada. A função retorna um inteiro que pode ser maior ou menor que zero caso as strings sejam diferentes. Por isto o teste compara se o retorno é igual a zero. Uma coisa importante é não se esquecer de fechar os arquivos lidos no final do programa, ou melhor, assim que você terminar o que tem para fazer neles...

  Sumário

Dúvidas? Dê uma olhadinha em nosso FAQ

Perguntas para a lista do Curso de C
Curso de C do CPDEE/UFMG - 1996-1998