CCO 016 / COM 110 Fundamentos de Programação

Documentos relacionados
Universidade de São Paulo São Carlos Instituto de Ciências Matemáticas e de Computação. Arquivos em C

Arquivos em C Parte 2

13a. Aula Manipulação de arquivos

Arquivos. Programação de Computadores I. Natália Batista.

Manipulação de Arquivos

Depuração e Teste de programas C C Depuração e teste de programas C

Manipulação de Arquivos Exercício/Exemplo:

LINGUAGEM C: ARQUIVOS

LINGUAGEM C: ARQUIVOS

Programação para Computação 13ª Aula

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

Computação 2. Aula 9. Diego Addan Arquivos

Aula 16: Manipulação de Arquivos em C

Computação 2. Aula 8. Profª. Fabiany Arquivos

Manipulação de Arquivos

Manipulação de Arquivos

E/S em Arquivo. Para ler ou escrever arquivos é preciso usar ponteiros de arquivo. Um ponteiro de arquivo é uma variável ponteiro do tipo FILE:

Programação II. Arquivos - Conceito. Arquivos

Alocação Dinâmica de Memória - Exercício

Aula 14 Oficina de Programação Tópicos Especiais em C: Arquivos. Profa. Elaine Faria UFU

Existe uma quantidade de informação que pode ser armazenada para resolver o problema.

9. Arquivos em C. Prof. Renato Tinós. Departamento de Computação e Matemática (FFCLRP/USP) Introdução à Computação II

Alocação Dinâmica de Memória - Exercício Escreva um programa em C que manipule um vetor de inteiros não nulos alocado dinamicamente.

Linguagem C. Armazenamento de Dados em Arquivos - Continuação

SSC304 Introdução à Programação Para Engenharias. Arquivos. GE4 Bio

Computação Eletrônica. Aula 12 Arquivos Texto e Binário. Prof: Luciano Barbosa. CIn.ufpe.br

Universidade Federal de Uberlândia Faculdade de Computação. Linguagem C: Manipulação de arquivos

Algoritmos e Estruturas de Dados II IEC013

Departamento de Sistemas de Computação Universidade de São Paulo Introdução a Ciência de Computação I. Aula 13 Arquivos

Aula: ARQUIVOS. Introdução à Ciência da Computação I Simone Senger Souza. ICMC/USP São Carlos

Sumário. Ficheiros. Ficheiros

Outline. 33. Manipulação de arquivos DIM

Arquivos em C. Material da Prof. Ana Eliza

Aula 26 - Arquivos. Prof. Laura Silva de Assis. Engenharia da Computação. CEFET/RJ - Centro Federal de Educação Tecnológica Celso Suckow da Fonseca

Programação. MEAer e LEE. Manipulação de ficheiros de texto. Bertinho Andrade da Costa. Instituto Superior Técnico. 2010/2011 1º Semestre

Laboratório de Introdução à Ciência da Computação I

Métodos Computacionais. Arquivos

Computadores Digitais 2. Prof. Rodrigo de Souza Couto

Introdução a Programação. Manipulando Arquivos em Modo Texto

3.1 - Funções para manipular dados de entrada e saída padrão

MC-102 Aula 24 Arquivos em C e Parâmetros do Programa

CCO 016 / COM 110 Fundamentos de Programação

C Arquivos. Adriano Cruz 21 de julho de Instituto de Matemática Departamento de Ciência da Computação UFRJ

Programação II. Files Read & Write. Bruno Feijó Dept. de Informática, PUC-Rio

Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria

Introdução à Programação

TÉCNICAS DE PROGRAMAÇÃO

Fundamentos de Programação

Fundamentos de Programação 1

Capítulo 06: Arquivos

Capítulo 6: Arquivos

Arquivos em C. Notas de Aula. Prof. Francisco Rapchan

INF 1620 P2-14/10/05 Questão 1 Nome:

USP - ICMC - SSC SSC o. Semestre Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria

Arquivos. Estruturas de Dados II Vanessa Braganholo

CCO 016 / COM 110 Fundamentos de Programação

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA RIO GRANDE DO NORTE

Programação de Computadores

Manipulação de Arquivos. Técnicas de Programação

O que é a modularização

CCO 016 / COM 110 Fundamentos de Programação

INF1005: Programação 1. Arquivos. 02/05/10 (c) Paula Rodrigues 1

Estruturas de Dados. Módulo 15 - Arquivos. 2/6/2005 (c) Dept. Informática - PUC-Rio 1

Manipulação de Arquivos

1/24 FICHEIROS DE TEXTO

USP - ICMC - SSC SSC o. Semestre Disciplina de Introdução à Computação para Engenharia Ambiental

CURSO BÁSICO DE PROGRAMAÇÃO AULA 17. Manipulação de arquivos binários.

9/24/2014. Prof. André Backes

INF 1620 P4 30/06/07 Questão 1 Nome:

Faculdade de Computação

INF 1620 P3-29/06/04 Questão 1 Nome:

Apêndice B. Cadeias de Caracteres (Strings)

Disciplina de Linguagem de Programação e Aplicações [ Eng. Elétrica / Automação ]

MAC-115 Introdução à Computação para Ciências Exatas e Tecnologia IO Terceiro Exercício-Programa Entregar até 09/11/2007

USP - ICMC - SSC SSC o. Semestre Disciplina de Linguagem de Programação e Aplicações [ Eng. Elétrica / Automação ]

Referências. Arquivos. Tópicos Principais. Programação de Computadores II. Motivação. Motivação. Abertura de arquivo. Slides da profa.

Introdução a Programação. Arquivos

INF 1005 Programação I - Prof. Hélio Lopes 24/04/2012

Introdução à Programação

INF 1620 P4-09/07/03 Questão 1 Nome:

Objetivo. Compreender a definição e dominar a implementação de ponteiros em C. Dominar a manipulação de arquivos

Aula 26: Arquivos de texto

INF 1620 P3-27/11/04 Questão 1 Nome:

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

