Notas de Aulas (parte 2)



Documentos relacionados
Manipulação de Arquivos

Introdução. Manipulação de arquivos em C. Estrutura de Dados II Prof Jairo Francisco de Souza

Algoritmos e Programação _ Departamento de Informática

INF 1005 Programação I

LP II Estrutura de Dados. Introdução e Linguagem C. Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br

Programação de Computadores I. Linguagem C Arquivos

Capítulo 2: Introdução à Linguagem C

Algoritmos e Estruturas de Dados I 01/2013. Arquivos. Pedro O.S. Vaz de Melo

Persistência de Dados

Algoritmos e Programação Estruturada

INF 1005 Programação I

2. OPERADORES ALGORITMOS, FLUXOGRAMAS E PROGRAMAS FUNÇÕES... 10

Introdução à Programação

V - Lista de Exercícios de SO e Lab. 1-) Escreva um programa em C para criar um arquivo texto, com informações fornecidas pelo usuário não formatadas.

Vetores. Vetores. Figura 1 Exemplo de vetor com 10 elementos

1 Funções básicas de implementação de arquivos

Exercício 1. Tabela 1: Cadastro de usuários, senhas e privilégios (exemplo). Login Senha Privilégio Armamento

INTRODUÇÃO À LINGUAGEM C++

Algoritmos e Estruturas de Dados I. Arquivos. Pedro O.S. Vaz de Melo

Estrutura da linguagem de programação C Prof. Tiago Eugenio de Melo tiago@comunidadesol.org

14. Arquivos. W. Celes e J. L. Rangel. Estruturas de Dados PUC-Rio 13-1

Conceitos básicos da linguagem C

Linguagem de Programação I

Sistemas Operacionais e Introdução à Programação. Programação com linguagem C

Componentes da linguagem C++

PROGRAMAÇÃO ESTRUTURADA. CC 2º Período

Orientação a Objetos

17 - Funções e Procedimentos em C Programação Modular

Armazenamento de Dados. Prof. Antonio Almeida de Barros Junior

20 Caracteres - Tipo char

MC102 Algoritmos e programação de computadores Aula 3: Variáveis

Primeiro Curso de Programação em C 3 a Edição

PROGRAMAÇÃO ESTRUTURADA. CC 2º Período

Curso de C para Engenharias

Lista de Exercícios da 3ª Unidade. ( Ponteiros, Alocação dinâmica, Arquivos, Estruturas de Dados)

Estruturas II UFOP 1/1

Fundamentos de Arquivos. SCC203 Algoritmos e Estruturas de Dados II

ARRAYS. Um array é um OBJETO que referencia (aponta) mais de um objeto ou armazena mais de um dado primitivo.

Estrutura de Dados Básica

Operaçõe õ s c om o Strings Intr oduç ão a o Ponte iros o e Funçõe õ s

INF 1007 Programação II

Edwar Saliba Júnior. Dicas, Comandos e Exemplos Comparativos entre Linguagem Algorítmica e Linguagem C

Manipulação de Arquivos

1 Resumo: Strings e vetores de caracteres. Departamento de Ciência da Computação IME/USP

Comunicação. O Modelo de Fluxo de Dados (Streams)

Arquivos. Estruturas de Dados II Vanessa Braganholo

Resumo da Matéria de Linguagem de Programação. Linguagem C

Linguagens de Programação I

UFSM Introdução ao Dev-C++ Profa. Patrícia Pitthan. Introdução ao Dev-C++

Curso de Programação Computadores

AULA 2: INTRODUÇÃO A LINGUAGEM DE C. Curso: Ciência da Computação Profª.: Luciana Balieiro Cosme

MC-102 Aula 17 Strings e Matrizes

Estruturas de Dados. Profa. Juliana Pinheiro Campos

Curso de Linguagem C

JSP - ORIENTADO A OBJETOS

1) Ao ser executado o código abaixo, em PHP, qual será o resultado impresso em tela?

Algoritmos e Programação

MC-102 Aula 19 Registros

Unidade IV: Ponteiros, Referências e Arrays

UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA INFORMÁTICA APLICADA

Introdução a Programação. Ponteiros e Strings, Alocação Dinâmica

PIP/CA - Programa Interdisciplinar de Pós-Graduação em Computação Aplicada da UNISINOS ALGORITMOS & ESTRUTURAS DE DADOS

SIMULADO Windows 7 Parte V

5 - Vetores e Matrizes Linguagem C CAPÍTULO 5 VETORES E MATRIZES

Trabalho 3: Agenda de Tarefas

INFORMÁTICA APLICADA AULA 02 LINGUAGEM DE PROGRAMAÇÃO C++

Prof. Yandre Maldonado - 1 PONTEIROS. Prof. Yandre Maldonado e Gomes da Costa

Linguagem C. Programação Estruturada. Fundamentos da Linguagem. Prof. Luis Nícolas de Amorim Trigo

UNIVERSIDADE FEDERAL DO AMAPÁ NÚCLEO DE TECNOLOGIA DA INFORMAÇÃO. Manual de Avaliação de Desempenho Cadastro

Iniciação à Informática

Alocação dinâmica de memória

CAPÍTULO 3 - TIPOS DE DADOS E IDENTIFICADORES

Prof. Esp. Adriano Carvalho

CAP. IX - MANIPULAÇÃO DE ARQUIVOS Generalidades sobre Arquivos. 9.2 Abertura e Fechamento de Arquivos. Operações com arquivos:

Linguagem e Técnicas de Programação I Operadores, expressões e funções. Prof. MSc. Hugo Souza Material desenvolvido por: Profa.

OPERADORES E ESTRUTURAS DE CONTROLE

Edwar Saliba Júnior. Dicas, Comandos e Exemplos Comparativos entre Linguagem Algorítmica e Linguagem C / C++

Aluísio Eustáquio da Silva

Status. Barra de Título. Barra de Menu. Barra de. Ferramentas Padrão. Caixa de nomes. Barra de. Ferramentas de Formatação. Indicadores de Coluna

Introdução a Java. Hélder Nunes

5 Apresentando a linguagem C

SISTEMAS OPERACIONAIS ABERTOS Prof. Ricardo Rodrigues Barcelar

Sistema de Arquivos. Ambientes Operacionais. Prof. Simão Sirineo Toscani

Registros. Técnicas de Programação. Rafael Silva Guimarães

DEFINIÇÃO DE MÉTODOS

Programação de Computadores I. Ponteiros

MC-102 Algoritmos e Programação de Computadores

3. No painel da direita, dê um clique com o botão direito do mouse em qualquer espaço livre (área em branco).

Criando um script simples

Aula 4 Pseudocódigo Tipos de Dados, Expressões e Variáveis

Introdução a Computação

Menu Utilitários. Atualização do Banco de Dados Atualização e organização dos arquivos existentes

P r o g r a m a ç ã o d e C o m p u t a d o r e s 1 o S e m P r o f. A n d r é A m a r a n t e L u i z L A B 5 tag %2d while printf PE1:

Capacidade = 512 x 300 x x 2 x 5 = ,72 GB

Transcrição:

Curso: Ciência da Computação (Integral) Disciplina: Linguagem de Programação C Notas de Aulas (parte 2) Professora: Luciana Rita Guedes março/2014

