Gabarito de Lista de Exercícios
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
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...