1 Escrita de Arquivos Binário

INF 1620 P3-02/07/02 Questão 1 Nome:

Treinamento Olimpíada Brasileira de Informática

4 MDP. void média e dp(int a[],int n,float em,float ed) 7. Variáveis auxiliares 7. Faça ed igual ao desvio padrão 6 }

Programação de Computadores I Arquivos na Linguagem C PROFESSORA CINTIA CAETANO

Structs, Ponteiros e Arquivos. Prof. Maurício Dias

Algoritmos e Estruturas de Dados I Linguagem C

Linguagem C arquivos. IF61A/IF71A - Computação 1 Prof. Leonelo Almeida. Universidade Tecnológica Federal do Paraná

INF 1620 P4 11/12/06 Questão 1 Nome:

Programação Computacional Aula 17: Manipulação de arquivos

Leitura de Arquivos. Prof. Fabrício Olivetti de França

Sequência de informações binárias armazenadas num dispositivo de armazenamento permanente. Em geral os bits são agrupados em grupos de 8 (1 byte)

Mestrado em Engenharia Física Tecnológica

Transcrição:

CCO 016 / COM 110 Fundamentos de Programação Prof. Roberto Affonso da Costa Junior Universidade Federal de Itajubá

AULA 11 Estruturas de Programação Entrada de dados via arquivo

Digite o seguinte programa #include <stdio.h> int main() { { int i, v[100], n; i = 0; while(scanf( %d, &v[i])!= EOF) } i++;

Digite o seguinte programa } n = i; for(i = 0; i < n; i++) { printf( %\n, v[i]); } return 0;

Salve-o Salve-o na pasta../aluno/workspace/ com o nome aula.c Execute-o no codeblocks e feche a janela. Crie no codeblock outro arquivo com os valores: 19 20 30 12 15

Salve-o Salve-o com o nome entrada.txt Abra o terminal do computador <ctrl>+<t> Digite: cd../aluno/workspace/ Digite:./aula <entrada.txt Apareceu na tala os valores? Digite agora:./aula <entrada.txt >saida.txt Digite: ls Apareceu o arquivo saida.txt?

FREOPEN Colocar o FREOPEN freopen ("entrada.txt","r",stdin); Veja o que acontece quando você roda. Agora coloque: freopen ("saida.txt","r",stdout);

A declaração: Entrada de dados scanf ( %d, &A ); faz com que o computador fique esperando que o usuário digite um número inteiro no teclado e após isto digite a tecla Enter, com o objetivo de transmitir ao computador, mais especificamente à memória A, o valor numérico digitado;

Ou seja, a declaração indica a leitura de dados através do teclado do computador; Muitas vezes porém, a entrada de dados via teclado é muito exaustiva, proporcionando uma forma muito fácil de se cometer erros ao se entrar com as informações; Exemplo: entrar com os dados de 100 alunos de uma escola;

para k = 1 até 100 faça imprima ( entre com numero de matricula, a idade, o sexo, a primeira nota, a segunda nota ) leia ( matricula, idade, sexo, nota1, nota2 ) fim_para

Esta é uma tarefa bastante desgastante para o usuário, principalmente por ocasião da confecção do programa, onde ele tem que ser executado várias vezes, sendo que a cada vez, o usuário tem que entrar novamente com todos os dados; No programa do exemplo anterior, esta tarefa é bastante desconfortável e também extremamente de alto risco, pois o usuário certa-mente não terá paciência de entrar com todos os dados mais de uma vez;

Uma forma disto ser evitado, é escrevendo num arquivo texto, todos os dados referentes a um programa, tal como se estes dados estivessem sido fornecidos via teclado; O programa, ao invés de ler as informações do teclado, ele as lê do arquivo texto onde elas estão armazenadas, e as guardam na memória normalmente;

A grande vantagem desta forma de entrada de dados, é que estes são digitados uma única vez, ou seja, na ocasião em que eles estiverem sendo armazenados no arquivo, e a partir daí estão a disposição dos programas para sempre; Em outras palavras, com a leitura dos dados em arquivos, há apenas a mudança do meio de armazenamento da informação, que agora passa do teclado para o arquivo; Após lidas, as informações são tratadas da mesma forma que eram até então.

Exemplo 1 Seja um programa que tem o seguinte trecho de entrada: for ( k = 1; k < 5; k++ ) scanf ( %d %c %s, &idade, &sexo, pnome ); O usuário deste programa tem que fornecer ao mesmo 4 registros contendo as informações pedidas; Este usuário tem então que digitar no teclado informações tais como as mostradas no exemplo a seguir: 19 M Roberto Tecla Enter 15 F Marta Tecla Enter 20 F Fabiana Tecla Enter 20 M Rubens Tecla Enter

Se for aumentada a quantidade de registros a serem lidos, tem-se então necessidade de fornecer todos estes registros, conforme solicitado pela entrada; Se por ventura for descoberto um erro no programa, tem-se que executá-lo novamente, e daí a necessidade de novamente digitar os mesmos dados;

Arquivo na Linguagem C A linguagem C não contém nenhum comando de E/S. Ao contrário, todas as operações de E/S ocorrem mediante chamadas de biblioteca C padrão; Essa abordagem faz o sistema de arquivos de C extremamente poderoso e flexível; O sistema de E/S de C é único, porque dados podem ser transferidos na sua representação binária interna ou em um formato de texto legível por humanos;

Arquivo na Linguagem C Antes de começar a falar do sistema de arquivos C ANSI, é importante entender a diferença entre os termos streams e arquivos; O sistema de arquivos de C é projetado para trabalhar com uma ampla variedade de dispositivos, incluindo terminais, acionadores de disco e acionadores de fita; Embora cada um dos disposistivos seja muito diferente, o sistema de arquivo com buffer transforma-os em um dispositivo lógico chamado de stream;