Linguagem de Programação C - notas de aula - parte 2 Página: i Índice 1. PONTEIROS PARA PONTEIROS:... 1 1.1 PONTEIROS QUE APONTAM PARA PONTEIROS... 1 1.2 PONTEIROS E MATRIZES MULTIDIMENSIONAIS:... 3 1.3 USO DE NOMES DE MATRIZES COMO PONTEIROS... 4 2. MATRIZES DE PONTEIROS:... 6 3. FUNÇÕES QUE RETORNAM PONTEIROS:... 9 4. PONTEIROS PARA O TIPO VOID... 11 5. ESTRUTURAS EM C... 12 5.1 ESTRUTURAS SIMPLES:... 12 5.1.1 Acessando os Membros de Uma Estrutura:... 14 5.2 ESTRUTURAS QUE CONTÊM ESTRUTURAS:... 15 5.3 ESTRUTURAS QUE CONTÊM MATRIZES:... 17 5.4 MATRIZES DE ESTRUTURAS:... 19 5.5 INICIALIZANDO ESTRUTURAS:... 21 6. ESTRUTURAS E PONTEIROS... 23 6.1 PONTEIROS COMO MEMBROS DE ESTRUTURAS:... 23 6.2 PONTEIROS PARA STRINGS COMO MEMBROS DE ESTRUTURAS:... 24 6.3 PONTEIROS PARA STRINGS X MATRIZES DE CHAR EM ESTRUTURAS:... 25 6.4 PONTEIROS PARA ESTRUTURAS:... 27 7. ARQUIVOS EM DISCO... 31 7.1 A ESTRUTURA FILE:... 33 7.2 ABRINDO ARQUIVOS:... 33 7.3 FECHANDO ARQUIVOS:... 34 7.4 GRAVANDO ARQUIVOS, CARACTER A CARACTER:... 35 7.5 LENDO ARQUIVOS, CARACTER A CARACTER:... 36 7.6 ERROS AO ABRIR ARQUIVOS:... 37 7.7 GRAVANDO ARQUIVOS, LINHA A LINHA:... 38 7.8 LENDO ARQUIVOS, LINHA A LINHA:... 39 8. ARQUIVOS BINÁRIOS... 40 8.1 LENDO E GRAVANDO REGISTROS:... 40 8.2 GRAVAÇÃO DIRETA COM FWRITE( ):... 40 8.3 LEITURA DIRETA COM FREAD( ):... 43 8.4 TIPOS DE ACESSO A ARQUIVOS:... 45 8.4.1 ACESSO SEQÜENCIAL... 45 8.4.2 CONTROLANDO O INDICADOR DE POSIÇÃO... 46 8.4.3 ACESSO ALEATÓRIO... 47 9. FUNÇÕES DE GERENCIAMENTO DE ARQUIVOS:... 48 9.1 APAGANDO UM ARQUIVO:... 48 9.2 MUDANDO O NOME DE UM ARQUIVO:... 48 9.3 COPIANDO UM ARQUIVO:... 49 9.4 USANDO ARQUIVOS TEMPORÁRIOS:... 50

Linguagem de Programação C - notas de aula - parte 2 Página: 1 1. PONTEIROS PARA PONTEIROS: Revisando: ponteiros são variáveis que contêm o endereço de outra variável; para declarar um ponteiro usa-se o operador de indireção (*): int *ptr; para fazer com que um ponteiro aponte para uma variável, pode-se usar o operador endereço de (&): ptr=&x; // supondo x uma variável do tipo int pode-se usar o operador de indireção (*) para armazenar um valor na variável para a qual o ponteiro estiver apontando (armazenamento indireto): *ptr=12; // equivale a x = 12 se ptr estiver // apontando para x 1.1 PONTEIROS QUE APONTAM PARA PONTEIROS Um ponteiro é uma variável numérica e é armazenado em algum endereço de memória; portanto, pode-se criar um ponteiro que aponte para outro ponteiro, ou seja, uma variável cujo valor é o endereço de um ponteiro. EXEMPLO (declaração): int x; int int *ptr; int **ptr_para_ptr; int // x é uma variável do tipo // ptr é um ponteiro para x // ptr_para_ptr é um ponteiro // para um ponteiro do tipo

Linguagem de Programação C - notas de aula - parte 2 Página: 2 Para atribuir valores a estas variáveis: x = 12; // x recebe o valor 12 ptr = &x; // ptr aponta para o endereço de x ptr_para_ptr = &ptr; // ptr_para_ptr aponta para o // endereço do ponteiro ptr x ptr ptr_para_ptr 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 12 1000 1006 para declarar um ponteiro que aponta para outro ponteiro usa-se o operador de indireção duplo (**); o operador de indireção duplo (**) também pode ser usado para acessar a variável que é referenciada **ptr_para_ptr = 12; // atribui o valor 12 para a variável // referenciada pelo ponteiro ptr // que no exemplo é a variável x printf( %d,**ptr_para_ptr); // imprime o valor da // variável x a declaração e utilização de um ponteiro-para-ponteiro é chamada de indireção múltipla ; o uso mais comum de ponteiros-para-ponteiros está relacionado à criação de matrizes de ponteiros, como será visto adiante.

Linguagem de Programação C - notas de aula - parte 2 Página: 3 1.2 PONTEIROS E MATRIZES MULTIDIMENSIONAIS: Como já foi visto anteriormente, há uma relação especial entre ponteiros e matrizes: o nome de uma matriz (sem os colchetes) é um ponteiro para o primeiro elemento desta matriz; pode-se usar ponteiros para acessar os demais elementos desta matriz; porém, o estudo anterior limitou-se ao uso de matrizes unidimensionais: como trabalhar com matrizes multidimensionais? Para declarar uma matriz multidimensional usa-se um par de colchetes: int multi[2][4]; // declara uma matriz de 8 ele- // mentos pode-se interpretar a declaração acima como sendo de uma matriz de 2 linhas por 4 colunas. outra forma de visualizar esta matriz é mais compatível com a forma como a linguagem C realmente lida com matrizes, ou seja: MULTI é uma matriz de 2 elementos, sendo que cada um desses 2 elementos é uma matriz de 4 números inteiros (pode-se dizer que MULTI é uma matriz de matrizes );

Linguagem de Programação C - notas de aula - parte 2 Página: 4 multi multi[0] multi[1][3] Uma matriz bidimensional é visualizada como uma matriz de matrizes 1.3 USO DE NOMES DE MATRIZES COMO PONTEIROS Como em matrizes unidimensionais: o nome de uma matriz é um ponteiro para o primeiro elemento desta matriz: multi é um ponteiro para multi[0] multi[0] é um ponteiro para multi[0][0] multi[1] é um ponteiro para multi[1][0] Como regra geral para matrizes com n dimensões, temos: O nome da matriz seguido por n pares de colchetes (cada par contendo um índice apropriado, evidentemente) é avaliado com base nos dados contido nessa matriz (ou seja, é igual aos dados armazenados no elemento especificado da matriz).

Linguagem de Programação C - notas de aula - parte 2 Página: 5 O nome da matriz seguido por um número de pares de colchetes menor que n é avaliado como um ponteiro para um elemento da matriz. Relação entre uma matriz multidlmenslonal e os ponteiros: 01:/* Demonstra o uso de ponteiros e matrizes multidimensionais. * / 02: 03:#include <stdio.h> 04: 05:int multi[2][4]; 06: 07:main() 08:{ 09: printf( \nmulti = %u, multi); 10: printf( \nmulti[0] = %u, multi[0]); 11: printf( \nmulti[0][0] = %u, &multi[0][0]); 12:} Resultados do programa (supondo o endereço inicial da matriz como 1328): multi = 1328 multi[0] = 1328 &multi[0][0] = 1328 Determinando o tamanho dos elementos: 01:/* Mostra o tamanho dos elementos de uma matriz multidimensional */ 02: 03:#include <stdio.h> 04: 05:int multi[2][4]; 06: 07:main() 08:{ 09: printf( \ntamanho de multi = %u, sizeof(multi)); 10: printf( \ntamanho de multi[0] = %u, sizeof(multi[0])); 11: printf( \ntamanho de multi[0][0] = %u, sizeof(multi[0][0])); 12: } Resultados: Tamanho de multi = 16 Tamanho de multi[0] = 8 Tamanho de multi[0][0] = 2

Linguagem de Programação C - notas de aula - parte 2 Página: 6 2. MATRIZES DE PONTEIROS: Na linguagem C pode-se declarar e usar matrizes de ponteiros; O uso mais comum para matrizes de ponteiros está relacionado aos strings; Para declarar uma matriz de ponteiros que apontam para variáveis do tipo char: char *texto[10]; // texto é uma matriz com 10 // ponteiros texto[0]?? texto[1]?? texto[2]?? texto[3]?? texto[4]?? texto[5]?? texto[6]?? texto[7]?? texto[8]?? texto[9]?? cada elemento da matriz texto é um ponteiro individual para o tipo char; Para declarar e inicializar uma matriz de ponteiros que apontam para diversos strings diferentes: char *texto[10]={ um, dois, três }; a declaração acima: aloca espaço para uma matriz chamada texto com 10

Linguagem de Programação C - notas de aula - parte 2 Página: 7 elementos, onde cada elemento é um ponteiro para o tipo char; aloca espaço em alguma outra região da memória para armazenar os três strings de inicialização inicializa o elemento texto[0] para apontar para o primeiro caractere do string um ; inicializa o elemento texto[1] para apontar para o primeiro caractere do string dois ; inicializa o elemento texto[2] para apontar para o primeiro caractere do string três ; 1524 texto[0] 1524 u m \0 texto[1] 2342 2342 texto[2] 5012 d o i s \0 texto[3]? 5012 texto[4]? t r ê s \0 texto[5]? texto[6]? texto[7]? texto[8]? texto[9]? EXEMPLO: inicializando e usando uma matriz do tipo char 01: /* Inicializando uma matriz de ponteiros para o tipo char */ 02: 03: #include <stdio.h> 04: 05: main() 06: { 07: char *mensagem[8] = { Já, dizia, vovó, antes, só, que, mal, acompanhado }; 08: 09: int contagem; 10: 11: for (contagem = 0; contagem < 8; contagem++) 12: printf( %s\n, mensagem[contagem]); 13: }

Linguagem de Programação C - notas de aula - parte 2 Página: 8 EXEMPLO: passando uma matriz de ponteiros para uma função 01: /* Passando uma matriz de ponteiros para uma função */ 02: 03: #include <stdio.h> 04: 05: void imprime_strings(char *p[], int n); 06: 07: main() 08: { 09: char *mensagem[8] = { Já, dizia, vovó, antes, só, que, mal, acompanhado } 10: 11: 12: imprime_strings(mensagem, 8); 13: } 14: 15: void imprime_strings(char *p[], int n) 16: { 17: int contagem; 18: 19: for (contagem = 0; contagem<n; contagem++) 20: printf( %s\n, mensagem[contagem]); 21: }

Linguagem de Programação C - notas de aula - parte 2 Página: 9 3. FUNÇÕES QUE RETORNAM PONTEIROS: A biblioteca-padrão C contém diversas funções que retornam um ponteiro para o programa de origem. Da mesma forma, é possível escrever funções que retornem ponteiros. Para declarar e/ou definir uma função que irá retornar um ponteiro, usa-se o operador de indireção (*). O formato geral é: tipo *nome_função(lista_parâmetros); Estas funções não têm nada de especial pois são usadas exatamente como qualquer outra função, atribuindo seu valor de retorno a uma variável do tipo apropriado; a única diferença é que este valor será um ponteiro. EXEMPLOS: usando funções que retornam ponteiros: O programa a seguir possui duas funções: maior1( ) e maior2( ). O objetivo do programa é obter dois valores inteiros do usuário (a partir do teclado) e indicar qual dos dois é o maior; este resultado é obtido igualmente através das duas funções, porém de forma um pouco diferente: A função maior1( ) recebe duas variáveis do tipo inteiro e retorna um valor do tipo inteiro; A função maior2( ) recebe dois poneiros para variáveis do tipo inteiro e retorna um ponteiro para o tipo inteiro.

Linguagem de Programação C - notas de aula - parte 2 Página: 10 01: /* Funcao que retorna um ponteiro. */ 02: 03: #include <stdio.h> 04: 05: int maiorl(int x, int y); // protótipo da 1a. função 06: int *maior2(int *x, int *y); // protótipo da 2a. função 07: 08: main() 09: { 10: int a, b, resultadol, *resultado2; 11: 12: printf( Digite dois numeros inteiros: ); 13: scanf( %d %d, &a, &b); 14: 15: resultadol = maiorl(a, b); 16: printf( \no maior valor e %d., resultadol); 17: 18: resultado2 = maior2(&a, &b); 19: printf( \no maior valor e %d., *resultado2); 20: } 21: 22: int maiorl(int x, int y) 23: { 24: if (y>x) 25: return y; 26: return x; // retorna um valor numérico inteiro 27: } 28: 29: int *maior2(int *x, int *y) 30: { 31: if (*y > *x) 32: return y; 33: // retorna o endereço de uma variável 34: return x; // do tipo inteiro 35: }

Linguagem de Programação C - notas de aula - parte 2 Página: 11 4. PONTEIROS PARA O TIPO VOID Qual a finalidade da palavra-chave void antes de uma função? Também é possível usar void para criar um ponteiro genérico, ou seja, um ponteiro que pode apontar para qualquer tipo de dados. EXEMPLO 1 void *x; declara o ponteiro genérico x, que aponta para algo; você apenas não especificou ainda para o que ele está apontando. EXEMPLO 2 Digamos que você queira criar uma função que aceite uma variável numérica como argumento e divida o seu valor por 2, retornando a resposta para a própria variável de argumento. Se a variável x contém o valor 4, depois de chamar a função metade (x), ela passaria a conter o valor 2. Considerações: Como você pretende modificar o argumento, ele deve ser passado por referência; Como você quer que a função seja acessível a qualquer dos tipos de dados numéricos possíveis em C, você deve declarála usando como argumento um ponteiro para o tipo void. EXEMPLO 3 void metade(void *x); Agora você já pode chamar essa função usando qualquer tipo de ponteiro como argumento.

Linguagem de Programação C - notas de aula - parte 2 Página: 12 5. ESTRUTURAS EM C OBJETIVO: Usar esquemas especiais de dados para simplificar tarefas de programação. Estes esquemas são chamados de estruturas. As estruturas constituem-se num método de armazenagem desenhado pelo próprio programador. 5.1 ESTRUTURAS SIMPLES: Uma estrutura é uma coleção de uma ou mais variáveis agrupadas sob um único nome; As variáveis de uma estrutura, ao contrário de uma matriz, podem ser de diferentes tipos de dados; Uma estrutura pode conter quaisquer tipos de dados, inclusive matrizes ou mesmo outras estruturas. Definindo e Declarando Estruturas Simples: Para definir uma estrutura simples usa-se a seguinte sintaxe: struct rotulo { membros_da_estrutura; }; A instrução acima define uma estrutura chamada rotulo que pode conter diversos membros, os quais podem ser do mesmo tipo ou podem ser de tipos diferentes;

Linguagem de Programação C - notas de aula - parte 2 Página: 13 Exemplos de Definição de Estruturas: struct hora { int horas; int minutos; int segundos; }; struct data { char dia[2]; char mes[2]; char ano[4]; }; Para declarar estruturas cujo gabarito foi previamente definido usa-se seguinte sintaxe: struct rotulo instancia1, instancia2,...; A instrução acima declara instancias da estrutura chamada rotulo, isto é, variáveis cujo formato é definido pela estrutura denominada rotulo; Outra forma de declarar estruturas é no momento de criação da estrutura (definição) colocando-se os nomes das instâncias logo após à definição: struct rotulo { membros_da_estrutura; } instancia1, instancia2,...; Exemplos de Declaração de Estruturas: // declaração em separado struct hora { int horas; int minutos; }; // pode haver outras // instrucoes aqui struct hora inicio, fim; // declaração junto c/definição struct data { char dia[2]; char mes[2]; char ano[4]; } data_nasc, data_atual; // neste caso a declaracao deve // vir logo apos a definicao

Linguagem de Programação C - notas de aula - parte 2 Página: 14 5.1.1 Acessando os Membros de Uma Estrutura: Os membros individuais de uma estrutura podem ser acessados como qualquer variável, desde que seja usado o operador de membro de estrutura (.), entre o nome da estrutura (instância) e o nome do membro. O operador de membro de estrutura também é chamado de operador ponto: nome_instancia.nome_membro = valor; printf(...,nome_instancia.nome_membro); Exemplos de Uso de Membros de Estruturas: // definição da estrutura HORA struct hora { int horas; int minutos; }; // pode haver outras instrucoes aqui // declaração das instâncias INICIO e FIM struct hora inicio, fim; // uso dos membros da estrutura através da instancia INICIO inicio.horas = 10; inicio.minutos = 35; // uso dos membros da estrutura através da instancia FIM fim.horas = inicio.horas; fim.minutos = 49; Ainda com relação ao uso dos membros de uma estrutura, é possível copiar informações entre estruturas de mesmo formato, como no exemplo abaixo: // os dados contidos nos membros da estrutura INICIO são // passados a cada um dos membros da estrutura FIM fim = inicio;