Arquivo na Linguagem C Portanto, o stream é uma abstração do dispositivo real chamado de arquivo; Pelo fato de as streams serem amplamente independentes do dispositivo, a mesma função pode escrever em um arquivo em disco ou em algum outrodispositivo, como o console; Existem dois tipos de streams: Texto e binária

Arquivo na Linguagem C Uma stream de texto é uma sequência de caracteres. O padrão C ANSI permite (mas não exige) que uma stream de texto seja organizada em linhas terminadas por um caractere de nova linha; Porém, o caracter de nova linha é opcional na última linha e é determinado pela implementação;

Arquivo na Linguagem C Uma stream binária é uma sequência de bytes com uma correspondencia de um para com aqueles encontrados no dispositivo externo; Em C, um arquivo pode ser qualquer coisa, desde um arquivo em disco até um terminal ou uma impressora; Você associa uma stream com um arquivo específico realizando uma operação de abertura; Uma vez o arquivo aberto, informações podem ser trocadas entre ele e o seu programa;

Arquivo na Linguagem C Cada stream associada a uma arquivo tem uma estrutura de controle de arquivo do tipo FILE; Essa estrutura é definida no cabeçalho STDIO.H O sistema de arquivos C ANSI é composto de diveras funções inter-relacionadas; A maioria das funções começa com a letra f. Isso é uma conversão do padrão C UNIX, que definiu dois sistemas de arquivos;

Arquivo na Linguagem C O ponteiro é o meio comum que une o sistem C ANSI de E/S; Um ponteiro de arquivo é um ponteiro para informações que definem várias coisas sobre o arquivos como: Nome, status e posição atual do arquivo; Basicamente, o ponteiro de arquivo identifica um arquivo específico em disco e é usado pela stream associadas para direcionar as operações das funções de E/S;

Arquivo na Linguagem C O sistema de entrada e saída do ANSI C é composto por uma série de funções, cujos protótipos estão reunidos em stdio.h. Todas estas funções trabalham com o conceito de "ponteiro de arquivo". Este não é um tipo propriamente dito, mas uma definição usando o comando typedef. Esta definição também está no arquivo stdio.h. Podemos declarar um ponteiro de arquivo da seguinte maneira: FILE *p;

Arquivo na Linguagem C FILE *p; p será então um ponteiro para um arquivo. FILE é o tipo da variável que permite que o ponteiro manipule arquivos na linguagem C.

Introdução No sistema de arquivo stdio.h. Temos três funções básicas para trabalhar com arquivo, que são: * fopen * exit * fclose

fopen Esta é a função de abertura de arquivos. Seu protótipo é: FILE *fopen (char *nome_do_arquivo,char *modo); O nome_do_arquivo determina qual arquivo deverá ser aberto. Este nome deve ser válido no sistema operacional que estiver sendo utilizado. O modo de abertura diz à função fopen() que tipo de uso você vai fazer do arquivo. A tabela abaixo mostra os valores de modo válidos:

fopen - Modo Modo "r" "w" "a" Significado Abre um arquivo texto para leitura. O arquivo deve existir antes de ser aberto. Abrir um arquivo texto para gravação. Se o arquivo não existir, ele será criado. Se já existir, o conteúdo anterior será destruído. Abrir um arquivo texto para gravação. Os dados serão adicionados no fim do arquivo ("append"), se ele já existir, ou um novo arquivo será criado, no caso de

fopen - Modo Modo "rb" "wb" "ab" Significado Abre um arquivo binário para leitura. Igual ao modo "r" anterior, só que o arquivo é binário. Cria um arquivo binário para escrita, como no modo "w" anterior, só que o arquivo é binário. Acrescenta dados binários no fim do arquivo, como no modo "a" anterior, só que o arquivo é binário.

fopen - Modo Modo "r+" "w+" "a+" Significado Abre um arquivo texto para leitura e gravação. O arquivo deve existir e pode ser modificado. Cria um arquivo texto para leitura e gravação. Se o arquivo existir, o conteúdo anterior será destruído. Se não existir, será criado. Abre um arquivo texto para gravação e leitura. Os dados serão adicionados no fim do arquivo se ele já existir, ou um novo arquivo será criado, no caso de

fopen - Modo Modo "r+b" Significado Abre um arquivo binário para leitura e escrita. O mesmo que "r+" acima, só que o arquivo é binário. "w+b" Cria um arquivo binário para leitura e escrita. O mesmo que "w+" acima, só que o arquivo é binário. "a+b" Acrescenta dados ou cria uma arquivo binário para leitura e escrita. O mesmo que "a+" acima, só que o arquivo é binário.

fopen Como usar? Pode-se então, abrir um arquivo binário para escrita, escrevendo: FILE *fp; // Declaração da estrutura fp = fopen ("exemplo.bin","wb"); /* o arquivo se chama exemplo.bin e está localizado no diretório corrente */ if (!fp) printf ("Erro na abertura do arquivo.");

fopen Como usar? A condição!fp testa se o arquivo foi aberto com sucesso porque no caso de um erro a função fopen() retorna um ponteiro nullo (NULL).

exit Aqui abrimos um parênteses para explicar a função exit() cujo protótipo é: void exit (int codigo_de_retorno);

exit Para utilizá-la deve-se colocar um include para o arquivo de cabeçalho stdlib.h. Esta função aborta a execução do programa. Pode ser chamada de qualquer ponto no programa e faz com que o programa termine e retorne, para o sistema operacional, o código_de_retorno. A convenção mais usada é que um programa retorne zero no caso de um término normal e retorne um número não nulo no caso de ter ocorrido um problema.

exit A função exit() se torna importante em casos como alocação dinâmica e abertura de arquivos pois nestes casos, se o programa não conseguir a memória necessária ou abrir o arquivo, a melhor saída pode ser terminar a execução do programa. Pode-se reescrever o exemplo da seção anterior usando agora o exit() para garantir que o programa não deixará de abrir o arquivo:

Exemplo #include <stdio.h> #include <stdlib.h> /* Para a função exit() */ int main() { FILE *p; } if (!(p = fopen("exemplo.txt","r"))) { printf("erro! Impossivel abrir o arquivo!\n"); exit(1); } return 0;