Linguagem de Programação C - notas de aula - parte 2 Página: 15 5.2 ESTRUTURAS QUE CONTÊM ESTRUTURAS: Uma estrutura pode conter outras estruturas dentro de si formando um agrupamento de variáveis mais complexos e interessantes. Vejamos isto através de um exemplo: Exemplos de Estruturas que Contêm Estruturas: // definição da estrutura COORD que é composta de // duas coordenadas num plano cartesiano (X e Y) struct coord { int x; int y; }; // definição e declaração da estrutura RETANGULO composta // de dois conjuntos de coordenadas X e Y struct retangulo { struct coord superior_esquerdo; struct coord inferior_direito; } caixa; // uso dos membros da estrutura da instancia CAIXA caixa.superior_esquerdo.x = 0; caixa.superior_esquerdo.y = 10; caixa.inferior_direito.x = 100; caixa.inferior_direito.y = 200; // estes dados podem ser interpretados como um conjunto // de duas coordenadas X e Y no plano cartesiano para // formarem uma caixa retangular O resultado da atribuição acima pode ser representado da seguinte forma: CAIXA SUPERIOR_ESQUERDO INFERIOR_DIREITO X Y X Y 0 10 100 200

Linguagem de Programação C - notas de aula - parte 2 Página: 16 Programa Exemplo com Estruturas que Contêm Estruturas: 01: /* Demonstra o uso de estruturas que contem outras estruturas */ 02: 03: /* Recebe informacoes sobre as coordenadas dos cantos de 04: um retangulo e calcula a sua area. Presume que a 05: coordenada y do canto superior esquerdo e maior que a 06: coordenada y do canto inferior direito, que a coordenada x 07: do canto inferior direito e maior que a coordenada x do canto 08: superior esquerdo, e que todas as coordenadas sao positivas. */ 09: 10: #include <stdio.h> 11: 12: int comprimento, largura; 13: long area; 14: 15: struct coord { 16: int x; 17: int y; 18: }; 19: 20: struct retangulo { 21: struct coord sup_esq; 22: struct coord inf_dir; 23: } caixa; 24: 25: main() 26: { 27: /* Recebe as coordenadas */ 28: 29: printf( \ndigite a coordenada x superior esquerda: ); 30: scanf( %d, &caixa.sup_esq.x); 31: 32: printf( \ndigite a coordenada y superior esquerda: ); 33: scanf( %d, &caixa.sup_esq.y); 34: 35: printf( \ndigite a coordenada x inferior direita: ); 36: scanf( %d, &caixa.inf_dir.x); 37: 38: printf( \ndigite a coordenada y inferior direita: ); 39: scanf( %d, &caixa.inf_dir.y); 40: 41: /* Calcula o comprimento e a largura */ 42: largura = caixa.inf_dir.x caixa.sup_esq.x; 43: comprimento = caixa.inf_dir.y caixa.sup_esq.y; 44: 45: /* Calcula e informa a area */ 46: area = largura * comprimento; 47: printf( \na área do retângulo é de %ld unidades., area); 48: }

Linguagem de Programação C - notas de aula - parte 2 Página: 17 5.3 ESTRUTURAS QUE CONTÊM MATRIZES: Pode-se definir uma estrutura cujos membros incluam uma ou mais matrizes. A matriz pode ser de qualquer tipo válido em C. Vejamos isto através de um exemplo: Exemplo de Estruturas que Contêm Matrizes: // definição da estrutura ALUNO contendo duas matrizes struct aluno { char nome[10]; float nota[3]; }; // declaração de uma instância da estrutura ALUNO struct aluno ZEZINHO; A estrutura definida acima poderia ser representada da seguinte forma: zezinho.nome[7] zezinho.nome zezinho.nota zezinho.nota[2] Para acessar os membros da estrutura, usa-se as mesmas instruções de manipulação de matrizes: zezinho.nota[2] = 10; zezinho.nome[1] = J ;

Linguagem de Programação C - notas de aula - parte 2 Página: 18 Exemplo de programa com estrutura que contêm matrizes:. 01: /* Demonstra uma estrutura que contem matrizes como membros */ 02: 03: #include <stdio.h> 04: 05: /* Define e declara uma estrutura para conter os dados, */ 06: /* cujos membros sao uma variavel float e duas matrizes char. */ 07: 08: struct dados { 09: float quantia; 10: char nome[30]; 11: char snome[30]; 12: } reg; 13: 14: main() 15: { 16: /* Recebe os dados do teclado. */ 17: 18: printf( Digite o nome e o sobrenome do doador,\n ); 19: printf( separados por um espaco: ); 20: scanf( %s %s, reg.nome, reg.snome); 21: 22: printf( \ndigite a quantia doada: ); 23: scanf( %f, &reg.quantia); 24: 25: /* Exibe as informacoes. */ 26: /* Nota: %.2f especifica um valor de ponto flutuante */ 27: /* que deve ser impresso com dois algarismos a direita */ 28: /* do ponto decimal. */ 29: 30: /*Exibe os dados na tela */ 31: 32: printf( \no doador %s %s deu $%.2f., reg.nome, reg.snome, reg.quantia); 33: 34: }

Linguagem de Programação C - notas de aula - parte 2 Página: 19 5.4 MATRIZES DE ESTRUTURAS: As matrizes de estruturas são ferramentas de programação poderosas. Significa que, partindo de uma estrutura definida, pode-se ter uma matriz onde cada elemento é uma estrutura deste tipo. Por exemplo, supondo uma estrutura como declarada abaixo: struct dados_pessoa { char nome[10]; char sobrenome[12]; char fone[8]; }; Esta estrutura poderia ser representada da seguinte forma: estrutura dados_pessoa nome sobrenome fone Para definir uma matriz a partir desta estrutura poderia ser usada, por exemplo, a seguinte definição: struct dados_pessoa cliente[5]; cliente[0] cliente[1] cliente[2] cliente[3] cliente[4] nome sobrenome fone nome sobrenome fone nome sobrenome fone nome sobrenome fone nome sobrenome fone

Linguagem de Programação C - notas de aula - parte 2 Página: 20 Exemplo de programa com matrizes de estruturas: 01: * Demonstra o uso de matrizes de estruturas */ 02: 03: #include <stdio.h> 04: #define tam 5 05: 06: main() 07: { 08: struct dados_aluno 09: { 10: char nome[15]; 11: float media; 12: int ano_nasc; 13: } aluno[tam]; 14: 15: int x; 16: 17: /* Recebe os dados do teclado. */ 18: 19: for(x=0;x<tam;x++) 20: { 21: printf("\ndigite o nome do %io. aluno: ",x+1); 22: scanf("%s", aluno[x].nome); 23: printf("digite a média deste aluno: "); 24: scanf("%f", &aluno[x].media); 25: printf("digite o ano de nascimento deste aluno: "); 26: scanf("%i", &aluno[x].ano_nasc); 27: } 28: 29: /*Exibe os dados na tela */ 30: 31: printf("\n\tnomes \tmedias\tidades"); 32: 33: for(x=0;x<tam;x++) 34: { 35: printf("\n\t%s\t%.2f\t%i",aluno[x].nome,aluno[x].media, 2001-aluno[x].ano_nasc); 36: } 37: 38: }

Linguagem de Programação C - notas de aula - parte 2 Página: 21 5.5 INICIALIZANDO ESTRUTURAS: As estruturas podem ser inicializadas ao serem declaradas. O procedimento é semelhante ao adotado para inicializar matrizes: coloca-se um sinal de igualdade após a declaração da estrutura seguido de uma lista de valores separados por vírgula e delimitados por chaves. Por exemplo: struct venda { char cliente[10]; char item[10]; float quantidade; } ultima_venda = { Fulano, Rebimboca,10.5}; No caso de uma estrutura que contenha outras estruturas como membros, os valores de inicilização devem ser listados em ordem. Esses valores serão armazenados nos membros da estrutura no ordem em que os membros estão listados na definição da estrutura. Por exemplo: struct cliente { char empresa[20]; char contato[15]; }; struct venda { struct cliente comprador; char item[10]; float quantidade; } primeira_venda = { { Indústria Acme, Fulano }, Rebimboca, 10.5 };

Linguagem de Programação C - notas de aula - parte 2 Página: 22 No caso de uma matriz de estrutura, os dados de inicilização fornecidos serão aplicados, pela ordem, às estruturas da matriz. Por exemplo: struct cliente { char empresa[20]; char contato[15]; }; struct venda { struct cliente comprador; char item[10]; float quantidade; } diaria[10] = { { /* Dados para diaria[0] */ { Indústria Acme, Fulano }, Rebimboca, 10.5 } { /* Dados para diaria[1] */ { ABC Ltda., Beltrano }, Parafuseta, 5.6 } { /* Dados para diaria[2] */ { Cia. XYZ, Cicrano }, Treco, 17.0 } }; No exemplo acima, apenas os três primeiros elementos da matriz de estrutura diaria receberam informações. Os demais elementos não foram inicializados.

Linguagem de Programação C - notas de aula - parte 2 Página: 23 6. ESTRUTURAS E PONTEIROS Pode-se usar ponteiros como membros de estruturas e também declarar ponteiros que apontem para estruturas. 6.1 Ponteiros Como Membros de Estruturas: Para usar um ponteiro como membro de uma estrutura, para declará-los precedidos do operador de indireção (*), tal como na declaração comum de ponteiros. Por exemplo: struct financiamento { int *valor; float *juros; }fin_automovel; Estas instruções declaram uma estrutura denominada financiamento que possui dois membros que são ponteiros. Além disso, uma estrutura denominada fin_automovel é definida com este gabarito de financiamento. A inicialização dos ponteiros acima declarados pode ser, por exemplo: fin_automovel.valor = &custo_total; fin_automovel.juros = &taxa; Também pode-se usar o operador de indireção para acessar o valor das variáveis apontadas por estes ponteiros: printf( \nvalor: %d, *fin_automovel.valor); tot = *fin_automovel.valor + *fin_automovel.juros;

Linguagem de Programação C - notas de aula - parte 2 Página: 24 6.2 Ponteiros para Strings como Membros de Estruturas: O uso mais comum de ponteiros como membros de estruturas é o de ponteiros para strings, como no exemplo abaixo: struct mensagem { char *msg1; char *msg2; } observacao; Tal como no uso comum de ponteiros para strings, podese inicializá-lo diretamento com um string, como abaixo: observação.msg1= Primeira mensagem de observação ; observação.msg2= Segunda mensagem de observação ; Desta mesma forma, os ponteiros que são membros de estruturas podem ser usados em qualquer lugar em que um ponteiro normal poderia ser usado. Por exemplo: printf( %s %s,observação.msg1, observação.msg2) puts(observação.msg1); puts(observação.msg2);

Linguagem de Programação C - notas de aula - parte 2 Página: 25 6.3 Ponteiros para strings x Matrizes de char em Estruturas: Tanto o uso de ponteiros para strings quanto o uso de matrizes para o tipo char são usados para armazenar um string dentro de uma estrutura. Definição de Ponteiros para Strings x Matrizes do tipo char: struct msg { char p1[20]; char *p2; } obs; Uso de Ponteiros para Strings x Matrizes do tipo char: /* atribuição de valores */ strcpy(obs.p1, Primeira mensagem ); strcpy(obs.p2, Segunda mensagem ); /* impressão dos valores */ puts(obs.p1); puts(obs.p2); Observe que a forma de uso tanto de ponteiros para strings quanto de matrizes para o tipo char é idêntico. Assim, a diferença entre ambos consiste basicamente em: Ao definir uma estrutura que contenha uma matriz do tipo char, todas as instâncias desse tipo de estrutura conterão espaço de armazenagem para o tamanho especificado. Além disso, com o uso de matrizes para o tipo char, o tamanho do string estará limitado ao tamanho

Linguagem de Programação C - notas de aula - parte 2 Página: 26 especificado e não poderá armazenar um número de caracteres maior na estrutura. Exemplo: limitação no uso de matrizes para o tipo char: // definição e declaração struct nome_completo { char prenome[10]; char sobrenome[10]; } cliente; // pode haver outras instruções aqui strcpy(cliente.prenome, Escolástica ); /* string maior que matriz provocará erros */ strcpy(cliente.sobrenome, Silva ); /* string menor que matriz desperdício de memória */ O uso de ponteiros para strings impede que tais problemas venham a ocorrrer. Vantagens do uso de ponteiros para strings no lugar de matrizes do tipo char: Cada instância da estrutura conterá apenas o espaço de armazenagem necessário para o próprio ponteiro; Os strings propriamente ditos serão armazenados em qualquer outra parte da memória (não há necessidade de se saber onde); Não há restrição ao tamanho do string nem haverá espaço ocioso; Cada ponteiro da estrutura pode apontar para um string de qualquer tamanho; Os strings referenciados por estes ponteiros passam a fazer parte da estrutura indiretamente.

Linguagem de Programação C - notas de aula - parte 2 Página: 27 6.4 PONTEIROS PARA ESTRUTURAS: É possível declarar e usar ponteiros que apontem para estruturas exatamente como são usados para qualquer outro tipo de armazenagem de dados. As grandes utilidades deste tipo de ponteiro são: para passar uma estrutura para uma função; para usá-los em listas encadeadas. Exemplo do uso de Ponteiros para Estruturas: /* definição e declaração da estrutura */ struct produto { int codigo; char nome[10]; } prod1; /* declaração de um ponteiro para esta estrutura */ struct produto *p_prod; /* inicialização do ponteiro */ p_prod = &prod1; /* atribuição de valor através da indireção */ (*p_prod).codigo = 100; // prod1.codigo = 100; strcpy((*p_prod).nome,"rebimboca"); /* operador (.) tem prioridade sobre (*) */ /* impressão dos valores através da indireção */ printf("%d\n",(*p_prod).codigo); printf("%s\n",(*p_prod).nome); puts((*p_prod).nome);

Linguagem de Programação C - notas de aula - parte 2 Página: 28 Outra forma de acessar membros da estrutura através de ponteiros é com o uso do operador de acesso a membro (->) como mostrado a seguir: printf("%d\n",p_prod->codigo); puts(p_prod->nome); p_prod->codigo é similar a (*p_prod).codigo struct produto { int codigo; char nome[10]; } prod[100]; /* declaração de um ponteiro para esta estrutura */ struct produto *p_prod; p_prod = &prod[0]; // p_prod = prod; // usando a matriz prod for(i=0;i<100;i++) { printf( Digite o código do %i o produto: ); scanf( %d,&prod[i].codigo) printf( Digite o nome do %i o produto: ); scanf( %s,prod[i].nome) } // usando o ponteiro p_prod for(i=0;i<100;i++) { printf( Digite o código do %i o produto: ); scanf( %d,&p_prod->codigo) printf( Digite o nome do %i o produto: ); scanf( %s,p_prod->nome) p_prod++; } // no final, o ponteiro estará apontando para // o fim da matriz (um endereço após o último)

Linguagem de Programação C - notas de aula - parte 2 Página: 29 PONTEIROS E MATRIZES DE ESTRUTURAS: 01: /* Demonstra a progressao atraves de unia matriz de estruturas */ 02: /* usando a notacao de ponteiros. */ 03: 04: #include <stdio.h> 05: 06: #define MAX 4 07: 08: /* Define uma estrutura, depois declara e inicializa */ 09: /* uma matriz contendo 4 estruturas. */ 10: 11: struct peca { 12: int numero; 13: char nome[10]; 14: } dados[max] = {1, Smith, 15: 2, Jones, 16: 3, Adams, 17: 4, Wilson 18: }; 19: 20: /* Declara um ponteiro p/o tipo peca e uma variavel de contagem */ 21: 22: struct peca *p_peca; 23: int contagem; 24: 25: main() 26: { 27: /* Inicializa o ponteiro para o primeiro elemento da matriz */ 28: 29: p_peca = dados; 30: 31: /* Faz um loop atraves da matriz, incrementando o ponteiro */ 32: /* a cada iteracao. */ 33: 34: for (contagem = 0; contagem < MAX; contagem++) 35: { 36: printf( \nno endereco %d: %d %s,p_peca, p_peca >numero, p_peca >nome); 37: p_peca++; 38: 39: } 40: 41: }