fclose Quando acabamos de usar um arquivo que abrimos, devemos fechá-lo. Para tanto usa-se a função fclose(): int fclose (FILE *fp); O ponteiro fp passado à função fclose() determina o arquivo a ser fechado. A função retorna zero no caso de sucesso.

fclose Fechar um arquivo faz com que qualquer caracter que tenha permanecido no "buffer" associado ao fluxo de saída seja gravado. Mas, o que é este "buffer"? Quando você envia caracteres para serem gravados em um arquivo, estes caracteres são armazenados temporariamente em uma área de memória (o "buffer") em vez de serem escritos em disco imediatamente.

fclose Quando o "buffer" estiver cheio, seu conteúdo é escrito no disco de uma vez. A razão para se fazer isto tem a ver com a eficiência nas leituras e gravações de arquivos. Se, para cada caracter que fossemos gravar, tivéssemos que posicionar a cabeça de gravação em um ponto específico do disco, apenas para gravar aquele caracter, as gravações seriam muito lentas. Assim estas gravações só serão efetuadas quando houver um volume razoável de informações a serem gravadas ou quando o arquivo for fechado.

Exemplo 2 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; if (!(fp = fopen("exemplo.txt","w"))) { } printf("erro! Impossivel abrir o arquivo!\n"); exit(1); } fclose(fp); return 0; Veja se você criou o arquivo exemplo.txt na sua pasta.

fprintf A função fprintf() funciona como a função printf(). A diferença é que a saída de fprintf() é um arquivo e não a tela do computador. Protótipo: int fprintf (FILE *fp,char *str,...); Como já poderíamos esperar, a única diferença do protótipo de fprintf() para o de printf() é a especificação do arquivo destino através do ponteiro de arquivo.

Exemplo 4 #include <stdio.h> #include <stdlib.h> int main() { FILE *p; char str[80],c; /* Le um nome para o arquivo a ser aberto: */ printf("\n\n Entre com um nome para o arquivo: "); scanf(" %[^\n]",str);

Exemplo 4 if (!(p = fopen(str,"w"))) { printf("\t\terro! Impossivel abrir o arquivo!\n"); exit(1); } } /* Se nao houve erro, imprime no arquivo, fecha...*/ fprintf(p,"\n\t\teste e um arquivo chamado: %s\n", str); fclose(p); printf("\n\t\tabra e leia o arquivo %s.\n\n",str); return 0;

fscanf A função fscanf() funciona como a função scanf(). A diferença é que fscanf() lê de um arquivo e não do teclado do computador. Protótipo: int fscanf (FILE *fp,char *str,...); Como já poderíamos esperar, a única diferença do protótipo de fscanf() para o de scanf() é a especificação do arquivo destino através do ponteiro de arquivo.

Exemplo 5 #include <stdio.h> #include <stdlib.h> int main() { FILE *p; char str[80],c; /* Le um nome para o arquivo a ser aberto: */ printf("\n\n Entre com um nome para o arquivo: "); scanf(" %[^\n]",str);

Exemplo 5 if (!(p = fopen(str,"w"))) { printf("\t\terro! Impossivel abrir o arquivo!\n"); exit(1); } /* Se nao houve erro, imprime no arquivo, fecha...*/ fprintf(p,"\n\t\teste e um arquivo chamado: %s\n", str); fclose(p); /* abre novamente para a leitura */ p = fopen(str,"r");

Exemplo 5 while (!feof(p)) { fscanf(p,"%c",&c); printf("%c",c); } fclose(p); // Fecha o arquivo } printf("\n\t\tabra e leia o arquivo %s.\n\n",str); return 0;

Exemplo 6 Escreva em linguagem C o trecho de progra-ma apresentado a seguir: para ( k = 1 até 10 ) faça imprima ( entre com a idade, primeiro nome e sexo do aluno ) leia ( idade, pnome, sexo); fim_para Simule os dados necessários ao programa Comente a entrada de dados operacionalmente

#include <stdio.h> int main ( ) { // definição das variáveis int k, idade; char nome[30], sexo; // cabeçalho de saída printf ( IDADE NOME SEXO \n ); // entrada e impressão dos dados for ( k = 1; k <= 10; k++ ) { printf ( entre com a idade, primeiro nome e sexo do aluno\n ); scanf ( %d %s %c, &idade, pnome, &sexo); printf ( %d %s %c\n, idade, pnome, sexo ); } } // fim do programa

feof EOF ("End of file") indica o fim de um arquivo. Às vezes, é necessário verificar se um arquivo chegou ao fim. Para isto podemos usar a função feof(). Ela retorna não-zero se o arquivo chegou ao EOF, caso contrário retorna zero. Seu protótipo é: int feof (FILE *fp);

feof Outra forma de se verificar se o final do arquivo foi atingido é comparar o caractere lido por getc com EOF. O programa a seguir abre um arquivo já existente e o lê, caracter por caracter, até que o final do arquivo seja atingido. Os caracteres lidos são apresentados na tela:

Exemplo 3 #include <stdlib.h> #include <stdlib.h> int main() { FILE *fp; char c, nomearq[30]="exemplo.txt"; int i; printf("\n\t\teste programa demonstra como se le\n"); printf("\t\tdados de um arquivo existente...\n\n"); if(fp = fopen(nomearq,"r")) { while((c = getc(fp) )!= EOF)

Exemplo 3 /* Enquanto não chegar ao final do arquivo */ printf("%c", c); /* imprime o caracter lido */ printf("\n\n\t\tarquivo lido com sucesso!!!\n\n"); } else { } printf( "Erro na abertura do arquivo"); exit(1); } fclose(fp); return 0;