Linguagem de Programação C - notas de aula - parte 2 Página: 30 PONTEIROS E MATRIZES DE ESTRUTURAS: 01: /* Demonstra o uso de estrutura como argumento de uma função */ 02: 03: #include <stdio.h> 04: 05: /* Define e declara uma estrutura para conter os dados */ 06: 07: struct dados { 08: float quantia; 09: char nome[30]; 10: char snome[30]; 11: } reg; 12: 13: /* O protótipo da função: A função não tem valor de retorno e */ 14: /* aceita como único argumento uma estrutura do tipo dados. */ 15: 16: void print_reg(struct dados x); 17: 18: main() 19: { 20: /* Recebe os dados do teclado. */ 21: 22: printf( Digite o nome e o sobrenome do doador,\n ); 23: printf( separados por um espaço: ); 24: scanf( %s %s, reg.nome, reg.snome); 25: 26: printf( \ndigite a quantia doada: ); 27: scanf( %f, &reg.quantia); 28: 29: /* Chama a função que exibe os dados. */ 30: 31: print_reg( reg ); 32: } 33: 34: void print_reg(struct dados x) 35: { 36: printf( \no doador %s %s deu $%.2f., x.nome, x.snome, x.quantia); 37: } Digite o nome e o sobrenome do doador, separados por um espaço: Carlos Silva Digite a quantia doada: 1000.00 O doador Carlos Silva deu $1000.00.

Linguagem de Programação C - notas de aula - parte 2 Página: 31 7. ARQUIVOS EM DISCO ARQUIVO (conceito): Uma coleção de bytes armazenados em memória secundária (disquete, disco rígido, fita magnética, etc.), e referenciados por um nome comum. IBPI, Dominando a linguagem C Os dados manipulados em C, a princípio, vêm do teclado (dispositivo padrão de entrada STDIN) e são enviados para a tela (dispositivo padrão de saída STDOUT). A linguagem C permite que sejam manipulados outros dispositivos de entrada e saída, como a impressora (STDPRN) ou mesmo arquivos em disco. Os arquivos em disco manipulados pela linguagem C podem ser do tipo texto ou do tipo binário. ARQUIVO EM MODO DE TEXTO: Um arquivo em modo de texto é uma seqüência de linhas, onde cada linha contém zero ou mais caracteres e termina com caracteres de sinalização de fim de linha. Uma linha não é um string pois não termina com \0 e sim com \n. Um \n é um sinalizador de fim de linha e, em geral, é representado pelos caracteres CR (carriage return) e LF (line feed). ARQUIVO EM MODO BINÁRIO: Um arquivo em modo binário é uma seqüência de caracteres onde os dados são gravados e lidos exatamente como estão armazenados na memória (2 bytes para inteiros, 4 bytes para float e assim por diante).

Linguagem de Programação C - notas de aula - parte 2 Página: 32 NOMES DE ARQUIVOS: Ao lidar com arquivos é preciso mencionar o nome do arquivo desejado. Os nomes de arquivos são armazenados em strings e são idênticos aos nomes usados pelo sistema operacional, seguindo portanto as mesmas regras de nomenclatura. Nomes de arquivos podem conter também informações sobre o drive e o diretório onde se encontra. Como exemplo, no DOS, poderíamos ter o arquivo: C:\DATA\LIST.TXT Num programa em C, este mesmo arquivo poderia ser mencionado da seguinte forma: char *nomearq = C:\\DATA\\LIST.TXT ; Observações: o uso de duas barras invertidas consecutivas deve-se ao fato que, em C, uma barra invertida possui um significado especial quando colocada dentro de um string; porém, se o nome do arquivo for especificado via teclado, deve-se digitar somente uma barra invertida. no DOS, a regra para nomenclatura de arquivos permite um nome e uma extensão de até três caracteres; os caracteres válidos são: - letras de A a Z - números de 0 a 9 - caracteres especiais como _! @ $ entre outros.

Linguagem de Programação C - notas de aula - parte 2 Página: 33 7.1 A ESTRUTURA FILE: O tipo FILE é uma estrutura declarada em <stdio.h> cujos elementos são informações sobre o arquivo que está sendo acessado, tais como: status do arquivo, endereço do buffer para transferência de dados, posição corrente do ponteiro, entre outras. Cada arquivo manipulado pela linguagem C tem a ele associada uma estrutura do tipo FILE e o modo de referência ao arquivo passa a ser através de um ponteiro para essa estrutura: FILE *fptr; /* ponteiro para um arquivo */ fptr é um ponteiro para a estrutura FILE que será usado para referenciar o arquivo desejado dentro do programa. 7.2 ABRINDO ARQUIVOS: Para manipular arquivos na linguagem C é necessário, primeirament, abrir o arquivo, ou seja, deixá-lo disponível para leitura e/ou gravação. Para abrir um arquivo em C utiliza-se a função fopen, que devolve um ponteiro para a estrutura FILE associada ao arquivo: fptr = fopen(nomearq,modo); onde fptr: é o ponteiro para a estrutura FILE anteriormente declarado; nomearq: é o nome do arquivo a ser aberto e pode conter a especificação do drive e do diretório; pode ser um string literal entre aspas duplas ou um ponteiro para um string armazenado na memória; modo: especifica o modo em que o arquivo deve ser aberto, ou seja, se o arquivo estará em modo texto ou binário e se será

Linguagem de Programação C - notas de aula - parte 2 Página: 34 usado para leitura e/ou gravação de dados, conforme detalhado a seguir. Modos de abertura de arquivos: Modo texto Modo binário Significado r rb Abre o arquivo para leitura; se não existir, retorna null. w wb Abre o arquivo para gravação; se não existir, cria-o; se já existir, apaga os dados já gravados. a ab Abre o arquivo para acréscimo de dados (append); se não existir, cria-o; se já existir, acrescenta novos dados ao fim do arquivo. r+ rb+ Abre o arquivo para leitura e gravação; se não existir, cria-o; se já existir, acrescenta os novos dados no início deste arquivo, sobregravando os já existentes. w+ wb+ Abre o arquivo para leitura e gravação; se não existir, cria-o; se já existir, apaga os dados já existentes, sobregravando-os. a+ ab+ Abre o arquivo para leitura e acréscimo de dados; se não existir, cria-o; se já existir, acrescenta os novos dados no fim do arquivo. 7.3 FECHANDO ARQUIVOS: Ao encerrar o processamento do arquivo, devemos fechálo, isto é, indicar ao sistema operacional que o arquivo não está mais sendo utlizado. Para fechar um arquivo usa-se o seguinte procedimento: fclose(fptr); onde fptr: é o ponteiro para a estrutura FILE que foi usado para referenciar o arquivo na abertura.

Linguagem de Programação C - notas de aula - parte 2 Página: 35 7.4 GRAVANDO ARQUIVOS, CARACTER A CARACTER: Após abrir o arquivo para gravação, pode-se escrever nele usando a função putc( ), como no exemplo abaixo: /* Primeiro, abre-se o arquivo p/ gravação */ fptr = fopen( C:\\TESTE.TXT, w ); /* Mais adiante,pode-se efetuar a gravação */ putc( A,fptr); Exemplo de gravação de arquivo em modo texto: 01: /* PROGRAMA EXEMPLO PARA GRAVAÇÃO DE UM ARQUIVO 02: TEXTO, CARACTER A CARACTER */ 03: 04: #include <stdio.h> 05: #include <conio.h> 06: 07: main() 08: { 09: FILE *fptr; 10: char ch; 11: 12: /* Abre o arquivo especialmente para gravação */ 13: fptr = fopen("c:\\luciana\\teste.txt","w"); 14: 15: /* Lê um caracter do teclado até ser digitado um 16: 'enter' (return) usando a função getche() */ 17: 18: while ((ch = getche())!= '\r') 19: putc(ch,fptr); // grava o caracter 20: 21: /* Fecha o arquivo */ 22: fclose(fptr); 23: }