Arquivos pré-definidos Quando se começa a execução de um programa, o sistema automaticamente abre alguns arquivos prédefinidos: stdin: dispositivo de entrada padrão (geralmente o teclado) stdout: dispositivo de saída padrão (geralmente o vídeo) stderr: dispositivo de saída de erro padrão (geralmente o vídeo) stdaux: dispositivo de saída auxiliar (em muitos sistemas, associado à porta serial) stdprn : dispositivo de impressão padrão (em muitos sistemas, associado à porta paralela)

Arquivos pré-definidos Cada uma destas constantes pode ser utilizada como um ponteiro para FILE, para acessar os periféricos associados a eles. Desta maneira, pode-se, por exemplo, usar: ch =getc(stdin); para efetuar a leitura de um caracter a partir do teclado, ou : para imprimí-lo na tela. putc(ch, stdout);

ferror e perror Protótipo de ferror: int ferror (FILE *fp); A função retorna zero, se nenhum erro ocorreu e um número diferente de zero se algum erro ocorreu durante o acesso ao arquivo.

ferror e perror ferror() se torna muito útil quando queremos verificar se cada acesso a um arquivo teve sucesso, de modo que consigamos garantir a integridade dos nossos dados. Na maioria dos casos, se um arquivo pode ser aberto, ele pode ser lido ou gravado. Porém, existem situações em que isto não ocorre. Por exemplo, pode acabar o espaço em disco enquanto gravamos, ou o disco pode estar com problemas e não conseguimos ler, etc. Uma função que pode ser usada em conjunto com ferror() é a função perror() (print error), cujo argumento é uma string que normalmente indica em que parte do programa o problema ocorreu.

fseek Para se fazer procuras e acessos randômicos em arquivos usa-se a função fseek(). Esta move a posição corrente de leitura ou escrita no arquivo de um valor especificado, a partir de um ponto especificado. Seu protótipo é: int fseek (FILE *fp,long numbytes,int origem); O parâmetro origem determina a partir de onde os numbytes de movimentação serão contados. Os valores possíveis são definidos por macros em stdio.h e são:

fseek Nome Valor Significado SEEK_SET 0 Início do arquivo SEEK_CUR 1 Ponto corrente no arquivo SEEK_END 2 Fim do arquivo Tendo-se definido a partir de onde irá se contar, numbytes determina quantos bytes de deslocamento serão dados na posição atual.

rewind A função rewind() de protótipo void rewind (FILE *fp); retorna a posição corrente do arquivo para o início.

remove Protótipo: int remove (char *nome_do_arquivo); Apaga um arquivo especificado.

Arquivo de Dados No exercício anterior é grande o desconforto para se entrar com os dados necessários, visto que os registros são grandes e são em grande número, proporcionando em muito a possibilidade de erros nesta operação; Desta forma, ao invés de se digitar os dados no teclado, e repeti-los todas as vezes que o programa for executado, estes são digitados uma única vez, dentro de um arquivo texto;

Exemplo 7 Através de um Editor de Texto qualquer, por exemplo, o gedit, digita-se as informações dos dados, tais como elas seriam escritas no teclado; Para o exemplo, pode-se ter os seguintes registros: 19 Antonio M 15 Marta F 20 Patricia F 20 Rubens M 15 Juarez M 19 Marcos M 17 Tereza F 16 Paula F 15 Fatima F 21 Julia Y

Estes dados devem ser então salvos num arquivo texto chamado, por exemplo: DADOS.DAT Todas as vezes que um programa precisar daquelas informações, ao invés de lê-las no teclado, ele as lerá do arquivo de dados, quantas vezes forem necessárias, sem ter necessidade do usuário ter que digitá-las de novo.

Implementação Na linguagem C, esta tarefa é resolvida da seguinte forma: #include <stdio.h> int main ( ) { // definição das variaveis int k, idade; char pnome[20], sexo, nome_arquivo_dados[30]; FILE *arquivo_dados;

// nome do arquivo de dados strcpy ( nome_arquivo_dados, DADOS.DAT ); // abertura do arquivo de dados arquivo_dados = fopen ( nome_arquivo_dados, rt ); if ( arquivo_dados == NULL ) { printf ( arquivo %s nao existe\n, nome_arquivo_dados ); } exit(0);

// impressao do cabecalho de saida printf ( IDADE PRIMEIRO NOME SEXO\n ); // leitura e impressao dos dados for ( k = 1; k <= 10; k++ ) { fscanf ( arquivo_dados, %d %s %c, &idade, pnome, &sexo ); printf ( %2d %s %c\n, idade, pnome, sexo ); } } // fim do programa

Arquivo: Definições importantes Local físico onde se guarda informações de qualquer espécie; Tal como na vida real, tem-se arquivos, compos-tos de pastas, onde são guardadas as contas do mês, pagamentos efetuados, etc; Numa biblioteca por exemplo, os arquivos guar-dam as informações dos periódicos, livros, etc.

Registro: É a informação que é lida do arquivo; Exemplo: Uma biblioteca guarda as informações de todos os seus livros numa gaveta, e dentro desta gaveta tem-se várias fichas, contendo cada uma as informações de um livro; neste caso, a gaveta corresponde ao arquivo e a ficha corres-ponde ao registro; Ou seja, ao se consultar um arquivo, no caso ao se abrir a gaveta, retira-se de lá uma ficha que contém as informações de um determinado livro; esta ficha corresponde ao registro lido do arquivo. Portanto, um arquivo pode conter vários registros armazenados;

Campo do registro: Cada ficha da gaveta, que corresponde a cada registro de um arquivo, contém várias informações de um livro; Cada informação desta ocupa um espaço físico da ficha, ou do registro; cada um destes espaços é denominado campo do registro; Portanto: Arquivo contém registros formados por campos;

campo 1 campo 2 campo 3 Registro 1 Idade Sexo Primeiro nome Registro 2 Idade Sexo Primeiro nome..... Registro n Idade Sexo Primeiro nome Um arquivo

Nome físico do arquivo: É o nome como o arquivo é salvo no diretório do usuário; No exemplo do programa anterior, o nome físico do arquivo de dados é DADOS.DAT