Linguagem de Programação C - notas de aula - parte 2 Página: 36 7.5 LENDO ARQUIVOS, CARACTER A CARACTER: Para ler dados anteriormente gravados num arquivo é preciso, primeiramente, abri-lo para leitura; em seguida, pode-se ler caracter a caracter, até encontrar o caracter de fim de arquivo (EOF). Para esta forma de leitura, pode-se usar a função getc( ), como no exemplo abaixo: /* Primeiro, abre-se o arquivo p/ leitura */ fptr = fopen( C:\\TESTE.TXT, r ); /* Mais adiante,pode-se efetuar a leitura */ getc(fptr); Exemplo de leitura de arquivo em modo texto: 01: /* PROGRAMA EXEMPLO PARA LEITURA DE UM ARQUIVO 02: TEXTO, CARACTER A CARACTER */ 03: 04: #include <stdio.h> 05: 06: main() 07: { 08: FILE *fptr; 09: int ch; 10: 11: /* Abre o arquivo especialmente para leitura */ 12: fptr = fopen("c:\\luciana\\teste.txt","r"); 13: 14: /* Lê um caracter do arquivo até ser encontrado um 15: caracter de 'fim de arquivo' (EOF) com getc() */ 16: 17: while ((ch = getc(fptr))!= EOF ) 18: putchar(ch); // imprime o caracter na tela 19: 20: /* Fecha o arquivo */ 21: fclose(fptr); 22: }

Linguagem de Programação C - notas de aula - parte 2 Página: 37 7.6 ERROS AO ABRIR ARQUIVOS: Uma tentativa de abertura de arquivo pode resultar num erro. Por execmplo, você pode tentar abrir paa leitura um arquivo inexistente; pode não haver espaço em disco para gravação dos dados; pode ocorrer uma fallha na leitura do disco, etc. Por estes motivos, é importante que os programa que acessam arquivos em disco verifiquem se estes foram abertos com sucesso antes de tentar ler ou gravar informações. Para saber se houve um erro na abertura do arquivo, basta verificar se a função fopen retornou um caracter NULL: /* Checagem na abertura do arquivo p/ leitura */ if ((fptr = fopen( C:\\TESTE.TXT, r )) == NULL) puts( Erro ao abrir o arquivo ); /* Checagem na abertura do arquivo p/ gravação */ if ((fptr = fopen( C:\\TESTE.TXT, w )) == NULL) puts( Erro ao abrir o arquivo );

Linguagem de Programação C - notas de aula - parte 2 Página: 38 7.7 GRAVANDO ARQUIVOS, LINHA A LINHA: É possível gravar strings diretamente num arquivo aberto para gravação através da função fputs( ). Para gerar um arquivo texto corretamente é necessário adicionar um caracter de fim de linha ( \n ) ao final de cada string. Exemplo de gravação de strings em arquivo em modo texto: 01: /* PROGRAMA EXEMPLO PARA GRAVAÇÃO DE UM ARQUIVO TEXTO, 02: LINHA A LINHA */ 03: 04: #include <stdio.h> 05: #include <string.h> 06: 07: main() 08: { 09: FILE *fptr; 10: char linha[80]; 11: 12: if ((fptr = fopen("c:\\teste.txt","w")) == NULL) 13: puts("erro na abertura do arquivo"); 14: else 15: { 16: do 17: { 18: puts("digite até 80 carateres para gravação no arquivo (deixe em branco para sair):"); 19: gets(linha); 20: if (strlen(linha)>0) /* se digitou algo */ 21: { 22: fputs(linha,fptr); // grava string no arq. 23: fputs("\n",fptr); // grava um fim de linha 24: } 25: } while (strlen(linha)>0); 26: } 27: 28: fclose(fptr); 29: }

Linguagem de Programação C - notas de aula - parte 2 Página: 39 7.8 LENDO ARQUIVOS, LINHA A LINHA: Também é possível ler dados de um arquivo texto armazenando-os em strings através da função fgets( ). A função fgets( ) deve ser acompanhada de um valor que indica o número máximo de caracteres a serem lidos de cada vez. Exemplo de leitura de strings em arquivo em modo texto: 01: /* PROGRAMA EXEMPLO PARA LEITURA DE UM ARQUIVO TEXTO, 02: LINHA A LINHA */ 03: 04: #include <stdio.h> 05: #include <string.h> 06: 07: main() 08: { 09: FILE *fptr; 10: char linha[80]; 11: 12: if ((fptr = fopen("c:\\teste.txt","r")) == NULL) 13: puts("erro na abertura do arquivo"); 14: else 15: { 16: while (fgets(linha,80,fptr)!= NULL) 17: printf("%s",linha); 18: } 19: 20: fclose(fptr); 21: }

Linguagem de Programação C - notas de aula - parte 2 Página: 40 8. ARQUIVOS BINÁRIOS 8.1 LENDO E GRAVANDO REGISTROS: A entrada e saída direta de arquivos é mais utlilizada para salvar dados que serão lidos posteriormente pelo mesmo programa ou por outro programa escrito em C. Esse modo de gravação/leitura só é usado em MODO BINÁRIO; As funções de entrada e saída direta são, respectivamente, fread( ) e fwrite( ), que serão detalhadas a seguir. Em arquivos binários, pode-se ainda efetuar acesso aleatório aos arquivos usando a função fseek( ), como será visto mais adiante. 8.2 GRAVAÇÃO DIRETA COM fwrite( ): A função fwrite( ) envia um bloco de dados da memória para um arquivo em modo binário, e é usada como abaixo: fwrite(endereço,tamanho,quantidade,ponteiro); onde: endereço é o endereço de memória onde se encontram os dados que devem ser gravados no arquivo (é um ponteiro do tipo void); tamanho corresponde ao número de bytes de cada item individual da dados que será gravado; quantidade especifica quantos itens individuais serão

Linguagem de Programação C - notas de aula - parte 2 Página: 41 gravados simultaneamente; ponteiro é o nome do ponteiro usado para indicar o arquivo conforme especificado na abertura do mesmo; A função fwrite( ) retorna o número de itens gravados com sucesso; se este número for menor que tamanho, isso significa que ocorreu algum erro. Exemplos do uso da função fwrite: /* Grava uma única variável do tipo int */ fwrite(&x,sizeof(int),1,fptr); /* Grava uma única variável do tipo double */ fwrite(&y,sizeof(float),1,fptr); /* Grava uma matriz denominada aluno contendo 50 estruturas do tipo registro */ fwrite(aluno,sizeof(registro),50,fptr); /* Grava a matriz anterior como um único bloco */ fwrite(matriz,sizeof(matriz),1,fptr); /* Grava uma variável do tipo int e testa o sucesso*/ if ( fwrite(&x,sizeof(int),1,fptr) =! 1)...// erro

Linguagem de Programação C - notas de aula - parte 2 Página: 42 Programa exemplo com gravação direta (modo binário): 01: /* PROGRAMA EXEMPLO DE GRAVAÇÃO DIRETA EM ARQUIVO BINÁRIO */ 02: #include <stdio.h> 03: #include <string.h> 04: 05: 06: struct data 07: { 08: int dia; 09: int mes; 10: int ano; 11: }; 12: 13: struct registro 14: { 15: char nome[20]; 16: char endereco[30]; 17: char fone[15]; 18: char cpf[11]; 19: struct data nasc; 20: } cliente; 21: 22: main() 23: { 24: FILE *fptr; 25: 26: fptr = fopen("c:\\cliente.bin","wb"); 27: 28: do 29: { 30: fflush(stdin); 31: puts("digite o nome do cliente ou <FIM> para sair:"); 32: gets(cliente.nome); 33: if ( strcmp ( cliente.nome, "FIM" )!= 0 ) 34: { 35: puts("digite o endereço do cliente:"); 36: gets(cliente.endereco); 37: puts("digite o telefone do cliente:"); 38: gets(cliente.fone); 39: puts("digite o CPF do cliente:"); 40: gets(cliente.cpf); 41: puts("digite dia, mes e ano de nasc. do cliente:"); 42: scanf("%d %d %d",&cliente.nasc.dia, &cliente.nasc.mes,&cliente.nasc.ano); 43: fwrite(&cliente,sizeof(registro),1,fptr); 44: } 45: } while ( strcmp ( cliente.nome, "FIM" )!= 0 ); 46: fclose(fptr); 47: }

Linguagem de Programação C - notas de aula - parte 2 Página: 43 8.3 LEITURA DIRETA COM fread( ): A função fread( ) lê um bloco de dados de um arquivo em modo binário para a memória e é usada como abaixo: fread(endereço,tamanho,quantidade,ponteiro); onde: endereço é o endereço de memória onde os dados lidos serão armazenados (é um ponteiro do tipo void); tamanho corresponde ao número de bytes de cada item individual da dados que será lido; quantidade especifica quantos itens individuais serão lidos simultaneamente; ponteiro é o nome do ponteiro usado para indicar o arquivo conforme especificado na abertura do mesmo; A função fread( ) retorna o número de itens lidos que pode ser menor que tamanho se for lido um caractere de fim-de-arquivo ou se ocorrer algum erro na leitura. Exemplos do uso da função fwrite: /* Lê uma única variável do tipo int */ fread(&x,sizeof(int),1,fptr); /* Lê uma única variável do tipo double */ fread(&y,sizeof(float),1,fptr); /* Lê dados do arquivo e armazena-os numa matriz denominada aluno contendo 50 estruturas do tipo registro */ fread(aluno,sizeof(registro),50,fptr); /* Lê dados do arquivo e armazena-os na matriz anterior de uma só vez (como um único bloco) */ fread(matriz,sizeof(matriz),1,fptr); /* Lê uma variável do tipo int e testa o sucesso*/ if ( fread(&x,sizeof(int),1,fptr) =! 1)...// erro

Linguagem de Programação C - notas de aula - parte 2 Página: 44 Programa exemplo com leitura direta (modo binário): 01: /* PROGRAMA EXEMPLO DE LEITURA DIRETA EM ARQUIVO BINÁRIO */ 02: #include <stdio.h> 03: #include <string.h> 04: 05: struct data 06: { 07: int dia; 08: int mes; 09: int ano; 10: }; 11: 12: struct registro 13: { 14: char nome[20]; 15: char endereco[30]; 16: char fone[15]; 17: char cpf[11]; 18: struct data nasc; 19: } cliente; 20: 21: main() 22: { 23: FILE *fptr; 24: 25: fptr = fopen("c:\\cliente.bin","rb"); 26: 27: do 28: { 29: /* se leitura for feita com sucesso, imprima dados */ 30: if ( fread(&cliente,sizeof(registro),1,fptr) == 1 ) 31: { 32: printf("%s %s %s %s %d/%d/%d\n",cliente.nome, cliente.endereco,cliente.fone,cliente.cpf, cliente.nasc.dia,cliente.nasc.mes,cliente.nasc.ano); 33: } 34: } while (! feof(fptr) ); 35: 36: fclose(fptr); 37: }

Linguagem de Programação C - notas de aula - parte 2 Página: 45 8.4 TIPOS DE ACESSO A ARQUIVOS: Todo arquivo aberto tem a ele associado um ponteiro de arquivo que aponta para a posição atual do arquivo, indicando qual o próximo byte que deve ser lido e/ou gravado; Esse ponteiro ou indicador de posição é especificado em termos de bytes a partir da posição inicial do arquivo, que é a posição 0 (zero); Quando um arquivo é novo, seu comprimento é zero e não há outra posição a ser indicada; 8.4.1 ACESSO SEQÜENCIAL Nos exemplos vistos até agora, os arquivos eram acessados de forma seqüencial, com as seguintes características: Quando um arquivo já existe e é aberto, o indicador de posição aponta para o final do arquivo caso tenha sido especificado o modo de acréscimo de dados (append), ou para o seu início quando outro modo é usado; Quando é feita a leitura de dados, o indicador de posição é automaticamente movido para a próxima posição a ser lida, seqüencialmente. O mesmo ocorre durante a gravação, ou seja, após gravar os novos dados logo abaixo dos dados existentes, o indicador de posição é automaticamente movido para a posição subseqüente (seqüencialmente);

Linguagem de Programação C - notas de aula - parte 2 Página: 46 8.4.2 CONTROLANDO O INDICADOR DE POSIÇÃO A função rewind( ) permite mover o indicador de posição do para o início do arquivo, independentemente de onde se encontre num dado momento; A sintaxe desta função é: rewind(fptr) onde fptr é o nome do ponteiro usado para indicar o arquivo conforme especificado na abertura do mesmo; A função ftell( ) indica o valor atual do indicador de posição de um arquivo. Esta função retorna um inteiro longo (que é o número do byte onde está localizado o indicador de posição ) e sua sintaxe é: ftell(fptr) onde fptr é o nome do ponteiro usado para indicar o arquivo conforme especificado na abertura do mesmo;

Linguagem de Programação C - notas de aula - parte 2 Página: 47 8.4.3 ACESSO ALEATÓRIO O acesso aleatório, ao contrário do seqüencial, permite que a transferência de dados seja feita de/para qualquer posição do arquivo, sem que as informações anteriores precisem ser acessadas. A função que permite o acesso aleatório a um arquivo é fseek( ) e sua sintaxe é a seguinte: fseek(fptr,offset,origem) onde fptr é o nome do ponteiro usado para indicar o arquivo conforme especificado na abertura do mesmo; offset é o deslocamento, em bytes, contado a partir da origem; origem indica a origem do deslocamento e pode ser: 0 (início do arquivo) 1 (posição atual do indicador de posição ) 2 (fim do arquivo) Note que, quando a origem especificado for o fim do arquivo (valor 2), o deslocamento (offset) deve ser negativo;

Linguagem de Programação C - notas de aula - parte 2 Página: 48 9. Funções de gerenciamento de arquivos: 9.1 Apagando um arquivo: /* Demonstra o uso da função remove().*/ #include <stdio.h> #include <stdlib.h> main() { char nomearq[80]; printf("digite o nome do arquivo a ser apagado:"); gets(nomearq); } if(remove(nomearq)==0) printf("o arquivo %s foi apagado.",nomearq); else printf("erro ao apagar o arquivo %s.",nomearq); 9.2 Mudando o nome de um arquivo: /* Mudando o nome de um arquivo usando rename().*/ #include <stdio.h> #include <stdlib.h> main(){ char oldname[80], newname[80]; printf("digite o nome atual:"); gets(oldname); printf("digite o novo nome:"); gets(newname); if (rename(oldname, newname) == 0) printf("o nome de %s foi mudado para %s.", oldname, newname); else printf("erro ao renomear %s.",oldname); }

Linguagem de Programação C - notas de aula - parte 2 Página: 49 9.3 Copiando um arquivo: /* Copiando um arquivo.*/ #include <stdio.h> #include <stdlib.h> #include <string.h> int copia_arq(char *nomeorigem, char *nomedestino); main(){ char origem[80], destino[80]; /* Obtem os nomes dos arquivos de origem e de destino.*/ printf("\ndigite o nome do arquivo de origem:"); gets(origem); printf("\ndigite o nome do arquivo de destino:"); gets(destino); } if(copia_arq(origem, destino) == 0) puts("arquivo copiado sem problemas."); else printf("erro durante a operação de cópia."); int copia_arq(char *origem, char *destino){ FILE *forigem, *fdestino; int c; /*Abre o arq.de origem para leitura em modo binário.*/ if ((forigem = fopen(origem, "rb"))== NULL) return -1; /*Abre arq.de destino para gravação em modo binário.*/ if ((fdestino = fopen(destino, "wb"))== NULL){ } fclose(forigem); return -1; /* Le 1 byte de cada vez do arq. de origem. */

Linguagem de Programação C - notas de aula - parte 2 Página: 50 /* se o fim do arquivo ainda não foi atingido, */ /* grava o byte no arquivo de destino.*/ while(1) { c= fgetc(forigem); if (!feof(forigem)) fputc(c, fdestino); else break; } fclose(forigem); fclose(fdestino); } return 0; 9.4 Usando arquivos temporários: /* Demonstra o uso de arquivos temporarios.*/ #include <stdio.h> main(){ char buffer[10], *c; /*Obtem um nome temporario no buffer especificado.*/ tmpnam(buffer); /*Obtem outro nome, desta vez no buffer interno*/ /* da própria função.*/ c = tmpnam(null); /* Exibe os nome.*/ } printf("o nome temporario 1 e $\%s", buffer); printf("\no nome temporario 2 e %s", c);