Nome lógico do arquivo: É o nome como o programa trata o arquivo; No exemplo do programa, o nome lógico do arquivo é arquivo_dados

Observe que um programa pode ser executado para ler um conjunto de informações armazenadas num determinado arquivo e após isto ser novamente executado para ler outro conjunto de informações armazenadas em outro arquivo; Como o programa gerencia este procedimento? É definido um arquivo lógico e este é associado a um arquivo físico, para ler os dados do primeiro conjunto; este mesmo arquivo lógico é associado novamente a outro arquivo físico para ler os dados do outro conjunto; Por isto existe a necessidade de se ter arquivo físico e arquivo lógico num programa;

Exemplo 4 #include <stdio.h> int main () { // definição das variaveis int k, idade1, idade2; char nome1[20], nome2[20]; char sexo1, sexo2; char nome_arquivo_dados[30]; FILE *arquivo_dados;

// nome do primeiro arquivo de dados strcpy ( nome_arquivo_dados, DADOS_1.DAT ); // abertura do primeiro arquivo de dados arquivo_dados = fopen ( nome_arquivo_dados, rt ); if ( arquivo_dados == NULL ) { printf ( arquivo %s nao existe\n, nome_arquivo_dados ); exit(0); } // leitura dos dados do primeiro arquivo for ( k = 1; k <= 10; k++ ) fscanf ( arquivo_dados, %d %s %c, &idade1, nome1, &sexo1 );

// nome do segundo arquivo de dados strcpy ( nome_arquivo_dados, DADOS_2.DAT ); // abertura do segundo arquivo arquivo de dados arquivo_dados = fopen ( nome_arquivo_dados, rt ); if ( arquivo_dados == NULL ) { printf ( arquivo %s nao existe\n, nome_arquivo_dados ); exit(0); } // leitura dos dados do segundo arquivo for ( k = 1; k <= 10; k++ ) fscanf ( arquivo_dados, %d %s %c, &idade2, nome2, &sexo2 );

Neste programa, na primeira parte, são lidos os dados do primeiro arquivo, ou seja, o arquivo físico DADOS_1.DAT é acessado através do arquivo lógico ARQUIVO_DADOS; Da mesma forma, na segunda parte, são lidos os dados do segundo arquivo, ou seja, o arquivo físico DADOS_2.DAT, o qual é também acessado através do arquivo lógico ARQUIVO_DADOS; Observe também que como os dados estão sendo lidos diretamente de um arquivo de dados, a declaração de interação entre usuário e programa não se faz necessária, ou seja a declaração seguinte não é mais usada: imprima ( entre com a idade, primeiro nome e sexo do aluno )

Programa com dados lidos do teclado: for ( k = 1; k <= 10; k++ ) { printf ( entre com a idade, primeiro nome e sexo do aluno\n ); scanf ( %d %s %c, &idade, pnome, &sexo ); printf ( %2d %s %c\n, idade, pnome, sexo ); } Programa com dados lidos de um arquivo: for ( k = 1; k <= 10; k++ ) { fscanf ( arquivo_dados, %d %s %c, &idade, pnome, &sexo ); printf ( %2d %s %c\n, idade, pnome, sexo ); }

Exemplo 7 implemente o programa anterior, de tal forma que os dados lidos também sejam impres-sos sob um cabeçalho; a) faça testes com a ausência de um ou todos os arquivos de dados; b) coloque quantidade de dados diferentes nos arquivos de dados;

Para se colocar um cabeçalho de saída, o trecho do progra-ma anterior, que corresponde à leitura dos dados do primei-ro arquivo, ou seja: // leitura dos dados do primeiro arquivo for ( k = 1; k < 10; k++ ) fscanf ( arquivo_dados, %d %s %c, &idade1, nome1, &sexo1 ); Deve ser antecedido das declarações: // cabecalho de impressao printf ( IDADE NOME SEXO \n ); O mesmo deve ser feito para o segundo arquivo de dados;

Para a leitura e impressão dos dados, com quantidades dife-rentes de dados nos arquivos, o trecho do programa onde é feita a leitura dos dados do primeiro arquivo: // leitura dos dados do primeiro arquivo for ( k = 1; k <= 10; k++ ) fscanf ( arquivo_dados, %d %s %c, &idade1, nome1, &sexo1 ); Deve ser substituído por: // leitura e impressao dos dados do primeiro arquivo for ( k = 1; k <= n; k++ ) { fscanf ( arquivo_dados, %d %s %c, &idade1, nome1, &sexo1 ); printf ( %d %s %c \n, idade1, nome1, sexo1 ); }

Neste caso, o valor da variável n ou é definido anteriormente à esta declaração ou é solicitado que ele seja fornecido co-mo entrada de dados, ou seja: n = 10; // valor de n Ou: // entrada do valor de n printf ( entre com o valor de n\n ); scanf ( %d, &n ); Faz-se o mesmo para o segundo arquivo; Para se ter quantidade de dados diferentes nos dois arqui-vos, basta entrar com valores diferentes de n

Exemplo 8 Repita o exercício anterior de tal forma que: a) o nome do arquivo físico seja dado em tempo de execução do programa; b) flags sejam utilizados nos arquivos de dados;

Para se ter o nome do arquivo dado em tempo de execução do programa, a declaração: // nome do primeiro arquivo de dados strcpy ( nome_arquivo_dados, DADOS_1.DAT ); Deve ser substituída pelas declarações: // entrada do nome do primeiro arquivo de dados printf ( entre com o nome do primeiro arquivo de dados ); scanf ( %s, nome_arquivo_dados ); A partir deste instante, o nome do arquivo de dados foi introduzido na variável e vai ser utilizado para abrir o arqui-vo tal como no programa anterior; Para o segundo arquivo de dados, o mesmo procedimento deve ser repetido;

Quanto à utilização de flags para leitura dos dados, mo-difica a forma de como estes dados são colocados no arquivo, ou seja, agora não se conhece a quantidade de dados armazenados, por isso um flag é colocado; Neste caso a declaração de leitura dos dados não pode ser feita com a instrução for, como no programa anterior, pois esta só pode ser utilizada quando se conhece a priori quantos registros vão ser lidos; Como não é este o caso, tem-se que então utilizar a repetição não definida, apropriada para estas situações, onde não se conhece quantas vezes o procedimento vai ser repetido.

Portanto, o trecho do programa onde se faz a leitura dos dados via arquivo: // leitura e impressao dos dados do primeiro arquivo for ( k = 1; k <= 10; k++ ) { fscanf ( arquivo_dados, %d %s %c, &idade1, nome1, &sexo1 ); printf ( %d %s %c \n, idade1, nome1, sexo1 ); } Vai ser substituído por: // leitura e impressao dos dados do primeiro arquivo fscanf ( arquivo_dados, %d %s %c, &idade1, nome1, &sexo1 ); while ( idade1!= 999 ) { printf ( %d %s %c \n, idade1, nome1, sexo1 ); fscanf ( arquivo_dados, %d %s %c, &idade1, nome1, &sexo1 ); }

Observe que agora um flag é utilizado para a variável idade, ou seja, enquanto um valor de idade = 999 não for forne-cido, o programa solicita nova leitura de dados do arquivo; Poderia ser utilizado qualquer outro tipo de flag, como por exemplo, fim para o nome do aluno; não esquecer que neste caso a função strcmp deve ser usada afim de compa-rar cadeias; Observar também que antes de se iniciar a repetição com a declaração while, é necessário que se tenha um valor inicial para a variável de controle desta repetição, no nosso exemplo, a variável idade1; Isto é providenciado com a colocação da declaração de entrada do primeiro registro de dados, antes de se iniciar a repetição da entrada dos outros registros de dados;

Exemplo 9 São dados vários registros de informações, cada um com a seguinte estrutura : Data de nascimento ( dd mm aaaa ) sexo Primeiro Nome do aluno Nota 1 Nota 2 a) O flag fim em nome de aluno deverá ser utilizado para indicar a parada de entrada dos dados; b) Calcular a nota final para cada aluno ( peso 2 na nota 1 e peso 3 na nota 2 )

c) Calcular o conceito de cada aluno segundo o seguinte critério: -nota final menor que 50, conceito R -nota final maior ou igual a 50 e menor que 70, conceito A -nota final maior ou igual a 70 e menor que 90, conceito B -nota final maior ou igual a 90, conceito E d) Mostrar todo o registro do aluno para todos os alunos; e) Calcular quantas meninas tiveram conceito E e quantos meninos tiveram conceito A ou B f) Calcular a média da classe; g) Calcular a média dos meninos;

h) Calcular a média das meninas; i) Calcular quantas meninas nasceram entre 10 e 20 de outubro (inclusives); j) Calcular quantos meninos, nascidos em fevereiro, têm conceito R; k) Calcular a percentagem de alunos em cada um dos conceitos; i) Fazer a consistência de todos os dados de entrada;

SOLUÇÃO

// PROGRAMA PARA LER E IMPRIMIR VÁRIOS REGISTROS DE DADOS // DE ALUNOS DE UMA SALA DE AULA // PROGRAMA FAZ TAMBEM VARIAS ESTATISTICAS SOBRE OS DADOS // LIDOS E CALCULADOS #include <stdio.h> #include <conio.h> #include <string.h> #include <stdlib.h> int main ( void ); int main ( void ) { // definicao das variaveis int dia_nascimento, mes_nascimento, ano_nascimento, nota1, nota2, q_a, q_b, q_r, q_e, q_fe, q_mab, q_mr, q_f1020, q_alunos, q_m, q_f; int chave_erro; char sexo_aluno, nome_aluno[30], conceito, nome_arq_dados[30]; float media_aluno, soma_medias_classe, soma_medias_meninas, soma_medias_meninos; FILE *arq_dados;

// inicializando variaveis q_a = 0; // quantidade de alunos com conceito A q_b = 0; // quantidade de alunos com conceito B q_r = 0; // quantidade de alunos com conceito R q_e = 0; // quantidade de alunos com conceito E q_fe = 0; // quantidade de meninas com conceito E q_mr = 0; // quantidade de meninos com conceito R q_mab = 0; // quantidade de meninos com conceito A ou B q_f1020 = 0; // quantidade de meninas nascidas entre 10 e 20 de outubro q_f = 0; // quantidade de meninas q_m = 0; // quantidade de meninos q_alunos = 0; // quantidade de alunos soma_medias_classe = 0; // somatorio das medias de todos os alunos soma_medias_meninas = 0; // somatorio das medias das meninas soma_medias_meninos = 0; // somatorio das medias dos meninos

// entrada do nome do arquivo de dados printf ( entre com o nome do arquivo de dados\n ); scanf ( %s, nome_arq_dados ); // abertura do arquivo de dados arq_dados = fopen ( nome_arq_dados, rt ); if ( arq_dados == NULL ) { printf ( arquivo %s não existe\n, nome_arq_dados ); exit(0); } // entrada do primeiro registro do arquivo fscanf ( arq_dados, "%d %d %d %c %s %d %d", &dia_nascimento, &mes_nascimento, &ano_nascimento, &sexo_aluno, nome_aluno, &nota1, &nota2 );

while ( strcmp ( nome_aluno, "fim" )!= 0 ) // fazendo a consistencia dos dados chave_erro = 0; // chave que indica que os dados estão corretos if ( ( mes_nascimento < 1 ) ( mes_nascimento > 12 ) ) { printf ( "mes errado\n" ); chave_erro = 1; } else { if ( ( ano_nascimento < 1900 ) ( ano_nascimento > 2010 ) ) { printf ( "ano errado\n" ); chave_erro = 1; } else { if ( ( ( mes_nascimento == 1 ) ( mes_nascimento == 3 ) ( mes_nascimento == 5 ) ( mes_nascimento == 7 ) ( mes_nascimento == 8 ) ( mes_nascimento == 10 ) ( mes_nascimento == 12 ) ) && ( ( dia_nascimento < 1 ) ( dia_nascimento > 31 ) ) ) { printf ( "dia errado para este mes\n" ); chave_erro = 1; }

if ( ( ( mes_nascimento == 4 ) ( mes_nascimento == 6 ) ( mes_nascimento == 9 ) ( mes_nascimento == 11 ) ) && ( ( dia_nascimento < 1 ) ( dia_nascimento > 31 ) ) ) { } printf ( "dia errado para este mes\n" ); chave_erro = 1; if ( ( mes_nascimento == 2 ) && ( ( dia_nascimento < 1 ) } ( dia_nascimento > 29 ) ) ) { } // END ELSE printf ( "dia errado para este mes\n" ); chave_erro = 1; if ( ( nota1 < 0 ) ( nota1 > 100 ) ( nota2 < 0 ) ( nota2 > 100 ) ) { printf ( "notas erradas\n" ); chave_erro = 1; } } if ( ( sexo_aluno!= 'F' ) && ( sexo_aluno!= 'M' ) ) { printf ( dados errados\n" ); chave_erro = 1; }

// fazendo os calculos if ( chave_erro == 0 ) { // calculando media do aluno media_aluno = ( 2.0 * nota1 + 3.0 * nota2 ) / 5.0; // calculando conceito do aluno if ( media_aluno < 50.0 ) conceito = 'R'; else if ( media_aluno < 70.0 ) conceito = 'A'; else if ( media_aluno < 90.0 ) conceito = 'B'; else conceito = 'E'; // imprimindo dados aluno printf ( "aluno: %s\n", nome_aluno ); printf ( " nascimento: %2d %2d %4d - sexo: %c - nota1 = %3d nota2 = %3d media = %7.2f conceito %c\n", dia_nascimento, mes_nascimento, ano_nascimento, sexo_aluno, nota1, nota2, media_aluno, conceito ); // quantidade de meninas com conceito E if ( sexo_aluno == 'F' && conceito == 'E' ) q_fe++;

// quantidade de meninos com conceito A ou B if ( ( sexo_aluno == 'M') && ( conceito == 'A' conceito == 'B' ) ) q_mab++; // somatorio das notas da classe soma_medias_classe += media_aluno; // somatorio das notas dos meninos e meninas if ( sexo_aluno == 'M' ) { q_m++; soma_medias_meninos += media_aluno; } else { soma_medias_meninas += media_aluno; q_f++; } // quantidade de meninas que nasceram entre 10 e 20 de outubro if (( sexo_aluno == 'F' ) && ( dia_nascimento >= 10 && dia_nascimento <= 20 && mes_nascimento == 10 )) q_f1020 ++; // quantidade de meninos nascidos em fevereiro com conceito R if ( sexo_aluno == 'M' && mes_nascimento == 2 && conceito == 'R' ) q_mr++;

// somatorio de alunos nos conceitos if ( conceito == 'R' ) q_r++; else if ( conceito == 'A' ) q_a++; else if ( conceito == 'B' ) q_b++; else q_e++; // quantidade de alunos q_alunos++; } // entrada dos demais registros fscanf ( arq_dados, "%d %d %d %c %s %d %d", &dia_nascimento, &mes_nascimento, &ano_nascimento, &sexo_aluno, nome_aluno, &nota1, &nota2 ); } // fim_equanto

// saidas pedidas printf ( "quantidade de alunos na sala: %3d\n", q_alunos ); if ( q_m > 0 ) printf ( "media dos meninos = %10.2f\n", soma_medias_meninos / q_m ); else printf ( "a classe nao tem meninos\n " ); if ( q_f > 0 ) printf ( "media das meninas = %10.2f\n", soma_medias_meninas / q_f ); else printf ( "a classe nao tem meninas\n " ); printf ( "percentagem de alunos com conceito A = %10.2f\n", q_a * 100.0 / q_alunos ); printf ( "percentagem de alunos com conceito B = %10.2f\n", q_b * 100.0 / q_alunos ); printf ( "percentagem de alunos com conceito R = %10.2f\n", q_r * 100.0 / q_alunos ); printf ( "percentagem de alunos com conceito E = %10.2f\n", q_e * 100.0 / q_alunos ); printf ( "quantidade de meninos nascidos em fevereiro com conceito R = %d\n", q_mr ); printf ( "quantidade de meninas com conceito E = %d\n", q_fe ); printf ( "quantidade de meninas nascidas entre 10 e 20 de outubro = %d\n", q_f1020 ); printf ( "quantidade de meninos com conceito A ou B = %d\n", q_mab ); } // FIM DO PROGRAMA

Treinamento 1) Refaça o programa a seguir para salvar os valores das expressões em um arquivo binário. #define max(a,b) ((A>B)? (A):(B)) #define min(a,b) ((A<B)? (A):(B)) #define sqr(x) x*x void main() { int a = 100, b = 250, minimo, maximo, quad z = 4; minimo = min(a,b); maximo = max(a++,b++); quad = sqr(z+1); }

Treinamento 2) Escrever um programa em linguagem C para o cálculo da resistência equivalente em uma associação em série ou em paralelo. Neste programa, o usuário deverá informar o número de resistores, o valor de cada resistor e o tipo de associação (em série ou em paralelo). O cálculo da resistência equivalente deverá ser realizado por duas funções (uma para série e outra para paralelo). Para este programa devem ser implementadas 4 soluções, a saber: Funções precedendo o programa principal, no mesmo arquivo;

Treinamento Funções sucedendo o programa principal, no mesmo arquivo; Funções em arquivo separado, chamadas diretamente do programa principal; Funções em arquivo separado, usando projeto da seguinte forma: O arquivo princ.c, que conterá o programa principal; O arquivo func.c, que conterá as funções; O arquivo func.h, que conterá os protótipos das funções.

Treinamento http://br.spoj.com/problems/encotel/ http://br.spoj.com/problems/placar/