CHAPTER ONE. Elementos de organização de arquivos. Histórico

Tamanho: px
Começar a partir da página:

Download "CHAPTER ONE. Elementos de organização de arquivos. Histórico"

Transcrição

1 / EDOA / 1 CHAPTER ONE Elementos de organização de arquivos Histórico Os primeiros projetos de arquivos assumiam que os arquivos estariam em fitas, o acesso era sequencial e o custo do acesso era diretamente proporcional ao tamanho do arquivo Arquivos cresceram de modo intolerável para acesso sequencial Dispositivos como disco e tambores apareceram, o que permitiu a associação de índices aos arquivos. Índices permitiram guardar uma lista de chaves/ponteiros em um arquivo menor. O arquivo de índices podia ser pesquisado mais rapidamente, dado chave e ponteiro a informação do arquivo principal era obtida diretamente. Mas índices simples resultam no mesmo problema quando crescem demais e tornam-se difíceis de manter, principalmente, com arquivos dinâmicos onde as chaves mudam todo o tempo. No início dos anos 60 surgiu a idéia de aplicar árvores como solução, mas árvores podem crescer desigualmente conforme as chaves são inseridas e removidas. Em 1963 foram desenvolvidas as árvores AVL que são ótimas para estruturar dados em RAM. Pesquisadores pensaram em utilizar algo parecido para a estrutura de arquivos. Mas, o problema era que mesmo árvores perfeitamente balanceadas exigem muitos acessos para se chegar a um dado registro. Era, portanto, necessário encontrar um mecanismo de armazenar em cada nó da árvore um bloco de arquivo contendo o máximo número de registros. Mais de dez anos se trabalho foram necessários para chegar-se à solução das B-trees. Um problema era que a metodologia requerida para arquivos era muito diferente da utilizada em RAM. Árvores AVL crescem de cima para

2 / EDOA / 2 baixo enquanto que árvores B crescem de baixo para cima! Árvores B permitiram uma excelente performance ao custo de não se poder acessar sequencialmente o arquivo de modo eficiente. A solução quase imediata foi encontrada com a adição de uma lista encadeada no nível inferior da árvore B. Nesse caso chamada de árvore B+. Em termos práticos, árvores B garantem acesso a um registro em um arquivo com milhões de entradas em três ou quatro acessos ao disco. Por mais de dez anos essas árvores formaram a base para a maioria dos sistemas comerciais. A capacidade de acessar um registro em 3 ou 4 acessos é muito bom mas o objetivo ideal era precisar de apenas 1 acesso. Hashing é uma boa maneira de obter isso para arquivos que não mudam de tamanho. Há muito tempo índices e hashing são combinados para acesso a arquivos estáticos É relativamente recente a técnica de hashing dinâmico, a qual pode ser aplicada a arquivos dinâmicos eficientemente. CHAPTER TWO Armazenamento Computadores precisam de dispositivos que armazenem informações de forma não volátil (isto é, permanecem mesmo depois de desligados) e que permitam a inclusão, exclusão ou modificação das informações quando necessário. Sem isso, pouca utilidade teriam. Embora existam dispositivos eletrônicos que operam de forma similar (memória flash), o custo ainda é alto para as capacidades necessárias e parece que a tecnologia dos discos rígidos ainda deve permanecer por algum tempo. O primeiro dispositivo de disco rígido foi desenvolvido pela IBM em Tinha cerca de 5 MB de capacidade e usava 50 discos de 24 polegadas de diâmetro. Considerando que as unidades atuais usam apenas alguns discos de 3 1/2 polegadas e podem armazenar 80 GB ou mais, é possível notar que a evolução foi realmente muito grande. Organização de arquivos O armazenamento de pequenos volumes de dados, via de regra, não encerra

3 / EDOA / 3 grandes problemas no que diz respeito à distribuição dos registros dentro de um arquivo, desde que a freqüência de acessos aleatórios a registros não seja muito elevada. A medida que cresce o volume de dados e/ou a freqüência e a complexidade dos acessos, crescem também os problemas de eficiência do armazenamento dos arquivos e do acesso a seus registros, sendo a sofisticação das técnicas de armazenamento e recuperação de dados uma conseqüência da necessidade de acesso rápido a registros pertencentes a grandes arquivos ou, simplesmente, arquivos muito solicitados. A maneira intuitiva de armazenar um arquivo consiste na distribuição dos seus registros em uma ordem arbitrária, um após o outro, dentro da área destinada a contê-lo. Esta ordem pode ser, por exemplo, aquela na qual os registros são gerados. Isto causa uma dificuldade na localização dos registros e uma perda de eficiência, porém esta técnica intuitiva é bastante usada, principalmente durante as fases preliminares da geração de um arquivos. Terminologia Um arquivo é formado por uma coleção de registros lógicos, cada um deles representando um objeto ou entidade. Um registro lógico, ou simplesmente registro, é formado por uma seqüência de itens, sendo cada item chamado campo ou atributo. Cada item corresponde a uma característica ou propriedade do objeto representado. Cada campo possui um nome, um tipo e um comprimento. O comprimento dos valores de um atributo pode ser constante para todos os registros do arquivo, ou variável. O armazenamento de um arquivo é feito, via de regra, por blocos de registros lógicos (um bloco é chamado registro físico), sendo, em cada leitura ou gravação, lido ou gravado todo um bloco e não apenas um registro lógico. Uma chave é uma seqüência de um ou mais campos em um arquivo. Uma chave primária é uma chave que apresenta um valor diferente para cada registro do arquivo, de tal forma que, dado um valor da chave primária, é identificado um único registro do arquivo. Usualmente a chave primária é formada por um único campo. Uma chave secundária difere de uma primária pela possibilidade de não possuir um valor diferente para cada registro. Assim, um valor de uma chave secundária identifica um conjunto de registros.

4 / EDOA / 4 Chave de acesso é a chave utilizada para identificar o(s) registro(s) desejado(s) em uma operação de acesso a um arquivo. Argumento de pesquisa é o valor da chave de acesso em uma operação. Chave de um registro é o valor de uma chave primária em um particular registro do arquivo Chave de ordenação é a chave usada para estabelecer a seqüência na qual devem ser dispostos (física ou logicamente) os registros de um arquivo. CHAPTER THREE Manipulação de dados Arquivo Físico: quando nos referimos a um dado arquivo em disco, nos referimos a uma sequência particular de bytes armazenados no disco. Um disco pode conter centenas ou milhares de arquivos físicos. Arquivo Lógico: é o arquivo visto do ponto de vista da aplicação. Cada arquivo manipulado pela aplicação é tratado como se um canal de comunicação (uma linha telefônica?) estivesse estabelecido entre a aplicação e o arquivo em disco. Apesar de um disco poder conter milhares de arquivos físicos, uma aplicação é limitada a utilizar cerca de 20 arquivos lógicos simultaneamente. É de responsabilidade do sistema operacional tomar conta desse "sistema telefônico". Um arquivo lógico utilizado por uma aplicação pode estar associado a um arquivo físico em disco, ou ao teclado(e), ao vídeo (S), ou outro dispositivo de E/S qualquer. Antes de uma aplicação poder abrir um arquivo, o sistema operacional deve ser informado de que modo a associação deve ser feita. A maneira como isso é feita varia de sistema para sistema e de linguagem para linguagem. Por exemplo, em Turbo Pascal o comando abaixo associa o arquivo físico meuarq.dat ao arquivo lógico arq a ser utilizado pela aplicação. assign(arq,'meuarq.dat')

5 / EDOA / 5 CHAPTER FOUR Streams Para uniformizar as primitivas através das quais um programa invoca as ações de I/O (entrada e saída de dados), a linguagem C++ virtualiza todos os dispositivos envolvidos nestas ações como objetos streams. A linguagem C++ dispõe de uma biblioteca de classes stream, cujas declarações se situam nos arquivos iostream.h e fstream.h, satisfazendo ao paradigma da Programação Orientada a Objetos. A estrutura de comunicação com o meio externo em modo texto é composta por um conjunto de objetos. Estas, em conjunto com operadores e funções de formatação possibilitam uma forma de comunicação mais intuitiva. Devido à abstração de elementos do mundo real por recursos da orientação a objetos, a forma de entender o código torna-se mais natural. Na biblioteca iostream, temos os seguintes objetos: cin: Este objeto fornece entrada de dados "bufferizada" através do "standard input device", o dispositivo de entrada padrão; cout: Este objeto fornece saída de dados "bufferizada" através do "standard output device", o dispositivo de saída padrão; cerr: Este objeto fornece saída de dados não "bufferizada" para o standard error device, o dispositivo de erro padrão, que é inicialmente definido para a tela. clog: Este objeto fornece saída "bufferizada" através do "standard error device", o dispositivo de erro padrão que é inicialmente definido para a tela. O foco de orientação a objetos que a biblioteca iostream confere aos dispositivos de entrada e saída é uma das características da linguagem C++. Ele está presente na maneira na qual o código foi idealizado e está formatado, modificando a maneira como as partes do sistema de entrada/ saída interagem. Desta forma, as operações de interação entre o usuário e o software tornam-se mais intuitivas para o programador. O sistema de entrada e saída é um exemplo deste modelo de programação, onde cada entidade física ou lógica de entrada e saída é representada por objetos cujas operações podem ser acessadas diretamente nos programas.

6 / EDOA / 6 Elementos Buffer Bufferização é um meio de sincronização entre dispositivos de velocidades diferentes, tais quais memória e dispositivos de armazenamento mecânicos, como discos magnéticos. Para evitar que as operações do dispositivo mais lento interfiram no desempenho do programa, pode-se fazer com que os dados sejam colocados em uma memória mais rápida e depois sejam enviadas ao dispositivo mais lento a medida que ele tenha disponibilidade para recebê-los, desta forma temos os seguintes modos de escrita em dispositivos de saída: unbuffered. Significa que qualquer mensagem ou dados serão escritos imediatamente. É o caso da escrita no dispositivo cerr; buffered. Significa que os dados serão mantidos num buffer de memória até que o dispositivo de destino solicite, ou que um comando de descarregamento seja executado, ou quando o buffer estiver cheio. O problema é que se o programa é interrompido antes do buffer ser escrito esses dados são perdidos. cout O cout, usado em conjunto com o operador de inserção <<, permite enviar dados para o "stream out" que por definição é o monitor. cout << "hello"; cout << 120; // mostra a palavra hello no monitor // mostra o número 120 no monitor cout << hello; // mostra o conteúdo do pedaço de memória a que chamamos de "hello" no monitor cout << "hello, tenho " << age<< " anos de idade"; /* mostra a primeira string depois cout << "Primeira frase. "; */ vai buscar o conteúdo da variável age de depois a string anos de idade cout << "Segunda frase.\n" << "Terceira frase."; /* imprime:

7 / EDOA / 7 */ Primeira frase. Segunda frase. Terceira frase. Uma característica muito importante do C++, presente nas instruções logo acima, é o polimorfismo notável na operação de apresentação dos dados na saída; Note que os tipos de dados que são passados para o cout são diversos, ou seja, não importa qual o tipo de dado que será entregue ao cout, de alguma maneira ele sempre formatará de uma maneira legível no monitor. Nos capítulos mais adiante veremos como fazer com que tipos de dados diferentes sejam tratados pelo mesmo objeto. Escape sequences A um conjunto de caracteres, nós chamamos de string. Mas no exemplo anterior quando usamos o "\n", nós antes dissemos que o cout com o operador << iria colocar no monitor todos os caracteres que estivessem entre aspas. Acontece que existem estas stings especiais chamadas de "escape sequences" - que de alguma forma alteram o sentido das strings. Existem muitas destas sequências. As mais conhecidas são estas: cin O objecto cin obtém informação do "standard input" (que usualmente é o teclado). Este objecto está tal como o cout declarado no cabeçalho da biblioteca <iostream> A sintaxe mais comum da instrução para obter dados do cin é: cin >> [variable name]; Aqui temos o operador de extracção ">>" que diz que tudo o que o teclado escrever, coloque esses dados na variável que me segue. Este operador consegue até traduzir o conceito de dados de fora para dentro. #include <iostream> using namespace std; int main(void) { int testscore; cin >> testscore;

8 / EDOA / 8 cout << "Your test score is " << testscore << "\n"; return 0; } Há mais um pormenor. O computador está à espera de um "Return" ("ENTER", ou "New Line", ou Espaço em Branco ) para finalizar a entrada de dados na variável, até lá o cursor permanece intermitente. Pergunta: declaramos uma variável int testscore e se colocarmos um valor que não seja um int? Assim, se no exemplo anterior colocarmos o nome Jeff, que é uma string, e o programa está a espera de um int, o que acontece é que o cin não vai colocar "jeff" na variável (ele ignora a entrada). e quando o cout é chamado ele vai colocar o valor que está na variável. Então porque é que me apareceu o número quando executei o programa? É que na memória física do computador existem dados da área onde a variável está alocada fisicamente, e quando declarei o testscore o compilador apenas reserva aquela memória mas não apaga o que lá está. Pergunta: O que é que acontece quando inserimos um número maior do que o limite da tipologia quando o programa está a executar? É o caso de "overflow" - estouro de memória, mas quando o programa corre/roda. Aqui já não temos a questão de dar a volta ao intervalo permitido, aqui temos o caso em que vai ser colocado um número estranho. Isto não está perfeitamente explicado. De uma maneira muito conveniente, os dados recebidos pelo cin são tratados de forma a tornar o processo polimórfico, da mesma forma que no caso do cout, assim temos como receber os dados da maneira que precisamos, ou seja, quando declaramos uma variável int e a usamos para receber um dado do cin, o mesmo é convertido na entrada para inteiro, quando usamos uma variável de outro tipo, a entrada é convertida para o tipo da variável. Lendo um caractere Ler um caractere até é simples, basta utilizar o objeto cin e será guardado o valor digitado na variável. char nivel; cout << "Entre um nível: ";

9 / EDOA / 9 cin >> nivel; Porém teremos de pressionar a tecla ENTER depois de digitar o caractere. Isto leva a várias questões. O problema pressione uma tecla para continuar... #include <iostream> using namespace std; int main(void) { char ch; do { "; cout << "Pressione S ou s para sair, qualquer outra tecla para continuar: } cin >> ch; if (ch!= 'S' && ch!= 's') cout << "Desaja continuar?"<<endl; else cout << "Saindo..."<<endl; } while (ch!= 'S' && ch!= 's'); return 0; O programa funciona bem se pressionarmos S ou s para sairmos; O programa funciona bem se pressionarmos qualquer outra tecla com caractere imprimível; Mas se pressionarmos a tecla ENTER, nada acontece, o cin continua à espera de entrada. a razão é o operador de extração >> ignorar os espaços em branco e os caracteres "nova linha" resultantes do pressionamento da tecla ENTER.

10 / EDOA / 10 A função cin.get() Esta função pode ser chamada, tal como a getline(), através de 3 argumentos, onde o primeiro é o array de caracteres, mas também o pode ser sem argumentos ou ainda apenas um argumento. No caso de não conter argumentos apenas irá ler um caracter, em vez de uma cadeia de caracteres. No caso de ter um argumento, ela aceita qualquer tecla incluindo o enter. (o que não se passa com o cin e o operador de extração). Aqui um exemplo #include <iostream> using namespace std; int main(void) { char ch; do { cout << "Pressione S ou s para sair, \nqualquer outra tecla para continuar: "; } cin.get(ch); if (ch!= 'S' && ch!= 's') cout << "Deseja continuar?" << endl; else cout << "Saindo..." << endl; } while (ch!= 'S' && ch!= 's'); return 0; Porém se pressionarmos uma tecla de caractere imprimível, não conseguiremos inserir o próximo prompt, parece que houve um salto. Estranho! Para explicar a razão deste novo problema necessitamos de explicar o conceito de buffer.

11 / EDOA / 11 O "input buffer" é uma área de memória que guarda os caracteres de entrada, por exemplo do telado, até que essa entrada seja atribuída pelo cin e o operador de extracção >>, ou por funções como get() ou getline() do objecto cin. Quando o loop começa, o "input buffer" está vazio. Se digitarmos apenas o enter, sendo este o primeiro e único caractere no "imput buffer", ele é removido do input buffer e atribuído á variavel ch, então o "input buffer" está vazio na próxima iteração do loop; Se digitarmos x e enter. Temos 2 caracteres. A função get() retira o primeiro c1aráctere do "input buffer" e atribui á variavel ch, mas nisto o caractere nova linha permanece no "input buffer". Isto faz com que na próxima iteração do loop, não haja a oportunidade para entrar com dados. Ou seja, na segunda iteração, é retirado o caractere nova linha que ficou da 1ª iteração - e é colocado na variável ch. Agora o "input buffer" está vazio. cin.ignore() Uma solução é limpar o caractere nova linha do "input buffer" antes da chamada da função getline(). E fazemos isso usando a função ignore() do objecto cin. Esta função membro tal com a get() e a getline() são sobrecarregadas, podem ser chamadas sem argumentos, com um ou dois argumentos. Utilizar a função ignore() sem argumentos, permite que o próximo caractere no "input buffer" seja lido e depois descartado,- e isto é exactamente aquilo que queríamos. A função com 1 ou 2 argumentos é usada para cadeias de caracteres. Com um argumento, o argumento é o número máximo de caracteres a ser removido do "input buffer". Exemplo: cin.ignore(80); // Remove até 80caracteres do input buffer Com dois argumentos, o segundo argumento é o delimitador, um caractere que se encontrado, antes do número de caracteres especificado no primeiro paramento, faz com que a remoção pare. Exemplo: cin.ignore (80, '\n'); // Remove 80 caracteres se até lá não encontrar o nova linha. Reescrevendo o código anterior utilizando o cin.ignore()

12 / EDOA / 12 #include <iostream> using namespace std; int main(void) { char ch; do { cout << "Pressione S ou s para sair,\n qualquer outra tecla para continuar: "; cin.get(ch); cin.ignore(); if (ch!= 'S' && ch!= 's') cout << "Deseja continuar?"<<endl; else cout << "Saindo..."<<endl; } while (ch!= 'S' && ch!= 's'); } return 0; Se pressionarmos a tecla Enter para continuar, teremos de fazer isso duas vezes, pois a primeira vez é ignorada. A razão: é que não existe nada no "input buffer" quando a função ignore é chamada, por isso é que a tecla enter necessita de ser pressionada 2 vezes, colocando um caractere nova linha a mais no "buffer" para a função ignore() remover. Se tentarmos modificar isto através do if? #include <iostream> using namespace std; int main(void) {

13 / EDOA / 13 char ch; do { cout << "Pressionar S ou s para sair,\n qualquer outra tecla para continuar: "; } cin.get(ch); if (ch!= '\n') cin.ignore(); if (ch!= 'S' && ch!= 's') cout << "Deseja continuar?"<<endl; else cout << "Saindo..."<<endl; } while (ch!= 'S' && ch!= 's'); return 0; Agora sim temos todos os problemas resolvidos e isto agora funciona!! O problema anterior do caractere nova linha permanece quando usamos o cin, o get() e o getline() juntos num programa, uma vez que o enter é usado para terminar a entrada. #include <iostream> using namespace std; int main(void) { char name[80]; int coursenum; cout << "Informe o número do curso: "; cin >> coursenum; cout << "Informe seu nome: "; cin.getline(name, 80);

14 / EDOA / 14 cout << "O número do curso é: " << coursenum << endl; cout << "Seu nome é: " << name << endl; return 0; } Aqui, neste exemplo, nós não tivemos a oportunidade de colocar o nome. Quando digitamos o número e depois pressionamos a tecla enter, o cin coloca o número no coursenum mas permanenece o caractere nova linha no "input buffer", que fica para o enter name, pois o getline lê espaços em branco. A solução pode ser: #include <iostream> using namespace std; int main(void) { char name[80]; int coursenum; cout << "Informe o número do curso: "; cin >> coursenum; cin.ignore(); cout << "Informe seu nome: "; cin.getline(name, 80); cout << "O número do curso é: " << coursenum << endl; cout << "Seu nome é: " << name << endl; return 0; }

15 / EDOA / 15 A partir destes exemplos podemos criar umas regras: Colocar sempre a função ignore() depois do cin e do >>; Razão: O "cin>>" deixa sempre o nova linha no "input buffer". Assim devemos eliminá-lo com a função ignore(). Não colocar a função ignore(), no caso de ser sem parâmetros, depois do getline(); Razão:O getline() remove o caractere nova linha que termina a entrada do "input buffer", portanto não é necessário o ignore(). Verificar se temos o caractere nova linha no "input buffer" depois de utilizar o get(), se tivermos deveremos utilizar o ignore(). Razão: A função get() com um argumento deixa o caractere nova linha no "input buffer" se pressionarmos um caractere e o enter. mas não deixará, se apenas pressionarmos o enter. portanto é necessário confirmar. [editar]entrada de valores para variáveis múltiplas Podemos fazer com que o programa receba vários valores ao mesmo tempo cin >> [first variable] >> [second variable] >> [third variable]; Neste caso o usuário separa os dados por espaços (o enter também dá) e como anteriormente o usuário fecha utilizando o enter #include <iostream> #include <string> using namespace std; int main(void) { int peso, altura; string nome; cout << "escreva o seu nome, peso e altura \n separe os valores por espaços\n"; cin >> nome >> peso >> altura;

16 / EDOA / 16 cout << "o seu nome é:" << nome << "\n"; cout << "o seu peso é:" << peso << "\n"; cout << "a sua altura é: " << altura<< "\n"; return 0; } Note-se que no exemplo anterior poderíamos colocar as 3 variáveis mesmo no caso de elas serem de tipologias diferentes. Temos é de ter atenção é á ordem de entrada. Arquivos sequenciais Ao construir uma estrutura de arquivo, estamos impondo uma organização aos dados. Inicialmente veremos um arquivo organizado como uma sequência de bytes. Considere um arquivo construído para armazenar nomes e endereços. O programa aceita nomes e endereços entrados via teclado, e os escreve como uma sequência (stream) de bytes consecutivos em um arquivo (ou seja, sem delimitadores, counts, ou qualquer outra informação para distinguir campos e registros). A escrita é feita como uma sequencia de caracteres sem qualquer informação adicional Uma vez que as informações foram escritas, não existe como recuperar porções individuais (nome, cidade, cep, etc) Desta forma perde-se a integridade das unidades de organização fundamental dos dados fornecidos na entrada. Os dados eram agregações de caracteres com significado próprio. Tais agregados são chamados campos (fields). Um campo é a menor unidade lógica de informação em um arquivo, e é uma noção lógica, uma ferramenta conceitual, que não corresponde necessariamente a um conceito físico. No exemplo acima, ao escolher uma organização em stream, perdemos os campos que estruturam logicamente a informação em nomes e endereços. 1 #include <iostream> 2 #include <fstream>

17 / EDOA / 17 3 #include <cstdlib> 4 #include <string> 5 using namespace std; 6 int main() 7 {int numero; 8 string nome; 9 ofstream outfile; // outfile é o arquivo onde a saída será escrita outfile.open( saída.txt, ios::out); // abre o arquivo para escrita 12 if (! outfile) 13 { cout << Arquivo saida.txt nao pode ser aberto << endl; 14 abort(); 15 } cout << Entre com o numero e nome do funcionário\n 18 << Fim de arquivo (Ctrl-Z) termina a entrada de dados\n\n? ; 19 while(cin >> numero >> nome) 20 { outfile << numero << << nome << \n ; 21 cout <<? ; 22 } 23 outfile.close(); // se o programador omitir a chamada ao método close 24 return 0; // o finalizador se encarrega de fechar o arquivo 25 } Observe as operações básicas sobre arquivos de saída neste exemplo. Em primeiro lugar, foi declarada uma variável do tipo arquivo (linha 9) e a variável foi associada a um arquivo em disco, aberto para escrita (linha 11). O construtor do objeto ofstream permite que essas duas operações sejam

18 / EDOA / 18 realizadas em um único comando, ou seja os comandos: ofstream outfile; outfile.open( saída.txt, ios::out); são equivalentes ao único comando: ofstream outfile( saída.txt, ios::out); O primeiro parâmetro passado para o método open (ou ao construtor) é o nome do arquivo ( saída.txt ) e o segundo parâmetro é o modo de abertura do arquivo (ios::out). Para um objeto ofstream, pode-se utilizar, dentro outros, os seguintes modos de abertura: Modo ios::out ios::app ios::nocre ate ios::norepl ace ios::in ios::ate Descrição Cria e abre um novo arquivo; se o arquivo já existe, todos seus dados são apagados Abre um arquivo existente, posicionando o ponteiro do arquivo no final, permitindo adicionar linhas (os dados já existentes não são modificados) Se o arquivo não existe, a operação de abertura falha Se o arquivo existe, a operação de abertura falha Abre para leitura (default de ifstream) Abre e posiciona no final do arquivo (para leitura e gravação) ios::binary Abre em binário (default é texto) Por default, os objetos ofstream são abertos no modo ios::out, ou seja, o comando: ofstream outfile( saída.txt, ios::out); é equivalente ao comando: ofstream outfile( saída.txt ); Após criada uma variável do tipo ofstream e feita uma tentativa de abertura do arquivo, o programa testa se a operação de abertura teve sucesso (linhas

19 / EDOA / a 15): if (! outfile) { cout << Arquivo saida.txt nao pode ser aberto << endl; abort(); } O teste! outfile determina se a operação de abertura não teve sucesso. Nesse caso, uma mensagem de erro é fornecida e o programa interrompe sua execução. Alguns erros possíveis na abertura de arquivos consistem na falta de permissão ou quando não há mais espaço em disco. Em seguida (linhas 17 a 22), o programa solicita que o usuário entre com o número e nome de funcionários de uma empresa qualquer. A condição no comando while (linha 19) é: while(cin >> numero >> nome) Esta condição é verdadeira enquanto o usuário entrar com valores diferentes de final de arquivo. Em ambientes Dos/Windows o final de arquivo é a seqüência de teclas Ctrl-Z. Em ambientes Unix, é a seqüência Ctrl-D. Na linha 20 outfile << numero << << nome << \n ; os valores fornecidos pelo usuário são escritos no arquivo saída.txt utilizando o operador << e a variável associada outfile. Quando um final de arquivo é encontrado, o laço termina e então o comando (linha 23) outfile.close(); fecha o arquivo saida.txt. Entretanto, o finalizador do objeto ofstream realiza essa operação automaticamente. Assim, é possível omitir completamente a linha 23 e mesmo assim o arquivo será fechado. O arquivo saída.txt pode ser lido por qualquer editor de texto. Fechar um arquivo faz com que qualquer informação que tenha permanecido no buffer associado ao fluxo de saída seja gravada no disco. Quando você envia dados para serem gravados em um arquivo, eles são armazenados temporariamente em uma área de memória (buffer) ao invés de serem imediatamente escritos em disco. Quando o buffer estiver cheio, seu conteúdo é escrito no disco de uma vez pelo sistema operacional. A razão para efetuar isso se deve à eficiência na leitura e escrita de arquivos. Se, para cada dado que fosse ser gravado, o sistema operacional tivesse que posicionar a cabeça de leitura/gravação em um ponto específico do disco, apenas para gravar aquele dado, as gravações seriam muito lentas. Assim, estas gravações só são efetuadas quando há um volume razoável de informações a serem gravadas ou quando o arquivo for

20 / EDOA / 20 fechado. Em C++ é possível forçar a gravação dos dados em disco utilizando endl (end line = fim de linha),ou seja, endl além inserir um caracter de fimde-linha ( \n ) ele descarrega (ou esvazia) (flush) o buffer de saída no mesmo, mesmo que ele não esteja cheio. O buffer de saída também pode ser descarregado pelo do comando: outfile << flush; Como observação final, os comandos das linhas poderiam ser substituídos pelo seguinte fragmento de código equivalente: cin >> numero >> nome; // ler dados while(! cin.eof()) { outfile << numero << " " << nome << '\n'; // final de dados? cout << "? "; cin >> numero >> nome; // ler proximos dados } Resumo das operações básicas sobre arquivos seqüenciais para escrita: Abrir: ofstream arquivo( nome-do-arquivo ); Escrever: arquivo << valor1 << << valor2 <<... << endl; Esvaziar o buffer: arquivo << flush; ou arquivo << endl; Teste de fim-de-arquivo: arquivo.eof(); Fechar (opcional): arquivo.close(); Criar um fluxo usando o modo ifstream significa criar um arquivo de entrada e criar um fluxo usando-se ofstream implica criar um arquivo de saída. Por este motivo, ainda que seja inteiramente apropriado abrir um arquivo usando a função open(), na maioria das vezes, você não irá usá-la, já que as classes ifstream, ofstream e fstream têm funções construtoras que abrem um arquivo automaticamente. Lendo dados de um arquivo seqüencial Os dados armazenados em arquivos podem ser recuperados quando necessários. Na seção anterior, foi criado o arquivo seqüencial saída.txt contendo o número e o nome de funcionários de uma empresa. Nesta seção, veremos como ler os dados armazenados em um arquivo seqüencial, por meio do seguinte exemplo: 1 #include <iostream> 2 #include <fstream>

21 / EDOA / 21 3 #include <cstdlib> 4 #include <iomanip> 5 #include <string> 6 using namespace std; 7 int main() 8 { int numero; 9 string nome; 10 ifstream infile; // infile é o arquivo de leitura dos dados infile.open( saída.txt, ios::in); // abre o arquivo para leitura 13 if (! infile) 14 { cout << Arquivo saida.txt nao pode ser aberto << endl; 15 abort(); 16 } cout << setiosflags(ios::left) 19 << setw(10) << Numero 20 << setw(50) << Nome << endl; 21 while(infile >> numero >> nome) 22 cout << setiosflags(ios::left) 23 << setw(10) << numero 24 << setw(50) << nome << endl; infile.close(); // se o programador omitir a chamada ao método close 27 return 0; // o finalizador se encarrega de fechar o arquivo

22 / EDOA / } Em primeiro lugar, foi declarada uma variável do tipo arquivo (linha 10) e a variável foi associada a um arquivo em disco, aberto para leitura (linha 12). O construtor do objeto ifstream permite que essas duas operações sejam realizadas em um único comando, ou seja os comandos: ifstream infile; infile.open( saída.txt, ios::in); são equivalentes ao único comando: ifstream infile( saída.txt, ios::in); O primeiro parâmetro passado para o método open (ou ao construtor) é o nome do arquivo ( saída.txt ) e o segundo parâmetro é o modo de abertura do arquivo (ios::in). Por default, os objetos ifstream são abertos no modo ios::in, ou seja, o comando: ifstream infile( saída.txt, ios::in); é equivalente ao comando: ifstream infile( saída.txt ); Após criada uma variável do tipo ifstream e feita uma tentativa de abertura do arquivo, o programa testa se a operação de abertura teve sucesso (linhas 13 a 16): if (! infile) { cout << Arquivo saida.txt nao pode ser aberto << endl; abort(); } O teste! infile determina se a operação de abertura não teve sucesso. Nesse caso, uma mensagem de erro é fornecida e o programa interrompe sua execução. Alguns erros possíveis na abertura de arquivos consiste na falta de permissão ou quando o arquivo não existe. Em seguida (linhas 18 a 24), o programa lê os dados do arquivo. A condição no comando while (linha 21) é: while(infile >> numero >> nome) Esta condição é verdadeira enquanto o programa ler valores diferentes de final de arquivo.. Quando um final de arquivo é encontrado, o laço termina e então o comando (linha 26) infile.close();

23 / EDOA / 23 fecha o arquivo saida.txt. Entretanto, o finalizador do objeto ifstream realiza essa operação automaticamente. Assim, é possível omitir completamente a linha 26 e mesmo assim o arquivo será fechado. Como observação final, os comandos das linhas 21 e 22 poderiam ser substituídos pelo seguinte fragmento de código equivalente: infile >> numero >> nome; // ler primeiro registro while(! infile.eof()) { cout << setiosflags(ios::left) << setw(10) << numero << setw(50) << nome << endl; infile >> numero >> nome; // ler próximo registro } O método eof() testa se foi atingido o final-de-arquivo (end-of-file). É importante salientar que este método somente pode ser chamado após realizado um comando de leitura (ou escrita) no arquivo e uma vez verdadeiro, ele permanece verdadeiro até a utilização do método clear(). Resumo das operações básicas sobre arquivos seqüenciais para leitura: Abrir: ifstream arquivo( nome-do-arquivo ); Ler: arquivo >> variavel1 >> variavel2 >>... ; Teste de fim-de-arquivo: arquivo.eof(); Fechar (opcional): arquivo.close(); Atualizando dados em um arquivo seqüencial Os dados escritos em arquivos seqüenciais não podem ser modificados sem o risco de destruir outros dados no arquivo. Por exemplo, suponha o seguinte arquivo: 100 Paulo 200 Mara 300 Pedro e que o nome Mara precise ser trocado para Marelise ; assim o nome antigo não pode ser simplesmente sobreposto. Se o registro para Mara for sobreposto na mesma localização no arquivo utilizando o nome mais longo, o registro ficaria 200 Marelise

24 / EDOA / 24 que contém quatro caracteres a mais que o registro original. Não esqueça que após cada registro existe apenas um \n, ou seja, o arquivo pode ser escrito como 100 Paulo\n200 Mara\n300 Pedro\n Portanto, os caracteres após o primeiro e em Marelise sobrescreveriam o início do próximo registro no arquivo, da seguinte forma: 100 Paulo\n200 Marelise Pedro\n O problema é que a entrada/saída formatada utilizando << e >> pode variar em tamanho. Por exemplo, embora 5, 10 e 2010 sejam inteiros (ocupando a mesma quantidade de bytes internamente), eles ocupam tamanhos diferentes quando escritos no formato texto em um arquivo em disco. Portanto, a entrada/saída formatada não é usualmente utilizada quando a atualização de registros é necessária. Se realmente for necessário, o processo de atualização requer que todos os registros antes daquele a ser atualizado sejam copiados para um novo arquivo; o novo registro então é escrito ao novo arquivo e, finalmente, os demais registros também devem ser copiados para o novo arquivo. Consultas em Arquivos Seqüenciais Um arquivo é um conjunto de registros, onde cada registro é formado por um ou mais campos. Por exemplo, os registros de um arquivo de funcionários poderiam incluir os seguintes campos: Número de matrícula Nome Cargo Grau de escolaridade Sexo (M,F) Local Estado civil (S, C) Salário Uma amostra de dados para um arquivo desse tipo pode ser:

25 / EDOA / 25 Regist ro > E# Nome Cargo Esc. Austin programad or Sex o Local E.C. Salário 2 F Campinas S Willian analista 3 M Campinas C Melissa analista 3 F Vinhedo S Hawkins Newton programad or programad or 2 M Campinas S M Vinhedo C 9000 Todo arquivo possui um ponteiro de arquivo (mostrado como ) que indica a posição do arquivo onde: Será efetuada a próxima leitura (caso seja utilizado um comando de leitura); Será efetuada a próxima escrita ou gravação (caso seja utilizado um comando de escrita/gravação) O objetivo principal da organização de arquivo é proporcionar meios para a recuperação e atualização dos registros. A atualização de um registro pode incluir sua eliminação, a alteração de alguns de seus campos ou a inserção de um registro completamente novo. Normalmente, alguns campos do registro são reservados como campos-chave. Os registros podem ser recuperados especificando os valores de alguns ou todas essas chaves. Um combinação de valores de chave, especificada para recuperação, é denominada consulta. Supondo que no exemplo anterior os campos Número de Matrícula, Cargo, Sexo e Salário foram designados como campos-chave. Algumas consultas válidas ao arquivo são: Recupere os registros de todos os funcionários com: Q1: Sexo = M Q2: Salário > 9000 Q3: Salário > média dos salários de todos os funcionários Q4: (Sexo = F and Cargo = Programador ) or (Matricula > 700 and Sexo = M ) Note que uma consulta do tipo Locação = Vinhedo seria inválida, já que o

26 / EDOA / 26 campo de locação não foi especificado como campo-chave. Os exemplos Q1-Q4 são representativos de tipos de consultas que se poderia fazer. Os quatro tipos de consultas são: Q1: Consulta simples: especifica-se o valor de uma chave única Q2: Consulta em intervalo: especifica-se um intervalo de valores para uma chave única Q3: Consulta funcional: especifica-se alguns valores determinados dentro do arquivo (exemplo: soma, média, desvio-padrão) Q4: Consulta booleana: uma combinação booleana de Q1-Q3 utilizando os operadores lógicos and, or e not. É possível efetuar consultas dos tipos Q1-Q4 em arquivos seqüenciais. Nesse caso, os programas normalmente começam a leitura a partir do início do arquivo, lêem todos os registros consecutivamente até que um registro específico seja encontrado. Pode ser necessário processar um arquivo seqüencial várias vezes (a partir do começo dele) durante a execução do programa. Ambas classes ifstream e ofstream possuem métodos para reposicionar o ponteiro de arquivo. Os métodos são seekg (seek get) para ifstrem e seekp (seek put) para ofstream. Cada objeto ifstream possui seu próprio ponteiro de arquivo que indica o byte no arquivo a partir do qual a próxima leitura será efetuada; cada objeto ofstrem também possui seu próprio ponteiro de arquivo que indica o byte no arquivo a partir do qual a próxima escrita será efetuada. O comando: infile.seekg(0); reposiciona o ponteiro de arquivo para o começo do arquivo (byte 0). O parâmetro de seekg é normalmente um long int indicando a quantidade de bytes. Um segundo parâmetro pode ser especificado para indicar a direção do posicionamento: ios::beg (default) para posicionar relativamente a partir do começo do arquivo; ios::cur para posicionar relativamente à posição atual do ponteiro de arquivo e ios::end para posicionar relativamente ao final do arquivo. Por exemplo: // posiciona no n-ésimo byte de infile (assume ios::beg) infile.seekg(n) // posiciona no n-ésimo byte à frente do ponteiro de arquivo de infile infile.seekg(n, ios::cur) // posiciona no y-ésimo byte a partir do final do arquivo infile (de trás para frente)

27 / EDOA / 27 infile.seekg(y, ios::end) // posiciona no final do arquivo infile infile.seekg(0, ios::end) O método seekp é utilizado de forma análoga. Adicionalmente, existem os métodos tellg e tellp que retornam a posição atual do ponteiro do arquivo onde a próxima leitura ou escrita ocorrerá, respectivamente. O programa seguinte implementa a consulta do tipo Q1, permitindo que o usuário escolha qual o sexo dos funcionários a serem listados. 1 #include <iostream> 2 #include <fstream> 3 #include <cstdlib> 4 #include <iomanip> 5 #include <string> 6 using namespace std; 7 struct funcionario // estrutura do registro de funcionário 8 { int matricula; 9 string nome; 10 string cargo; 11 int escolaridade; 12 char sexo; 13 string local; 14 char ecivil; // estado civil 15 float salario; 16 }; int main() 19 { funcionario f;

28 / EDOA / char sexo; 21 ifstream funcfile("func.dat"); if (! funcfile) 24 { cout << "Arquivo func.dat nao pode ser aberto" << endl; 25 abort(); 26 } cout << "\n\nsexo dos funcionarios a serem listados (M ou F) Ctrl-Z termina? "; 29 while (cin >> sexo) 30 { cout << "Consulta funcionario com sexo = " << sexo << endl; 31 cout << setiosflags(ios::left) 32 << setw(10) << "Matricula" 33 << setw(10) << "Nome" 34 << setw(15) << "Cargo" 35 << setw(5) << "Esc." 36 << setw(5) << "Sexo" 37 << setw(10) << "Local" 38 << setw(5) << "E.C." 39 << setw(10) << "Salario" << endl; funcfile.clear(); // limpa "eof = final de arquivo" para proximo uso 42 funcfile.seekg(0); // posiciona no inicio do arquivo 43 funcfile >> f.matricula >> f.nome >> f.cargo >> f.escolaridade 44 >> f.sexo >> f.local >> f.ecivil >> f.salario; // ler primeiro registro

29 / EDOA / while (! funcfile.eof()) 46 { if(f.sexo == sexo) // o registro atende a condição de consulta? 47 cout << setiosflags(ios::left) 48 << setw(10) << f.matricula 49 << setw(10) << f.nome 50 << setw(15) << f.cargo 51 << setw(5) << f.escolaridade 52 << setw(5) << f.sexo 53 << setw(10) << f.local 54 << setw(5) << f.ecivil 55 << setw(10) << f.salario << endl; 56 funcfile >> f.matricula >> f.nome >> f.cargo >> f.escolaridade 57 >> f.sexo >> f.local >> f.ecivil >> f.salario; // ler próximo registro 58 } 59 cout << "\n\nsexo dos funcionarios a serem listados (M ou F) Ctrl-Z termina? "; 60} 61 return 0; 62 } Nas linhas 7-16 é definida a estrutura de dados na qual as informações de um funcionário serão colocadas. Na linha 21, o arquivo func.dat é aberto para leitura. Na linha 29, o usuário fornece qual o sexo que ele deseja consultar no arquivo de funcionários (M ou F). Na linha 41, o flag de final de arquivo é limpo, caso contrário uma vez ele sendo verdadeiro ele permanece verdadeiro. Na linha 42, o ponteiro de arquivo é posicionado no começo do arquivo. Nas linhas é lido o primeiro registro do arquivo e logo a seguir na linha 45 é verificado se o final de arquivo (eof = end-of-file) foi atingido. Lembre-se que antes de testar pelo final de arquivo é necessário efetuar pelo menor um comando de leitura que altera o valor do flag de final de arquivo para seu valor adequado. Na linha 46 encontra-se o

30 / EDOA / 30 critério de seleção de registros, ou seja, o critério da consulta; caso ele seja satisfeito, o registro é exibido na tela (linhas 47-55). Em seguida, nas linhas o próximo registro do arquivo é lido para continuidade do loop na linha 45. Ao encontrar o final de arquivo, o processamento termina e o programa solicita ao usuário (linha 59) novamente qual o sexo dos funcionários a serem listados para continuidade do loop na linha 29. Ao digitar Ctrl-Z, o programa termina. Fica como exercício a implementação das consultas Q2-Q4. Arquivos binários Arquivos seqüenciais são inadequados para aplicações ditas de acesso instantâneo. Algumas aplicações típicas de acesso instantâneo são os sistemas de reservas de vôos, sistemas de ponto-de-venda, caixas automáticos, sistemas bancários e outros tipos de sistemas de processamento de transações que requerem acesso rápido a um dado específico. Por exemplo, no banco onde você possui sua conta corrente, mesmo quando você utiliza um caixa automático, sua conta é verificada se possui fundos em alguns segundos. Este tipo de acesso instantâneo é possível através dos arquivos de acesso aleatório. Os registros individuais em um arquivo de acesso aleatório podem ser acessados direta e rapidamente sem ser necessário procurar em todos os registros. C++ não impõe estrutura para arquivos. Assim, a aplicação que deseja fazer uso de arquivos de acesso aleatório deve literalmente criá-los. Uma variedade de técnicas pode ser utilizada para criar arquivos de acesso aleatório e possivelmente a mais simples requer que todos os registros no arquivo possuam um tamanho fixo. A utilização de registros de tamanho fixo facilita o cálculo da localização exata de qualquer registro relativamente ao início do arquivo (como uma função do tamanho do registro e da chave). Na figura seguinte é mostrado um esquema C++ de um arquivo de acesso aleatório, composto de registros de tamanho fixo (cada registro possui 100 bytes). Um arquivo de acesso aleatório é como um trem com vários vagões, alguns cheios, outros vazios. Os dados podem ser inseridos em um arquivo de acesso aleatório sem destruir outros dados no arquivo. Os dados armazenados anteriormente

31 / EDOA / 31 também podem ser atualizados ou apagados sem a necessidade de reescrever o arquivo inteiro. Manipulação de arquivos Para a manipulação (leitura e/ou escrita) e criação de arquivo é necessário que façamos uma referência do mesmo à um espaço da memória. Para tanto, o C++ utiliza as classes iostream e fstream.h. Para realizar gravação em arquivos, fazemos: ofstream fgrava("livro.txt"); //O objeto fgrava faz referência ao arquivo livro.txt Para realizar leitura em arquivos, fazemos: ifstream fleitura("livro.txt"); //O objeto fleitura faz referência ao arquivo livro.txt Para realizar leitura e gravação em arquivos, fazemos: fstream fio; fio.open("livro.txt"); //O objeto 'fio' recebe a referência ao arquivo livro.txt Manipulação de arquivos, é, de certa forma, parecida com a manipulação de vetores, ambos trabalham com o conceito de posição, a diferença se dá no fato de que arquivos não tem um limite de posições, ao contrário do que ocorre com vetores, assim, teoricamente, podemos adicionar novos registros até o limite físico do disco rígido. Podemos escolher a posição em que queremos trabalhar no arquivo, para tanto, usamos a função: <nome_da_objeto_de_entrada_e_saida_de_dados>.seekg(x); X deve receber a posição do registro no arquivo. Em C++, ao contrário do que ocorre em algoritmo, X não recebe 0, 1, 2, 3..., mas sim a posição do registro em forma binária. Para tanto, usa-se o seguinte artifício: sizeof(nome_do_objeto_molde_do_registro) As classes iostream e fstream.h O C++ utiliza as classes ofstream e ifstream (membros da classe iostream) para realizar, respectivamente, a gravação e leitura de arquivos. Para realizar ambos em um mesmo arquivo utilizamos a classe fstream.h Quando utilizamos fstream, necessariamente também precisamos fazer uso

32 / EDOA / 32 da função open(), que é a responsável por fazer a referência de um objeto (alocado na memória) com um arquivo. Utilizando ofstream e ifstream, esta "ligação" com um arquivo é feita diretamente na declaração do objeto. Para utilizar as classes iostream e fstream, é necessário fazer a referência das mesmas no código: #include <fstream.h> #include <iostream> Para fazer a gravação no arquivo, usamos a função: <objeto_de_dados>.write( (char *)&<objeto_para_ser_gravado>, sizeof(<classe_molde_do_objeto_a_ser_gravado>)) Para fazer a leitura no arquivo, usamos a função: <objeto_de_dados>.read( (char *)&<objeto_para_ser_gravado>, sizeof(<classe_molde_do_objeto_a_ser_gravado>)) Entrada e saída binária Existem duas maneiras de se ler e escrever dados binários de e para um arquivo. Primeiro, pode-se escrever um byte usando-se a função membro put( ) e ler um byte com a função membro get( ). A função get( ) tem muitas formas, mas a versão mais usada é mostrada aqui. A função get() lê um único caracter do fluxo associado, coloca o valor em ch e retorna o fluxo. A função put() escreve ch para o fluxo e retorna o fluxo. Exemplo: programa que exibe o conteúdo de um arquivo na tela, usando a função get(). #include <iostream.h> #include <fstream.h> int main ( int argc, char *argv[] ) { // declaração das variáveis char ch; // guarda o caractere lido if( argc!= 2 ) { cout << "Use: programa <nome do arquivo>" << endl; return 1;

33 / EDOA / 33 } // abre um arquivo para leitura ifstream in( argv[1] ); if(!in ) { cout << "O arquivo não pode ser aberto!"; return 1; } while( in ) { // in será zero quando eof (fim do arquivo) for encontrado in.get( ch ); cout << ch; } // fecha o arquivo in.close(); } Exemplo: programa que escreve uma string para um arquivo, usando a função put( ): #include <iostream.h> #include <fstream.h> int main ( void ) { char *p = "Alô a todos!"; // abre um arquivo para escrita ofstream out( "Test.txt" ); if(!out ) { } cout << "O arquivo não pode ser aberto!"; return 1; while( *p ) out.put( *p++ );

34 / EDOA / 34 // fecha o arquivo in.close(); } Exemplos Gravando registros - ofstream #include <fstream.h> #include <cstdlib> #include <stdio.h> #include <iostream> using namespace std; class alunos{ private: int ra; char nome[50]; public: alunos(); void cadastra(); }; alunos :: alunos(){ ra = 1; strcpy(nome,""); }

35 / EDOA / 35 void alunos :: cadastra(){ cout << "Digite o RA: " << endl; cin >> ra; cout << "Digite o nome: "<< endl; cin >> nome; } int main(){ int i; //Aqui criamos o objeto 'fgrava', que faz referência ao objeto aluno.txt ofstream fgrava("alunos.txt"); //Aqui criamos o objeto 'cad1' usando a classe 'alunos'. alunos cad1; cout << "Deseja cadastrar um aluno? Tecle 0(zero) para sair e 1 para confirmar." << endl; cin >> i; while(i!=0){ cad1.cadastra();//lemos os dados com a função 'cadastra()'. fgrava.write( (char *)&cad1, sizeof(alunos));//aqui gravamos o

36 / EDOA / 36 conteúdo do objeto 'cad1' em 'alunos.txt'. //Usamos 'sizeof(alunos)' neste caso, para informar o tamanho do registro e posteriormente grava -lo no arquivo. cout << "Deseja cadastrar um aluno? Tecle 0(zero) para sair e 1 para confirmar." << endl; } cin >> i; } Lendo vários registros - ifstream #include <fstream.h> #include <cstdlib> #include <stdio.h> #include <iostream> using namespace std; class alunos{ private: int ra; char nome[50]; public: alunos(); void display(); }; alunos :: alunos(){ ra = 1; strcpy(nome,"");

37 / EDOA / 37 } void alunos :: display(){ } cout << "Número do RA: " << endl; cout<< ra << endl; cout << "Nome do aluno: "<< endl; cout << nome << endl; int main(){ //Aqui criamos o objeto 'fread', que faz referência ao objeto aluno.tx ifstream fread("/users/sam/alunos.txt"); //Aqui criamos o objeto 'cad1' usando a classe 'alunos'. alunos cad1; while(fread){//enquanto não for F.D.A //Aqui "lemos" o conteúdo do arquivo 'alunos.txt' em 'cad1'. fread.read( (char *)&cad1, sizeof(alunos)); //Usamos o sizeof(alunos) para ler o registro no tamanho certo da classe alunos. } } cad1.display();//imprime na tela o registro. fread.close(); Gravação e leitura - fstream #include <fstream.h> #include <cstdlib> #include <stdio.h> #include <iostream>

38 / EDOA / 38 using namespace std; class alunos{ private: int ra; char nome[50]; public: alunos(); void cadastra(); void display(); }; alunos :: alunos(){ ra = 1; strcpy(nome,""); } void alunos :: cadastra(){ cout << "Digite o RA: " << endl; cin >> ra; cout << "Digite o nome: "<< endl; cin >> nome; } void alunos :: display(){ cout << "Número do RA: " << endl;

39 / EDOA / 39 cout<< ra << endl; cout << "Nome do aluno: "<< endl; cout << nome << endl; } int main(){ int i; fstream iodados; iodados.open("/users/sam/alunos.txt", fstream::in fstream::out fstream::app); alunos cad1; cout << "Deseja cadastrar um aluno? Tecle 0(zero) para sair e 1 para confirmar." << endl; cin >> i; while(i!=0){ cad1.cadastra();//lemos os dados com a função 'cadastra()'. iodados.write( (char *)&cad1, sizeof(alunos));//aqui gravamos o conteúdo do objeto 'cad1' em 'alunos.txt'. //Usamos 'sizeof(alunos)' neste caso, para informar o tamanho do registro e posteriormente grava -lo no arquivo. cout << "Deseja cadastrar um aluno? Tecle 0(zero) para sair e 1 para confirmar." << endl;

40 / EDOA / 40 cin >> i; cin.ignore(); } iodados.seekg(0); while (iodados.read( (char *)&cad1, sizeof(alunos))) cad1.display();//imprime na tela o registro. iodados.close(); } No código acima foi necessário colocar iodados.seekg(0), pois depois que adicionamos registros ao arquivo, este chega ao estado de Fim de Arquivo (End of File), colocando 0 (zero), voltamos ao começo do arquivo e depois mostramos na tela os registros armazenados no mesmo. Em iodados.open("/users/sam/alunos.txt", ios::app ios::out ios::in), o segundo argumento indica o modo de abertura do arquivo. Abaixo, temos as opções possíveis para abertura (o pipe é usado para combinar as opções): Modos de abertura ios::in ios::out ios::ate ios::app ios::trunc ios::nocreate ios::noreplace Descrição Abre para leitura (default de ifstream) Abre para gravação (default de ofstream) Abre e posiciona no final do arquivo.(este modo trabalha com leitura e gravação) Grava a partir do fim do arquivo Abre e apaga todo o conteúdo do arquivo Erro de abertura se o arquivo não existe Erro de abertura se o arquivo existir

41 / EDOA / 41 ios::binary Abre em binário (default é texto) É recomendada a utilização da função <nome_do_objeto_de_dados>.close para fechar o arquivo, depois de manipulá-lo, no final do código. Alguns compiladores podem não aceitar e gerar erros se o arquivo não é fechado. Criando um Arquivo Binário No exemplo seguinte é criado um arquivo que pode ser utilizado para gerenciar um sistema de contas de clientes. Assume-se que cada cliente é identificado pelo número de sua conta, nome e saldo. A seguinte estrutura de dados é definida: 1 // cliente.h 2 // Definição da estrutura cliente 3 #ifndef CLIENTE_H 4 #define CLIENTE_H 5 6 struct cliente 7 { int numero; 8 char nome[30]; 9 float saldo; 10 }; #endif Com base nisso, o programa seguinte cria o arquivo denominado credito.dat contendo 100 registros em branco ou seja, com informações que podem ser consideradas como indicadoras de um registro vazio (linha 9). Na linha 17, os registros (todos iguais a clientevazio) são gravados no arquivo através do comando: outcredito.write((const char *)(&clientevazio), sizeof(cliente)); O método write requer dois parâmetros, sendo o primeiro um ponteiro constante para o tipo de dados char. Assim, é necessário converter a variável clientevazio (do tipo cliente) para o tipo (const char *). Em algumas

42 / EDOA / 42 implementações é necessário substituir o comando anterior por: outcredito.write(reinterpret_cast<const char *>(&clientevazio), sizeof(cliente)); O segundo parâmetro do método write é um inteiro do tipo size_t especificando o número de bytes a serem escritos. O tamanho do registro de cliente é dado pela função sizeof(cliente), que determina quantos bytes a estrutura de dados (registro) cliente ocupa no computador em questão. 1 // cliente1.cpp 2 // Criação sequencial de um arquivo de acesso aleatório 3 #include <iostream> 4 #include <fstream> 5 #include <cstdlib> 6 using namespace std; 7 #include "cliente.h" 8 int main() 9 { cliente clientevazio = {0, "", 0.0}; 10 ofstream outcredito("credito.dat",ios::out); if(! outcredito) 13 { cerr << "Arquivo credito.dat nao pode ser aberto." << endl; 14 exit(1); 15} 16 for(inti=0;i<100;i++) 17 outcredito.write((const char *)(&clientevazio),sizeof(cliente)); 18 return 0; 19 } Escrevendo Dados Aleatoriamente em um Arquivo Uma vez criado o arquivo com o programa anterior, agora podemos

43 / EDOA / 43 proceder à atualização dos registros contidos nele no programa seguinte. Observe na linha 10: o modo de abertura ios::ate abre um arquivo para gravação e move o ponteiro de arquivo para o final-de-arquivo; os dados podem ser gravados em qualquer posição no arquivo neste modo de abertura de arquivo. O programa então lê um número de conta, c.numero (linhas 17-18) entre 1 e 100 (que é o total de registros existentes no arquivo criado com o programa anterior). Em seguida o nome e saldo do cliente são lidos (linhas 20-21). Na linha 24 o ponteiro de arquivo é posicionado na conta desejada (lembre-se que o ponteiro de arquivo indica o número de bytes deslocados em relação ao início do arquivo e que o arquivo começa no byte de número zero. Assim, para o primeiro registro, devemos posicionar no byte zero; para o segundo registro devemos posicionar no byte sizeof(cliente) e assim por diante. Para o n-ésimo registro, devemos posicionar no byte (n-1)*sizeof(cliente). Uma vez o ponteiro de arquivo na posição correta, na linha 26 os dados fornecidos pelo usuário são regravados por cima dos existentes, atualizando as informações. 1 // cliente2.cpp 2 // Escrevendo Dados de modo aleatorio 3 #include <iostream> 4 #include <fstream> 5 #include <cstdlib> 6 using namespace std; 7 #include "cliente.h" 8 int main() 9 { cliente c; 10 ofstream outcredito("credito.dat",ios::ate); if(! outcredito) 13 { cerr << "Arquivo credito.dat nao pode ser aberto." << endl; 14 exit(1);

44 / EDOA / } cout << "Enter numero da conta de 1 a 100 (0 termina) "; 18 cin >> c.numero; 19 while(c.numero > 0 && c.numero <= 100) 20 { cout << "Entre nome, saldo\n? "; 21 cin >> c.nome >> c.saldo; // posicionar no cliente desejado 24 outcredito.seekp((c.numero - 1) * sizeof(cliente)); 25 // atualizar dados 26 outcredito.write((const char *)(&c),sizeof(cliente)); cout << "Enter numero da conta de 1 a 100 (0 termina) "; 29 cin >> c.numero; 30 } 31 return 0; 32 } Lendo Dados Seqüencialmente a partir de um Arquivo de Acesso Aleatório Considerando o próximo programa, nas linhas 24 e 32, os registros são lidos do arquivo através do comando: incredito.read((char *)(&c), sizeof(cliente)); O método read requer dois parâmetros, sendo o primeiro um ponteiro para o tipo de dados char. Assim, é necessário converter a variável c (do tipo cliente) para o tipo (char *). Em algumas implementações é necessário substituir o comando anterior por: incredito.read(reinterpret_cast<char *>(&c), sizeof(cliente));

45 / EDOA / 45 O segundo parâmetro do método read é um inteiro do tipo size_t especificando o número de bytes a serem lidos. Como antes mencionado, o tamanho do registro de cliente é dado pela função sizeof(cliente), que determina quantos bytes a estrutura de dados (registro) cliente ocupa no computador em questão. Como o arquivo foi aberto no modo leitura (ios::in), observe que não há nenhuma chamada ao método seekg para posicionamento do ponteiro de arquivo. Ao ler um registro, o ponteiro de arquivo é automaticamente incrementado pela quantidade de bytes lidos, posicionando o ponteiro de arquivo no próximo registro do arquivo. Assim, mesmo o arquivo sendo de acesso aleatório, os dados podem ser lidos seqüencialmente. O laço na linha 25 while (incredito &&! incredito.eof()) utiliza o método eof para determinar quando o final-de-arquivo é atingido e termina a execução do laço. Além disso, se houver um erro de leitura do arquivo, o laço termina uma vez que InCredito será false. 1 // cliente3.cpp 2 // Lendo Dados Sequencialmente a partir de um Arquivo de Acesso Aleatório 3 #include <iostream> 4 #include <iomanip> 5 #include <fstream> 6 #include <cstdlib> 7 using namespace std; 8 #include "cliente.h" 9 int main() 10 { cliente c; 11 ifstream incredito("credito.dat", ios::in); if(! incredito) 14 { cerr << "Arquivo credito.dat nao pode ser aberto." << endl;

46 / EDOA / exit( 1 ); 16 } } cout << setiosflags(ios::left) 19 << setw(10) << "Conta" 20 << setw(30) << "Nome" 21 << resetiosflags(ios::left) 22 << setw(10) << "Saldo" << endl; incredito.read((char *)(&c),sizeof(cliente)); 25 while (incredito &&! incredito.eof()) 26 { if(c.numero!= 0) 27 cout << setiosflags( ios::left ) 28 << setw(10) << c.numero 29 << setw(30) << c.nome 30 << setw(10) << setprecision( 2 ) << resetiosflags(ios::left) 31 << setiosflags(ios::fixed ios::showpoint) << c.saldo << '\n'; 32 incredito.read((char *)(&c),sizeof(cliente)); 33 } 34 return 0; 35 } Exemplo de Programa de Processamento de Transações O programa seguinte utiliza um arquivo de acesso aleatório para obter acesso instantâneo aos registros de um arquivo, simulando contas de clientes em um banco. A opção número 1 deve ser utilizada somente uma única vez, já que ela cria o arquivo com 100 registros em branco ou sobrepõe os 100 registros existentes com valores que consideramos como registros vazios. Note que, embora interpretemos os registros como vazios,

47 / EDOA / 47 eles contêm dados, ou seja, zero para o número de conta e saldo e um vetor de caracteres de tamanho zero para o nome. 001 #include <iostream> 002 #include <fstream> 003 #include <iomanip> 004 #include <cstdlib> 005 #include <string> 006 using namespace std; 007 #include "cliente.h" 008 enum Escolhas {CRIAR=1, TELA, ARQUIVOTEXTO, ATUALIZAR, NOVO, APAGAR, FIM}; 009 // Escolhas enterchoice() 011 // pre: nenhuma 012 // pos: exibe menu na tela e solicita acao a ser tomada ao usuario 013 { int menuchoice; 014 cout << "\nmenu:" << endl 015 << "1 - cria registros vazios no arquivo\n" 016 << "2 - lista os dados na tela\n" 017 << "3 - armazena os dados no arquivo texto \"print.txt\"\n" 018 << "4 - atualiza uma conta que ja contenha informacoes\n" 019 << "5 - insere informacoes em uma nova conta\n" 020 << "6 - apaga informacoes de uma conta\n" 021 << "7 fim do programa\n" 022 << "Opcao: "; 023 cin >> menuchoice;

48 / EDOA / return (Escolhas) menuchoice; 025 } 026 // void create(fstream &f) 028 // pre: arquivo f aberto 029 // pos: insere/sobrepoe 100 registros no arquivo, destruindo 030 // qualquer informacao anterior 031 { cliente clientevazio = {0, "", 0.0}; f.seekg(0); 034 for(inti=0;i<100;i++) 035 f.write((const char *)(&clientevazio),sizeof(cliente)); 036 } 037 // void outputline(ostream &output, const cliente &c) 039 // pre: arquivo output aberto para escrita, cliente c contendo dados de cliente 040 // pos: escreve dados do cliente c no arquivo output 041 { output << setiosflags(ios::left) 042 << setw(10) << c.numero 043 << setw(30) << c.nome 044 << setw(10) << setprecision(2) << resetiosflags(ios::left) 045 << setiosflags(ios::fixed ios::showpoint) << c.saldo << '\n'; 046 } 047 // void screen(fstream &f)

49 / EDOA / // pre: Arquivo f contendo dados de clientes aberto 050 // pos: Cria um arquivo texto formatado para impressao 051 { cliente c; cout << setiosflags(ios::left) 054 << setw(10) << "Conta" 055 << setw(30) << "Nome" 056 << resetiosflags(ios::left) << setw(10) << "Saldo" << endl; f.seekg(0); 059 f.read((char *)(&c),sizeof(cliente)); 060 while(! F.eof()) 061 { if(c.numero!= 0) 062 outputline(cout,c); 063 f.read((char *)(&c),sizeof(cliente)); 064 } 065 } 066 // void textfile(fstream &f) 068 // pre: Arquivo f contendo dados de clientes aberto 069 // pos: Cria um arquivo texto formatado para impressao 070 { cliente c; 071 ofstream outprintfile("print.txt",ios::out); if(! outprintfile)

50 / EDOA / { cerr << "Arquivo print.txt nao pode ser aberto." << endl; 075 exit(1); 076 } outprintfile << setiosflags(ios::left) 079 << setw(10) << "Conta" 080 << setw(30) << "Nome" 081 << resetiosflags(ios::left) << setw(10) << "Saldo" << endl; f.seekg(0); 084 f.read((char *)(&c),sizeof(cliente)); 085 while(! f.eof()) 086 { if(c.numero!= 0) 087 outputline(outprintfile,c); 088 f.read((char *)(&c),sizeof(cliente)); 089 } 090 outprintfile.close(); 091 } 092 // int getaccount(string msg) 094 // pre: nenhuma 095 // pos: imprime msg, obtem do teclado um numero de conta entre 1 e 100 e retorna-o 096 { int conta; do

51 / EDOA / {cout<<msg<<"(1-100):"; 100 cin >> conta; 101 } while (conta < 1 conta > 100); return conta; 104 } 105 // void updaterecord(fstream &f) 107 // pre: Arquivo f aberto 108 // pos: Atualiza o saldo de uma conta 109 { int conta; 110 cliente c; 111 float transacao; conta = getaccount("conta a ser atualizada"); 114 f.seekg((conta 1) * sizeof(cliente)); // posicionar na conta desejada 115 f.read((char *)(&c),sizeof(cliente));// ler dados da conta 116 if(c.numero!= 0) // conta contem informacao? 117 { outputline(cout,c); 118 cout << "\nentre deposito (+) ou retirada (-): "; 119 cin >> transacao; 120 c.saldo += transacao; 121 outputline(cout,c); 122 f.seekp((conta - 1) * sizeof(cliente)); // posicionar na conta desejada 123 f.write((const char *)(&c),sizeof(cliente)); // atualizar

52 / EDOA / } 125 else 126 cerr << "Conta #" << conta << " nao possui informacao." << endl; 127 } 128 // void newrecord(fstream &f) 130 // pre: arquivo f aberto 131 // pos: insere informacao em um registro de conta que esteja vazio (sem informacao) 132 { int conta; 133 cliente c; conta = getaccount("numero da nova conta"); 136 f.seekg((conta-1) * sizeof(cliente)); // posicionar na conta desejada 137 f.read((char *)(&c),sizeof(cliente)); // ler dados da conta 138 if(c.numero == 0) 139 { cout << "Entre um nome e o saldo\n? "; 140 cin >> c.nome >> c.saldo; 141 c.numero = conta; 142 f.seekp((conta - 1) * sizeof(cliente)); // posicionar na conta desejada 143 f.write((const char *)(&c),sizeof(cliente)); // atualizar 144 } 145 else 146 cerr << "Conta #" << conta << " ja possui informacao." << endl; 147 }

53 / EDOA / // void deleterecord(fstream &f) 150 // pre: arquivo f aberto 151 // pos: conta fornecida pelo usuario e apagada 152 // (informação em branco) 153 { int conta; 154 cliente c, clientevazio = {0, "", 0.0}; conta = getaccount("conta a ser apagada"); 157 f.seekg((conta-1) * sizeof(cliente)); 158 f.read((char *)(&c),sizeof(cliente)); 159 if(c.numero!= 0) 160 { f.seekp((conta - 1) * sizeof(cliente)); 161 f.write((const char *)(&clientevazio), sizeof(cliente)); 162 cout << "Conta #" << conta << " apagada." << endl; 163 } 164 else 165 cerr << "Conta #" << conta << " ja esta apagada." << endl; 166 } 167 // int main() 169 { Escolhas opcao; 170 fstream inoutcredito("credito.dat", ios::in ios::out); // leitura e escrita if(! inoutcredito) {

54 / EDOA / cerr << "Arquivo credito.dat nao pode ser aberto." << endl; 174 exit (1); 175 } while ((opcao = enterchoice())!= FIM) 178 { switch (opcao) 179 { case CRIAR: 180 create(inoutcredito); 181 break; 182 case TELA: 183 screen(inoutcredito); 184 break; 185 case ARQUIVOTEXTO: 186 textfile(inoutcredito); 187 break; 188 case ATUALIZAR: 189 updaterecord(inoutcredito); 190 break; 191 case NOVO: 192 newrecord(inoutcredito); 193 break; 194 case APAGAR: 195 deleterecord(inoutcredito); 196 break; 197 default:

55 / EDOA / cerr << "Opcao incorreta\n"; 199 break; 200 } 201 inoutcredito.clear(); // limpa o indicador de final-de arquivo

56 / EDOA / 56 CHAPTER FIVE Tipos de arquivos CHAPTER SIX Arquivo sequencial A organização de arquivos sequenciais é a mais conhecida e mais freqüentemente usada. A ordem lógica e física dos registros armazenados em um arquivo seqüencial é a mesma. Os arquivos sequenciais em disco são armazenados em trilhas dentro de cilindros contidos em tambores que são armazenados em trilhas adjacentes. Já que os registros em arquivos seqüenciais são armazenados em sucessão contínua, acessar o registro N do arquivo(começando no início do arquivo) requer que os registros N-1 também sejam lidos. Os arquivos seqüenciais são associados, historicamente, a fitas magnéticas, devido a natureza seqüencial do meio de gravação. Mas são também armazenados em dispositivos de acesso aleatório, quando o acesso a sucessivos registros em alta velocidade é um requisito do processamento. Claro que o tempo de movimento da cabeça de leitura/gravação que realmente afeta o processamento de uma aplicação depende, de certa forma, do esquema de memória intermediária usado e também se leituras antecipadas são feitas ou não no arquivo sequencial, pelas rotinas de acesso do sistema operacional. O principal uso dos arquivos sequencias é o processamento em série ou sequencial de registros. Se um mecanismo de leitura/gravação é posicionado para recuperar um registro em particular, então ele pode acessar rapidamente o registro seguinte do arquivo. A vantagem de poder acessar rapidamente o registro seguinte torna-se uma desvantagem quando o arquivo é usado para acessar um outro registro diferente do registro "seguinte". Em média, metade de um arquivo sequencial tem que ser lido para recuperar um registro. A organização sequencial tem como princípios a busca e a inserção, bem como a exclusão de informações de forma sequencial, ou seja, o acesso a uma posição N requer N - 1 acessos. Pelo ponto de vista prático teríamos uma organização simples, de fácil

57 / EDOA / 57 entendimento, mas pelo ponto de vista de eficiência teríamos um arquivo onde qualquer processamento que o utilizasse se tornaria lento, comprometendo o tempo do sistema, desde que o arquivo não fosse pequeno. Os arquivos sequenciais podem ter chave ou não. Cada registro lógico do arquivo com chave tem um item de dado chamado chave que pode ser usado para ordenar os registros, essa chave é então chamada chave de ordenação. Os registros em arquivos sequenciais sem chave estão ordenados em série, sendo que geralmente cada novo registro é colocado no final do arquivo. Em um arquivo sequencial, os registros são dispostos ordenadamente, obedecendo a seqüência determinada por uma chave primária, chamada chave de ordenação e para arquivos seqüências sem chave de ordenação, os registros estão ordenados em série, sendo que geralmente, cada novo registro é colocado no final do arquivo. A utilização de arquivos organizados sequencialmente oferece problemas. Se o novo registro for maior ou menor que o registro que existia anteriormente, os registros adjacentes podem ser destruídos ou se tornarem inacessíveis quando o novo registro for gravado. Além disso, é difícil inserir novos registros ou retirar registros de um arquivo organizado sequencialmente. Quando se tem uma organização sequencial, pode-se ou não ter chaves para ordenação. Caso não se tenha chave, os registros serão inseridos no fim do arquivo em ordem de cronológica. Caso contrário, quando fizermos um inserção em uma posição N, os registros seguintes serão incrementados em uma posição. O conceito de chaves artificiais se resume ao fato de podermos adicionar campos numéricos aos registros dos arquivos para ordenação. Operações Existe a possibilidade de se trabalhar com um arquivo de transação durante as operações, fazendo assim ao final do dia ou após um determinado período de tempo, uma intercalação com o arquivo principal. Desse modo seria inibida toda a demora que se torna tão evidente quando se tem arquivos seqüências muito grandes. O arquivo de transação é ordenado de acordo com as mesmas chaves utilizadas pelo arquivo principal. O acesso a uma registro, dado um argumento de pesquisa, é facilitado se a chave de acesso coincide com a chave de ordenação (ou com sua parte inicial), pois, nos demais casos, não há vantagem na seqüencialidade do

58 / EDOA / 58 arquivo. Inserções A maneira usual de processar inserções de registros em um arquivo sequencial consiste em montar um arquivo de transações contendo os registros a serem inseridos, ordenado pela mesma chave de ordenação do arquivo principal. Os arquivos principal e de transação são então intercalados através de merge, gerando um arquivo principal atualizado. Este procedimento é adotado, porque a inserção de um registro isolado apresenta um custo proibitivo, pois todos aqueles registros com chaves superiores ao inserido seriam necessariamente deslocados de sua posição, o que é inviável em se tratando de arquivos armazenados em um meio externo. O arquivo de transação pode ser usado como uma extensão do arquivo principal até assumir um tamanho que justifique a efetivação da operação de intercalação. Exclusões Usualmente implementada como a inserção, sendo as indicações de exclusão coletadas no mesmo arquivo de transação para posterior efetivação das operações. Pode, ainda, se implementada com o uso de um campo adicional que indique o estado de cada registro, sendo excluído um de seus possíveis valores. Neste caso, a operação de exclusão consiste na localização do registro a excluir e alteração no seu campo de estado para o valor excluído. Durante o processamento de um arquivo sequencial, os registros marcados como excluídos não são considerados. Com este procedimento, é eliminada a necessidade de movimentação de outros registros para o preenchimento do espaáo liberado pelo excluído. Alterações A operação de alteração consiste em modificação do valor de um ou mais atributos de um registro. O registro deve ser localizado, lido e seus campos alterados sendo, após, gravado novamente. Esta operação deve ser feita sem maiores problemas, desde que não ocorra uma das duas seguintes situações: A alteração faz com que os registros assumam um tamanho maior do que o original; A alteração modifica o valor do campo que determina a seqüência

59 / EDOA / 59 dos registros dentro do arquivo (chave de ordenação). No primeiro caso, o registro não pode ser gravado em sua posição original por falta de espaço, e, no segundo caso, a mudança do valor da chave de ordenação implica em uma mudança da posição do registro dentro do arquivo. Por esses motivos, esta operação é usualmente implementada da mesma forma que a inserção e da exclusão, com o uso do arquivo de transação. Reorganização Esta operação precede, geralmente, ao uso do arquivo sequencial para a emissão de relatórios ou efetivação de consultas, sendo pouco comum a utilização do arquivo de transação como uma extensão do arquivo sequencial, durante o processamento normal. O arquivo de transação é usualmente empregado apenas nesta operação de reorganização e no registro de atualização, sendo nos demais casos usado o arquivo reorganizado. O conceito de reorganização em arquivos seqüências consiste na intercalação (merge) do arquivo de transação mais o arquivo principal, onde ambos já estariam ordenados por uma mesma chave. O tempo da reorganização seria: TR=TOAT + TLAT + TLAV + TEAN onde, TR = tempo de reorganização TOAT = tempo de reorganização do arquivo de transação TLAT = tempo de leitura do arquivo de transação TLAV = tempo de leitura do Arquivo Velho TEAN = tempo de escrita no Arquivo Novo Pesquisa sequencial Pesquisa A pesquisa sequencial consiste no exame de cada registro, a partir do primeiro, até ser localizado aquele que possui, para a chave de acesso, um valor igual ao argumento de pesquisa, ou então, ser atingido o final do

60 / EDOA / 60 arquivo, o que significa que o registro procurado não está presente no arquivo. Passo-a-passo: 1. Posicionar-se no início do arquivo; 2. Se registro atual = registro desejado : Sucesso, Terminar; 3. Se registro atual>registro desejado : Fracasso, Terminar; 4. Se registro atual < registro desejado, avançar um registro; 5. Se não for final de arquivo, retornar ao passo 2; 6. Fracasso, Terminar. Pesquisa binária Se o arquivo estiver armazenado em um dispositivo de acesso direto (disco, tambor, etc.), torna-se viável a utilização de um método de pesquisa mais eficaz, sendo mais conhecido o método de pesquisa binária, no qual o primeiro registro a ser pesquisado é o registro que ocupa a posição média do arquivo. Se a chave do registro for igual ao argumento de pesquisa, esta termina com sucesso, caso contrário, ocorre uma das seguintes situações: 1. A chave do registro é maior do que o argumento de pesquisa e o processo de busca é repetido para metade inferior do arquivo; 2. A chave do registro, é menor do que o argumento de pesquisa e o processo de busca é repetido para metade superior do arquivo; 3. A busca é encerrada sem sucesso quando a área de pesquisa, que a cada comparação é reduzida a metade, assumir o comprimento zero. Passo a Passo: 1. Selecionar todo o conjunto de registros do arquivo; 2. Posicionar-se no meio do conjunto selecionado; 3. Se registro atual=registro desejado: Sucesso,terminar; 4. Se registro atual>registro desejado:selecionar metade superior do arquivo e repetir o processo -passo(2); 5. Se registro atual<registro desejado:selecionar metade inferior do arquivo e repetir o processo -passo(2); 6. Se o conjunto selecionado não possuir

61 / EDOA / 61 elementos:fracasso,terminar Probing Literalmente um palpite para começarmos a busca do registro procurado. Seu funcionamento se baseia na fórmula: Local= [(C - Cmin / Cmax - Cmin) (n - 1)] + 1 onde, Local = localização do registro C = chave procurada Cmin = chave de menor valor Cmax = chave de maior valor n = número de chaves Após calculado o endereço provável para se encontrar o registro procurado, é feita uma pesquisa sequencial caso o endereço dado pela fórmula seja menor que a chave procurada. Tudo dependerá do algoritmo implementado. Existe a necessidade de se ter conformidade no valor das chaves de modo que sempre que se utilizar a fórmula de Probing possamos sempre nos localizarmos perto do registro procurado. CHAPTER SEVEN Arquivo sequencial indexado Quando o número de acessos aleatórios a um arquivo seqüencial se torna muito grande, surge a necessidade de utilização de uma estrutura de acesso associada ao arquivo, que oferecerá uma maior eficiência na localização de um registro dada uma chave de pesquisa. Sendo assim, utilizaremos técnicas de indexação e algoritmos de busca. De uma forma bem simples, podemos dizer que um arquivo seqüencial indexado nada mais é do que um arquivo seqüencial acrescido de um índice. A principal vantagem do arquivo seqüencial indexado é a utilização de índices, o que conseqüentemente, diminui o número de acessos aos registros em disco. No entanto, possui como desvantagem a inserção realizada da mesma forma que no arquivo seqüencial, ou seja, não permite

62 / EDOA / 62 que os arquivos sejam organizados de acordo com sua ordem de entrada no arquivo (como ocorre no arquivo indexado). A principal justificativa para utilização de índices é a área ocupada pelo índice é menor que a área ocupada pelo registro de dados correspondente, oferecendo maior rapidez na pesquisa. Indexação Sua principal finalidade é permitir a rápida determinação do endereço de um arquivo, dado um argumento de pesquisa. Indexação é baseada no conceito de índices (chaves) e campos de referência. Para entender melhor, você poderia comparar com a estrutura de um índice em um livro. Neste caso, você interpretaria os tópicos como chaves do índice e o número da página correspondente seria o endereço do registro no arquivo de dados. Sendo assim, localizada a chave de acesso relacionada ao assunto desejado, esta indicará o endereço exato onde você encontrará os dados referentes ao assunto desejado, sem que se tenha que ler todas as referências anteriores para encontrá-lo. Podemos usar um campo de uma estrutura de registro para "identificar"esse registro. Chamamos a este campo de chave. Índice é uma estrutura de dados que mantém o conjunto de chaves de um arquivo e seus endereços e serve de referência para os registros. Estruturação de Índices: Índice Primário. Também chamado Indexação por chave primária. É um índice único que organiza o arquivo através do campo considerado "mais importante" ou "identificador" da sua definição de registros. A chave de acesso deste índice está, portanto, associada à chave de ordenação do arquivo que contém os registros. Ex: arquivo de índice organizado pelo campo nº de matrícula do registro de funcionários, pois dois funcionários não podem possuir o mesmo número de identificação. Índice Secundário. Também chamado Indexação por chave secundária. É um índice que organiza o arquivo referenciando outro campo ou combinação de campos. Ex: arquivo de índice organizado pelo campo nome do registro de funcionários (é uma chave importante, mas, não mais que o nº de matrícula). Estrutura O arquivo seqüencial indexado é constituído de um arquivo seqüencial

63 / EDOA / 63 acrescido de uma estrutura de acesso (índice). O arquivo seqüencial indexado utiliza indexação primária, ou seja, índice ordenado por chave primária. Um índice é formado por uma coleção de pares, sendo cada um deles associado a um valor da chave de acesso a um endereço de arquivo de dados. Sendo assim, um índice é sempre específico pa uma chave de acesso. Nos casos em que é desejado acesso aleatório, por meio de várias chaves de acesso, deve ser construído um índice para cada chave de acesso. Além do arquivo seqüencial e do índice, o arquivo seqüencial indexado possui áreas de extensão que são utilizadas para a implementação da operação de inserção de registros. Índice A finalidade do índice é permitir a rápida determinação do endereço de um registro do arquivo, dado um argumento de pesquisa. O endereço identificar a posição onde está armazenado o registro de dados, na memória secundária. Cada entrada do índice, formada por um par (chave do registro, endereço do registro), ocupa um espaço bem menor do que o registro de dados correspondente, o que faz com que a área ocupada pelo índice seja menor do que aquela ocupada pelos dados. Com isto, a pesquisa sobre um índice pode ser feita com maior rapidez do que se fosse realizada diretamente sobre o arquivo de dados correspondente, o que constitui a justificativa maior para a utilização de índices. Cada entrada do índice pode, então, determinar um registro em particular, ou um bloco de registros do arquivo de dados. Veja a figura ao lado, que apresenta um arquivo seqüencial indexado: Número Endereç o Número Nome Salário PEDRO JOÃO MARIA CARLA MAX 2000 Índice Área de dados no disco Para tornar mais eficiente o processo de pesquisa, o índice pode ser estruturado em vários níveis, sendo o número de níveis proporcional ao

64 / EDOA / 64 número de entradas do índice. 1. Índice implementado em um nível. 2. Índice implementado em dois ou mais níveis. Com esta organização, a localização de um registro por meio de uma chave de pesquisa pode ser feito em duas etapas: na primeira, consulta-se o índice e determina-se o registro ou o bloco onde este se encontra e na segunda o registro (ou bloco) determinado é localizado (ou pesquisado). É comum, também, o estabelecimento de índices estruturados de acordo com os níveis físicos dos meios de armazenamento. Este é o caso dos discos magnéticos, onde podemos identificar os níveis de disco, cilindro e trilha. Índice implementado em um nível No caso de um índice implementado em um único nível, cada entrada do índice apontaria para um registro ou para um bloco de registros no arquivo de dados. 1. Entrada do índice apontando para um registro. Neste caso, cada entrada do índice vai conter, como chave de acesso, o valor da chave de ordenação do registro no arquivo de dados. 2. Entrada do índice apontando para um bloco de registros. Neste caso, cada entrada do índice vai conter, como chave de acesso, o maior valor que a chave de ordenação pode assumir em determinado bloco de registros. Ou seja, se tivermos uma entrada apontando para um bloco de 9 registros (que deverão estar, obrigatoriamente, ordenados por sua chave de acesso, visto que é um arquivo seqüencial), o valor da chave desta entrada deverá ser o maior valor da chave dos registros deste bloco, isto é, a chave do 9º registro. Índice implementado em dois ou mais níveis No caso de um índice implementado em dois ou mais níveis, teríamos dois ou mais níveis, sendo estes denominados como índice primário, secundário,etc. de acordo com o nível de implementação de índices e não de acordo com a sua chave de ordenação (não confunda com o outro conceito de índice primário e secundário abordado anteriormente). Cada entrada do índice primário apontará para um registro ou para um bloco de registros do índice secundário, e não mais do arquivo de dados, e assim sucessivamente até o último nível de implementação de índices que apontará para um registro ou um bloco de registros no arquivo de dados. Para seu melhor entendimento, vamos nos basear em um índice

65 / EDOA / 65 implementado em dois níveis, onde teremos, então, um índice primário que apontará para um índice secundário que por sua vez apontará para um registro (ou bloco de registros) do arquivo de dados. 1. Entrada do índice apontando para um registro. Neste caso, cada entrada do índice primário vai conter, como chave de acesso, o valor da chave de ordenação do registro no índice secundário que será a mesma no arquivo de dados. O índice secundário então apontará para um registro (ou bloco de registros) no arquivo de dados. 2. Entrada do índice apontando para um bloco de registros. Neste caso, cada entrada do índice primário vai conter, como chave de acesso, o maior valor que a chave de ordenação pode assumir em determinado bloco de registros do índice secundário. Este apontará, finalmente, para o arquivo de dados. Área de extensão Um arquivo seqüencial indexado não utiliza exatamente um arquivo seqüencial e um índice. Na verdade, ele é constituído de um índice e uma arquivo seqüencial acrescido de uma estrutura denominada área de extensão, onde os dois juntos chamamos de arquivo de dados. Arquivo de dados = arquivo seqüencial + área de extensão A área de extensão, também chamada Área de Overflow destina-se a conter os registros inseridos após a criação do arquivo. Assim, constitui uma extensão da área principal de dados do arquivo. Áreas de extensão são necessárias em arquivos seqüenciais indexados, porque nestes não é viável a implementação da operação de inserção de registros do mesmo modo que nos arquivos seqüenciais. Naquele processo, a maioria dos registros muda de endereço, o que obrigaria a uma completa alteração do índice, a cada atualização do arquivo. Há duas alternativas principais para a implementação de áreas de extensão em um arquivo seqüencial indexado: 1. Destinar em cada registro da área principal um campo de elo para conter o endereço da lista encadeada de seus sucessores (ou antecessores), alocados na área de extensão. 2. Utiliza um campo de elo em cada bloco de registros, destinados a conter o endereço da lista de extensões do bloco, sendo mantida a seqüencialidade física dos registros dentro de cada bloco da área principal, e sendo que todos os registros da lista de extensão de um bloco possuem ordem maior do que todos os da área principal do mesmo bloco.

66 / EDOA / 66 NÚMERO ENDEREÇO NÚMERO NOME ELO PEDRO JOÃO MARIA CARLA MAX Área de dados no disco Índice NÚMERO NOME ELO BILL NARA Área de extensão A segunda alternativa implica na mudança de endereços de registros dentro de um bloco, podendo, pois, ser utilizada somente naqueles casos em que o índice possui uma entrada para cada bloco. A existência de índices secundários, sobre o mesmo arquivo, também torna inviável esta alternativa. Em ambos os casos, é usual a utilização de várias áreas de extensão para cada arquivo, sendo uma para cada bloco ou grupo de blocos adjacentes e uma (ou mais) adicional, usada sempre que ocorre uma inserção em um bloco cuja área de extensão já está completamente ocupada. Acesso a um registro Operações O acesso serial pode ser feito diretamente sobre a área de dados, sem a utilização do índice, como em um arquivo seqüencial, havendo apenas, nesta caso,um cuidado adicional pela existência de áreas de extensão. O acesso aleatório é feito com a utilização do índice. O argumento de pesquisa define o caminhamento sobre o índice, que conduz ao endereço do registro desejado. O endereço obtido do índice pode ser o próprio endereço o registro ou o endereço do bloco que o contém. Neste caso, é necessária ainda a efetivação de uma busca no bloco para a localização do registro, a qual pode requerer acessos às áreas de extensão.

67 / EDOA / 67 Inserção de um registro O processo de inserção de um registro requer a efetivação de uma busca sobre o arquivo, por meio do índice, para determinação do local onde deve ser inserido o novo registro. Uma vez determinada a posição, o registro é inserido na lista de extensão do seu antecessor na área principal, se cada registro conter m campo de elo para a lista encadeada de seus sucessores (estrutura mais simples). CHAPTER EIGHT Arquivo indexado Nos arquivos seqüenciais indexados, o compromisso de manter os registros fisicamente ordenados pelo valor da chave de ordenação, com o objetivo de prover um acesso serial eficiente, acarreta uma série de problemas, principalmente no que diz respeito à operação de inserção de um registro, conduzindo à necessidade de utilização de áreas de extensão e efetivação de reorganizações periódicas. À medida que decresce a freqüência de acessos seriais, relativamente à freqüência de acessos aleatórios, a manutenção da seqüencialidade física do arquivo encontra uma compensação cada vez menor em termos de eficiência de acesso, até tornar-se antieconômica. A partir deste ponto, torna-se mais conveniente o uso de um arquivo indexado, no qual os registros são acessados sempre através de um ou mais índices, não havendo qualquer compromisso com a ordem física de inserção dos registros. A liberdade na escolha do endereço no qual um registro é armazenado representa um ganho de flexibilidade que permite maior eficiência, principalmente na operação de inserção de um registro, conduzindo, também, a uma simplificação da estrutura geral do arquivo, sendo dispensados os mecanismos complexos de administração de áreas de extensão. Veja a figura abaixo, que apresenta o indexado: Número Endereço Número Nome Salário PAULO JOSÉ 1500

68 / EDOA / MARIA MARISA FÁBIO 2000 Índice Área de dados no disco Ao definir que organização de arquivo será empregada numa certa aplicação, o projetista deve tentar alcançar três objetivos básicos: Rapidez no processo de inclusão de novos registros; Rapidez no processo de pesquisa do arquivo; Rapidez no processo de atualização do arquivo. Desde que não haja movimentação de registros dentro do arquivo, eficiência na inclusão é fácil de se obter, basta inserir os novos registros sempre no final do arquivo. Neste caso, entretanto, a pesquisa se tornará extremamente lenta. Para obter um registro com uma chave* específica poderia ser necessário realizar uma leitura seqüencial exaustiva do arquivo. Assim, para garantir rapidez na pesquisa, podemos usar uma estrutura de indexação, o que reduziria muito o número de acessos a disco, já que a chave seria procurada nesta estrutura, mantida na memória principal do computador e, não haveria compromisso com a ordem física do arquivo. Conceitualmente, um índice é um mapeamento que associa a cada chave, uma referência ao registro que a contém. Assim, dada uma chave de pesquisa como argumento, o índice fornece imediatamente a localização do registro correspondente. O processo de atualização, considerando a existência do índice, também será rápido, dada a chave do registro que deve ser alterado, podemos acessá-lo rapidamente e gravar as novas informações. Se um registro tiver que ser removido, basta remover sua referência do índice (remoção lógica). Uma exclusão efetiva (física) ocorreria somente durante o processo de reorganização do arquivo, quando uma cópia dele seria gerada, contendo apenas os registros ainda referenciados no índice. O termo chave é utilizado para estabelecer o campo de um registro que será utilizado no processo de localização de todo um registro dentro de um arquivo. Desta forma, será possível acessar um determinado registro diretamente, sem nos preocuparmos com os registros que o antecedem. Por exemplo, em um cadastro de funcionários, poderá ser utilizado o campo reservado para a matrícula, como sendo a chave para a manipulação do mesmo. Uma base de dados indexada é composta por duas partes básicas: um

69 / EDOA / 69 arquivo de dados e uma estrutura de índice associada. Cada vez que um novo registro é incluído no arquivo de dados, uma referência a ele é inserida no índice. Quando um registro com uma chave específica precisa ser acessado, para consulta ou alteração, pesquisamos da estrutura de indexação para encontrar sua localização no disco, aí então, podemos acessá-lo diretamente para leitura ou gravação. Índices Em um arquivo indexado, podem existir tantos índices quantas forem as chaves de acesso aos registros. Um índice consiste de uma entrada para cada registro considerando relevante com relação à chave de acesso associada ao índice. As entradas do índice são ordenadas pelo valor da chave de acesso, sendo cada uma constituída por um par (chave do registro, endereço do registro). A seqüencialidade física das entradas no índice visa a tornar mais eficiente o processo de busca e permitir o acesso serial ao arquivo. Tipos de índices: Índice exaustivo Índice seletivo Índice exaustivo Possui uma entrada para cada registro do arquivo (figura ao lado). Índice seletivo Possui entradas apenas para um subconjunto dos registros. O subconjunto é definido por uma condição relativa à chave de acesso e/ou a outros atributos do arquivo. Um exemplo de índice seletivo seria o índice dos funcionários estáveis (há mais de 10 anos na empresa) sobre o cadastro geral de

70 / EDOA / 70 funcionários de uma empresa. Veja outro exemplo. Se nenhum dos índices existentes sobre um arquivo for exaustivo, é necessária a manutenção de uma tabela de alocação que identifique todos os espaços alocados para o arquivo, para fins de manutenção e administração do arquivo. O maior problema relacionado com a utilização de arquivos indexados diz respeito à necessidade de atualização de todos os índices, quando um registro é inserido no arquivo. Atualizações nos índices são também necessárias quando a alteração de um registro envolve atributos associados a índices. Nos arquivos seqüenciais indexados, a necessidade de alteração dos índices é eliminada pelo uso de áreas de extensão e encadeamento na implementação de inserções; no entanto, esta estratégia não é condizente com a idéia de arquivos indexados, nos quais a manutenção constante dos índices é necessária. Exclusão de um registro Operações A exclusão em um arquivo indexado pode parecer muito complicado, mas ao continuar o estudo, você verá que se trata de uma operação bastante simples. Não é possível suprimir um registro do meio de um arquivo sem causar, a maioria das vezes, uma grande movimentação de dados. Para tornar a exclusão um processo mais eficiente, quando um registro precisa ser removido, a área de dados ocupada pelo registro é liberada e retiramos do índice a sua referência correspondente. Após isto, com todos

Manipulação de Arquivos Binários

Manipulação de Arquivos Binários Introdução à Computação I Departamento de Física e Matemática FFCLRP-USP Prof. Dr. José Augusto Baranauskas IBm1006 1º Semestre/2006 Notas de Aula Manipulação de Arquivos Binários Até agora vimos como

Leia mais

Operações com Arquivos

Operações com Arquivos Operações com Arquivos Programação de Computadores I Emiliana Mara Lopes Simões simoes.eml@gmail.com Universidade Federal de Ouro Preto dezembro 2009 Arquivos Os arquivos são utilizados para armazenamento

Leia mais

Aula 28: Arquivos de texto

Aula 28: Arquivos de texto Aula 28: Arquivos de texto Introdução a Programação Túlio Toffolo & Puca Huachi http://www.toffolo.com.br BCC201 2018/2 Baseado nos slides de Guillermo Cámara-Chávez Aulas anteriores Memória Ponteiro Utilização

Leia mais

Arquivos de Texto UFOP 1/41

Arquivos de Texto UFOP 1/41 BCC 201 - Introdução à Programação I Arquivos de Texto Guillermo Cámara-Chávez UFOP 1/41 Arquivos I Podem armazenar grande quantidade de informação Dados são persistentes (gravados em disco) Acesso aos

Leia mais

Arquivos. BCC Programação Orientada a Objectos(POO) Departamento de Computação - UFOP

Arquivos. BCC Programação Orientada a Objectos(POO) Departamento de Computação - UFOP Arquivos BCC 221 - Programação Orientada a Objectos(POO) Guillermo Cámara-Chávez Departamento de Computação - UFOP Introdução O armazenamento em variáveis e vetores é temporário; Arquivos são utilizados

Leia mais

Arquivos em C. Material da Prof. Ana Eliza

Arquivos em C. Material da Prof. Ana Eliza em C Material da Prof. Ana Eliza Definição Um arquivo é uma estrutura de dados linear ( lista ) que é mantida fora da memória principal, em um dispositivo de armazenamento (memória secundária). Um arquivo

Leia mais

Manipulação de Arquivos

Manipulação de Arquivos 1 Manipulação de Arquivos Para realizar E/S em arquivo, você precisa incluir o arquivo-cabeçalho fstream.h nos programas. Esse arquivo define muitas classes e valores importantes. Abrindo e fechando um

Leia mais

Técnicas de Programação I

Técnicas de Programação I Técnicas de Programação I Conceitos básicos C/C++ Material baseado em sites da internet em especial no livro: STARTING OUT WITH C++ C++: Manipulação de Arquivos (1) ifstream : leitura (2) ofstream : escrita

Leia mais

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

3.1 - Funções para manipular dados de entrada e saída padrão 1616161616161616161616161616161616161616161616161616 3- ENTRADA E SAÍDA EM C Os principais meios para executar operações de entrada e saída (E/S) são: Entrada e saída pelo console (ou padrão): teclado

Leia mais

Orientação a Objetos. Programação em C++

Orientação a Objetos. Programação em C++ Orientação a Objetos - Programação em C++ Arquivos Binários Prof. Dr. Jean Marcelo SIMÃO DAINF / UTFPR Monitor: Vitor C. M. Corrêa discente de Engenharia de Computação DAINF / DAELN Arquivos Binários Para

Leia mais

9/24/2014. Prof. André Backes

9/24/2014. Prof. André Backes Prof. André Backes 1 Arquivos Por que usar arquivos? Permitem armazenar grande quantidade de informação; Persistência dos dados (disco); Acesso aos dados poder ser não sequencial; Acesso concorrente aos

Leia mais

LINGUAGEM C: ARQUIVOS

LINGUAGEM C: ARQUIVOS LINGUAGEM C: ARQUIVOS Prof. André Backes Arquivos 2 Por que usar arquivos? Permitem armazenar grande quantidade de informação; Persistência dos dados (disco); Acesso aos dados poder ser não seqüencial;

Leia mais

Manipulação de Streams e arquivos

Manipulação de Streams e arquivos Manipulação de Streams e arquivos Prof. Leandro Tonietto Estruturas de Dados em C++ - Unisinos ltonietto@unisinos.br http://www.inf.unisinos.br/~ltonietto mar-09 Introdução Streams: Área de memória intermediária

Leia mais

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

Existe uma quantidade de informação que pode ser armazenada para resolver o problema. Arquivos Introdução As estruturas vistas anteriormente armazenam as informações na memória principal do computador. Nem sempre é conveniente. Problemas: A informação é perdida; As estruturas de dados são

Leia mais

Tratamento de Exceções, Multithreads e arquivos (em Java) Programação Orientada a Objetos

Tratamento de Exceções, Multithreads e arquivos (em Java) Programação Orientada a Objetos Tratamento de Exceções, Multithreads e arquivos (em Java) Programação Orientada a Objetos Nesta unidade vamos ver os últimos assuntos de interesse em java. O primeiro deles, bem simples, é o tratamento

Leia mais

Organização de Arquivos. SCE-183 Algoritmos e Estruturas de Dados II

Organização de Arquivos. SCE-183 Algoritmos e Estruturas de Dados II Organização de Arquivos SCE-183 Algoritmos e Estruturas de Dados II 1 Arquivos Ao construir uma estrutura de arquivos, estamos impondo uma organização aos dados Qual a diferença entre os termos stream

Leia mais

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

CAP. IX - MANIPULAÇÃO DE ARQUIVOS Generalidades sobre Arquivos. 9.2 Abertura e Fechamento de Arquivos. Operações com arquivos: CAP. IX - MANIPULAÇÃO DE ARQUIVOS 9.1 Generalidades sobre arquivos 9.2 Abertura e fechamento de arquivos 9.3 Arquivos textos e arquivos binários 9.4 Leitura e escrita em arquivos binários 9.5 Procura direta

Leia mais

Puca Huachi Vaz Penna

Puca Huachi Vaz Penna Aula 3 C++: variáveis e expressões aritméticas 2017/1 BCC201 Introdução à Computação Turmas 61, 62, 63, 64, 65 e 66, 32 e 33 Puca Huachi Vaz Penna Departamento de Computação Universidade Federal de Ouro

Leia mais

Introdução à linguagem C++

Introdução à linguagem C++ Estrutura de Dados e Algoritmos e Programação e Computadores II Aula 3: Introdução à linguagem C++ Introdução à linguagem C++ Vetores Estruturas Objetos Arquivos-texto 1 Vetores Vetores são uma séria de

Leia mais

Programação: Vetores

Programação: Vetores Programação de Computadores I Aula 09 Programação: Vetores José Romildo Malaquias Departamento de Computação Universidade Federal de Ouro Preto 2011-1 1/62 Motivação Problema Faça um programa que leia

Leia mais

Programação estruturada em C++: extensões ao C. João Pascoal Faria (versão original) Ana Paula Rocha (versão 2004/2005)

Programação estruturada em C++: extensões ao C. João Pascoal Faria (versão original) Ana Paula Rocha (versão 2004/2005) Programação estruturada em C++: extensões ao C João Pascoal Faria (versão original) Ana Paula Rocha (versão 2004/2005) FEUP - LEEC - AED - 2004/2005 1972 1978 1983 1988 1995 Breve historial Primeira versão

Leia mais

exatasfepi.com.br Informática C/C++ André Luís Duarte Feliz é o homem que acha sabedoria, e o homem que adquire entendimento; Provérbios 3:13

exatasfepi.com.br Informática C/C++ André Luís Duarte Feliz é o homem que acha sabedoria, e o homem que adquire entendimento; Provérbios 3:13 exatasfepi.com.br Informática C/C++ André Luís Duarte Feliz é o homem que acha sabedoria, e o homem que adquire entendimento; Provérbios 3:13 Conceitos Fundamentos Estrutura sequencial Estruturas de seleção

Leia mais

Programação Computacional C/C++

Programação Computacional C/C++ exatasfepi.com.br Programação Computacional C/C++ André Luís Duarte Feliz é o homem que acha sabedoria, e o homem que adquire entendimento; Provérbios 3:13 Conceitos Fundamentos Estrutura sequencial Estruturas

Leia mais

Faculdade de Computação

Faculdade de Computação Faculdade de Computação Programação Procedimental 13 Laboratório de Programação - Algoritmos Prof. Cláudio C. Rodrigues Prof. Fabíola Gonçalves I. Introdução a Arquivos A motivação para utilizar arquivos

Leia mais

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

Aula: ARQUIVOS. Introdução à Ciência da Computação I Simone Senger Souza. ICMC/USP São Carlos Aula: ARQUIVOS Introdução à Ciência da Computação I Simone Senger Souza ICMC/USP São Carlos Introdução As estruturas vistas anteriormente armazenam as informações na memória principal do computador. Nem

Leia mais

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

Aula 14 Oficina de Programação Tópicos Especiais em C: Arquivos. Profa. Elaine Faria UFU Aula 14 Oficina de Programação Tópicos Especiais em C: Arquivos Profa. Elaine Faria UFU - 2017 Uso da Memória Secundária Em muitos casos necessitamos da memória secundária (auxiliar), para armazenar informações

Leia mais

Introdução à Programação

Introdução à Programação Programação de Computadores Introdução à Programação Prof. Helton Fábio de Matos hfmatos@dcc.ufmg.br Agenda Algoritmo & Programa Variáveis Declaração de tipos Comando de entrada ou de leitura Comando de

Leia mais

1/24 FICHEIROS DE TEXTO

1/24 FICHEIROS DE TEXTO 1/24 FICHEIROS DE TEXTO Hardware de entrada/saída 2/24 Hardware de entrada/saída Grande variedade de dispositivos de E/S (Input/Output) - de memória: disco interno e externo, DVD, pen, CD,... - de transmissão:

Leia mais

Aula 4: Introdução à Linguagem C++

Aula 4: Introdução à Linguagem C++ CI208 - Programação de Computadores Aula 4: Introdução à Linguagem C++ Prof. MSc. Diego Roberto Antunes diegor@inf.ufpr.br www.inf.ufpr.br/diegor Universidade Federal do Paraná Setor de Ciências Exatas

Leia mais

Classes o Objetos. Classes, objetos, métodos e variáveis de instância

Classes o Objetos. Classes, objetos, métodos e variáveis de instância Classes o Objetos Um recurso comum de cada aplicativo feito até agora é que todas as instruções que realizavam tarefas localizavam-se no método main. Se você tornar parte de uma equipe de desenvolvimento

Leia mais

Algoritmos e Estruturas de Dados II IEC013

Algoritmos e Estruturas de Dados II IEC013 Algoritmos e Estruturas de Dados II IEC013 Linguagem C - Arquivos - Prof. César Melo cavmelo@dcc.ufam.edu.br Slides preparados pelo Prof. Leandro Galvão galvao@dcc.ufam.edu.br Conceitos iniciais Um arquivo

Leia mais

Computação L2. Linguagem C++ Observação: Material Baseado na Disciplina Computação Eletrônica.

Computação L2. Linguagem C++ Observação: Material Baseado na Disciplina Computação Eletrônica. Computação L2 Linguagem C++ ovsj@cin.ufpe.br Observação: Material Baseado na Disciplina Computação Eletrônica. Alfabeto São os símbolos ( caracteres ) permitidos na linguagem: Letras (maiúsculas e minúsculas);

Leia mais

Instituto Federal de Educação, Ciência e Tecnologia do RN Câmpus Currais Novos. LINGUAGEM C++ VARIÁVEIS COMPOSTAS Arrays Aula I

Instituto Federal de Educação, Ciência e Tecnologia do RN Câmpus Currais Novos. LINGUAGEM C++ VARIÁVEIS COMPOSTAS Arrays Aula I LINGUAGEM C++ VARIÁVEIS COMPOSTAS Arrays Aula I Prof. Bruno E. G. Gomes Uma variável em um algoritmo pode ser vista como uma gaveta. A declaração de uma variável reserva uma gaveta (posição) de um certo

Leia mais

Linguagem C++ Estruturas de controle Parte II Estruturas de repetição

Linguagem C++ Estruturas de controle Parte II Estruturas de repetição Fundamentos de Programação Linguagem C++ Estruturas de controle Parte II Estruturas de repetição Prof. Bruno E. G. Gomes IFRN 1 Estruturas de Controle Permitem o controle da sequência de execução de um

Leia mais

Ambiente de desenvolvimento

Ambiente de desenvolvimento Linguagem C Ambiente de desenvolvimento Um programa em C passa por seis fases até a execução: 1) Edição 2) Pré-processamento 3) Compilação 4) Linking 5) Carregamento 6) Execução Etapa 1: Criação do programa

Leia mais

C com introdução a OO

C com introdução a OO ... Centro Integrado de Tecnologia da Informação C com introdução a OO ... Centro Integrado de Tecnologia da Informação Aula 9 Ronald Dener - Instrutor Matheus Soares - Monitor 17 / outubro 17 / outubro

Leia mais

PROGRAMAÇÃO COMPUTACIONAL

PROGRAMAÇÃO COMPUTACIONAL PROGRAMAÇÃO COMPUTACIONAL LINGUAGEM C/C++ REVISÃO 1 ANDRÉ LUÍS DUARTE Honra a teu pai e a tua mãe (que é o primeiro mandamento com promessa), para que te vá bem, e sejas de longa vida sobre a terra.(ef

Leia mais

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

Computação Eletrônica. Aula 12 Arquivos Texto e Binário. Prof: Luciano Barbosa. CIn.ufpe.br Computação Eletrônica Aula 12 Arquivos Texto e Binário Prof: Luciano Barbosa Relembrando a Arquitetura Básica de um Computador Até agora, toda a informação armazenada por nossos programas estava na memória

Leia mais

Linguagem C Princípios Básicos (parte 1)

Linguagem C Princípios Básicos (parte 1) Linguagem C Princípios Básicos (parte 1) Objetivos O principal objetivo deste artigo é explicar alguns conceitos fundamentais de programação em C. No final será implementado um programa envolvendo todos

Leia mais

Aula 27: Estruturas heterogêneas e alocação dinâmica

Aula 27: Estruturas heterogêneas e alocação dinâmica Aula 27: Estruturas heterogêneas e alocação dinâmica Introdução a Programação Túlio Toffolo & Puca Huachi http://www.toffolo.com.br BCC201 2018/2 Departamento de Computação UFOP Aulas anteriores Memória

Leia mais

Módulo 2. Acesso a Arquivos. Métodos e Algoritmos Computacionais C++ (Rone Ilídio)

Módulo 2. Acesso a Arquivos. Métodos e Algoritmos Computacionais C++ (Rone Ilídio) Módulo 2 Acesso a Arquivos Métodos e Algoritmos Computacionais C++ (Rone Ilídio) Manipulação de Objetos iostream Bytes armazenados na memória Tipos: Arquivos com caracteres: textos Arquivos binários: programas,

Leia mais

Programação de Computadores II

Programação de Computadores II Programação de Computadores II 1. Programação Básica 2019.1 Slides adaptados do material de Karina Mochetti Problema, Algoritmo, Programa Um programa de computador é a implementação de um algoritmo para

Leia mais

Aula 29: Arquivos binários

Aula 29: Arquivos binários Aula 29: Arquivos binários Introdução a Programação Túlio Toffolo & Puca Huachi http://www.toffolo.com.br BCC201 2018/2 Departamento de Computação UFOP Aulas anteriores Memória Ponteiro Utilização de ponteiros

Leia mais

Programação de Computadores I Introdução ao C PROFESSORA CINTIA CAETANO

Programação de Computadores I Introdução ao C PROFESSORA CINTIA CAETANO Programação de Computadores I Introdução ao C PROFESSORA CINTIA CAETANO Introdução Criada em 1972, por Dennis Ritchie; Centro de Pesquisas da Bell Laboratories; Para utilização no S.O. UNIX; C é uma linguagem

Leia mais

Arquivos O QUE É, COMO LER E MANIPULAR

Arquivos O QUE É, COMO LER E MANIPULAR Arquivos O QUE É, COMO LER E MANIPULAR Arquivos Variáveis oferecem armazenamento de dados temporariamente Os dados são perdidos quando o escopo da variável é finalizado ou quando o programa termina Arquivos

Leia mais

INTRODUÇÃO À LINGUAGEM C

INTRODUÇÃO À LINGUAGEM C INTRODUÇÃO À LINGUAGEM C Prof. Bruno Feijó, Dept. de Informática, PUC-Rio (2018) C foi criado no início da década de 70, quando os programas mais eficientes eram escritos em linguagem Assembly, bem próxima

Leia mais

Organização de Arquivos. Leandro C. Cintra M.C.F. de Oliveira Thiago A. S. Pardo Cristina D. A. Ciferri

Organização de Arquivos. Leandro C. Cintra M.C.F. de Oliveira Thiago A. S. Pardo Cristina D. A. Ciferri Organização de Arquivos Leandro C. Cintra M.C.F. de Oliveira Thiago A. S. Pardo Cristina D. A. Ciferri Organização de Arquivos Informações em arquivos são, em geral, organizadas logicamente em campos e

Leia mais

Centro Universitário Franciscano Curso de Sistemas de Informação Disciplina de algoritmos e programação II. Ponteiros

Centro Universitário Franciscano Curso de Sistemas de Informação Disciplina de algoritmos e programação II. Ponteiros Centro Universitário Franciscano Curso de Sistemas de Informação Disciplina de algoritmos e programação II Ponteiros Profa.: Simone Ceolin Slides (Prof.Tiago Rios da Rocha) Primeiro Semestre 2011 Sumário

Leia mais

Arquitetura Von Neumann Dados e instruções são obtidos da mesma forma, simplificando o desenho do microprocessador;

Arquitetura Von Neumann Dados e instruções são obtidos da mesma forma, simplificando o desenho do microprocessador; 1 Microprocessador Um microprocessador é um circuito eletrônico capaz de realizar diversas tarefas conforme os comandos específicos. Para isso ele deve ler esses comandos da memória de programa (ROM) e

Leia mais

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

Computação 2. Aula 8. Profª. Fabiany Arquivos Computação 2 Aula 8 Arquivos Profª. Fabiany fabianyl@utfpr.edu.br E/S com Arquivos A linguagem C não possui nenhum comando de E/S. Todas as operações de E/S ocorrem mediante chamadas a funções de biblioteca

Leia mais

ANHANGUERA ESTRUTURA DE DADOS AULA 04 MATRIZES, LISTAS E ALOCAÇÃO DINÂMICA. Prof. Thomás da Costa

ANHANGUERA ESTRUTURA DE DADOS AULA 04 MATRIZES, LISTAS E ALOCAÇÃO DINÂMICA. Prof. Thomás da Costa ANHANGUERA 2015.2 ESTRUTURA DE DADOS AULA 04 Prof. Thomás da Costa thomascosta@aedu.com O que é: Matrizes São vetores que possuem duas ou mais dimensões para armazenar valores. Uma matriz de duas dimensões,

Leia mais

PROGRAMAS BÁSICOS EM C++ Disciplina: Introdução à Ciência da Computação Prof. Modesto Antonio Chaves Universidade estadual do Sudoeste da Bahia

PROGRAMAS BÁSICOS EM C++ Disciplina: Introdução à Ciência da Computação Prof. Modesto Antonio Chaves Universidade estadual do Sudoeste da Bahia PROGRAMAS BÁSICOS EM C++ Disciplina: Introdução à Ciência da Computação Prof. Modesto Antonio Chaves Universidade estadual do Sudoeste da Bahia Calculo da área de um triângulo Algoritmo Área Var base,

Leia mais

Programação científica C++

Programação científica C++ Programação científica C++ NIELSEN CASTELO DAMASCENO Slide 2 Expressões Combinação de dados e operadores que resulta em um valor. expressão x = 2 * y + 4; variável operador constante Memória do computador

Leia mais

Aula 12: Funções. CI208 - Programação de Computadores. Prof. MSc. Diego Roberto Antunes

Aula 12: Funções. CI208 - Programação de Computadores. Prof. MSc. Diego Roberto Antunes CI208 - Programação de Computadores Aula 12: Funções Prof. MSc. Diego Roberto Antunes diegor@inf.ufpr.br www.inf.ufpr.br/diegor Universidade Federal do Paraná Setor de Ciências Exatas Departamento de Informática

Leia mais

LISTA DE EXERCÍCIOS 2

LISTA DE EXERCÍCIOS 2 UNIVERSIDADE FEDERAL RURAL DO SEMI-ÁRIDO CURSO DE CIÊNCIA DA COMPUTAÇÃO PROGRAMAÇÃO DE COMPUTADORES 1. TIPOS COMPOSTOS DE DADOS LISTA DE EXERCÍCIOS 2 1. Considerando as declarações abaixo, responda dizendo

Leia mais

CCO 016 Fundamentos de Programação

CCO 016 Fundamentos de Programação CCO 016 Fundamentos de Programação Prof. Roberto Affonso da Costa Junior Universidade Federal de Itajubá Aula 05 Entrada de dados Leia scanf ou cin Entrada de Dados Entrada de dados compreende a operação

Leia mais

Aula 3 Constantes e funções de E/S

Aula 3 Constantes e funções de E/S Programação I Aula 3 e funções de E/S Prof. Laura Silva de Assis e Prof. Luis Carlos Retondaro Engenharia de Computação 2o Período CEFET/RJ - Centro Federal de Educação Tecnológica Celso Suckow da Fonseca

Leia mais

Objectivos. Observar os tipos fornecidos pelo C++ Explicar as regras sintácticas para nomes de identificadores Estudar variáveis e constantes

Objectivos. Observar os tipos fornecidos pelo C++ Explicar as regras sintácticas para nomes de identificadores Estudar variáveis e constantes Tipos de Dados Objectivos Observar os tipos fornecidos pelo C++ São dados alguns exemplos Explicar as regras sintácticas para nomes de identificadores Estudar variáveis e constantes O que são Como se distinguem

Leia mais

Processamento de Arquivos. Escrita Leitura Ponteiros de Posição Arquivos de Acesso Aleatório Exemplos

Processamento de Arquivos. Escrita Leitura Ponteiros de Posição Arquivos de Acesso Aleatório Exemplos Processamento de Arquivos Escrita Leitura Ponteiros de Posição Arquivos de Acesso Aleatório Exemplos 1 O armazenamento em variáveis e vetores é temporário; Arquivos são utilizados para persistência de

Leia mais

Aula 01 Algoritmos e lógica de programação e introdução ao C++

Aula 01 Algoritmos e lógica de programação e introdução ao C++ Aula 01 Algoritmos e lógica de programação e introdução ao C++ Autor: José Martins de Castro Neto Carga Horária: 2h 21 de julho de 2015 1 Algoritmo e lógica de programação Ementa do curso 1. Definições

Leia mais

Aula 3 Primeiros programas

Aula 3 Primeiros programas Aula 3 Primeiros programas FACOM-UFMS 2012 OBJETIVOS DA AULA Introdução ao CodeBlocks; Criação dos primeiros programas; Esta aula foi baseada nos capítulos 3 e 4 da apostila de Programação de Computadores

Leia mais

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

INFORMÁTICA APLICADA AULA 05 LINGUAGEM DE PROGRAMAÇÃO C++ UNIVERSIDADE FEDERAL RURAL DO SEMI-ÁRIDO CURSO: Bacharelado em Ciências e Tecnologia INFORMÁTICA APLICADA AULA 05 LINGUAGEM DE PROGRAMAÇÃO C++ Profª ª Danielle Casillo LAÇOS Laços são comandos da linguagem

Leia mais

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

Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria USP - ICMC - SSC SSC 0501-1o. Semestre 2015 Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria Prof. Fernando Santos Osório Email: fosorio [at] icmc. usp. br, gmail. com Página Pessoal: http://www.icmc.usp.br/~fosorio/

Leia mais

Comandos de controle de fluxo: if / for / while / do while.

Comandos de controle de fluxo: if / for / while / do while. Conceitos básicos do C. 2 Introdução às funções. Entrada e saída. Comandos de controle de fluxo: if / for / while / do while. Variáveis, constantes, operadores e expressões Switch / break / matrizes e

Leia mais

Linguagem C. André Tavares da Silva.

Linguagem C. André Tavares da Silva. Linguagem C André Tavares da Silva dcc2ats@joinville.udesc.br Variáveis Posição nomeada de memória que é usada para guardar um valor que pode ser modificado pelo programa. Todas as variáveis devem ser

Leia mais

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

Departamento de Sistemas de Computação Universidade de São Paulo Introdução a Ciência de Computação I. Aula 13 Arquivos Departamento de Sistemas de Computação Universidade de São Paulo Introdução a Ciência de Computação I Aula 13 Arquivos Responsável Seiji Isotani, Rafaela V. Rocha sisotani@icmc.usp.br rafaela.vilela@gmail.com

Leia mais

Leitura Segura de Strings

Leitura Segura de Strings Leitura Segura de Strings As funções da biblioteca padrão de C que podem ser usadas para leitura de strings não são suficientemente adequadas para esta finalidade básica. Nesta seção, serão descritos alguns

Leia mais

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

Programação de Computadores I Arquivos na Linguagem C PROFESSORA CINTIA CAETANO Programação de Computadores I Arquivos na Linguagem C PROFESSORA CINTIA CAETANO Introdução As informações que os programas utilizam são perdidas quando eles são finalizados ou quando o computador é desligado.

Leia mais

Programação em C. Variáveis e Expressões. Universidade Federal do Rio Grande do Norte Departamento de Engenharia de Computação e Automação

Programação em C. Variáveis e Expressões. Universidade Federal do Rio Grande do Norte Departamento de Engenharia de Computação e Automação Universidade Federal do Rio Grande do Norte Departamento de Engenharia de Computação e Automação Programação em C Variáveis e Expressões DCA0800 Algoritmos e Lógica de Programação Heitor Medeiros Florencio

Leia mais

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

Programação Computacional Aula 17: Manipulação de arquivos Programação Computacional Aula 17: Manipulação de arquivos Profa. Madeleine Medrano madeleine@icte.uftm.edu.br Arquivos de registros Os dados manipulados pelos nossos programas (dados de entrada, dados

Leia mais

Métodos Computacionais. Operadores, Expressões Aritméticas e Entrada/Saída de Dados

Métodos Computacionais. Operadores, Expressões Aritméticas e Entrada/Saída de Dados Métodos Computacionais Operadores, Expressões Aritméticas e Entrada/Saída de Dados Tópicos da Aula Hoje aprenderemos a escrever um programa em C que pode realizar cálculos Conceito de expressão Tipos de

Leia mais

INTRODUÇÃO À LINGUAGEM C

INTRODUÇÃO À LINGUAGEM C INTRODUÇÃO À LINGUAGEM C Prof. Bruno Feijó, Dept. de Informática, PUC-Rio (2017) C foi criado no início da década de 70, quando os programas mais eficientes eram escritos em linguagem Assembly, bem próxima

Leia mais

Aula 26: Estruturas heterogêneas

Aula 26: Estruturas heterogêneas Aula 26: Estruturas heterogêneas Introdução a Programação Túlio Toffolo & Puca Huachi http://www.toffolo.com.br BCC201 2018/2 Departamento de Computação UFOP Aulas anteriores Memória Ponteiro Utilização

Leia mais

Aula 01 Algoritmos e lógica de programação e introdução ao C++

Aula 01 Algoritmos e lógica de programação e introdução ao C++ Aula 01 Algoritmos e lógica de programação e introdução ao C++ Autor: Max Rodrigues Marques Carga Horária: 2h 21 de julho de 2015 1 Algoritmo e lógica de programação Ementa do curso 1. Definições de algoritmo

Leia mais

LINGUAGEM C: ARQUIVOS

LINGUAGEM C: ARQUIVOS LINGUAGEM C: ARQUIVOS Prof. André Backes ARQUIVOS Por que usar arquivos? Permitem armazenar grande quantidade de informação; Persistência dos dados (disco); Acesso aos dados poder ser não seqüencial; Acesso

Leia mais

Linguagem C Controle do Fluxo de Execução. Lógica de Programação

Linguagem C Controle do Fluxo de Execução. Lógica de Programação Linguagem C Controle do Fluxo de Execução Lógica de Programação Caro(a) aluno(a), Aqui começaremos a escrever os nossos primeiros programas em uma Linguagem de Programação. Divirta-se!!! Estrutura Seqüencial

Leia mais

Fundamentos de Programação Linguagem C++ Entrada e saída com arquivos

Fundamentos de Programação Linguagem C++ Entrada e saída com arquivos Fundamentos de Programação Linguagem C++ Entrada e saída com arquivos Prof.: Bruno E. G. Gomes IFRN 1 Introdução Entrada e saída de dados pode ser feita: Para dispositivo de entrada/saída (monitor, impressora,

Leia mais

BCC221 Programação Orientada a Objetos. Prof. Marco Antonio M. Carvalho 2014/2

BCC221 Programação Orientada a Objetos. Prof. Marco Antonio M. Carvalho 2014/2 BCC221 Programação Orientada a Objetos Prof. Marco Antonio M. Carvalho 2014/2 Site da disciplina: http://www.decom.ufop.br/marco/ Moodle: www.decom.ufop.br/moodle Lista de e- mails: bcc221- decom@googlegroups.com

Leia mais

Programação II. Arquivos - Conceito. Arquivos

Programação II. Arquivos - Conceito. Arquivos Programação II Arquivos Jocélio Passos joceliodpassos@bol.com.br C Comp Total, Cap 9 Espaço para armazenar dados em memória auxiliar (não volátil) Arquivos em C podem ser também terminais ou impressoras

Leia mais

Template de classe. class vetor { int *arranjo; int limite; public: vetor(int=100); int & operator[ ](int n); };

Template de classe. class vetor { int *arranjo; int limite; public: vetor(int=100); int & operator[ ](int n); }; Template de classe! Idéia é semelhante ao template de função! Usando a classe vetor que foi desenvolvida anteriormente: class vetor { int *arranjo; int limite; public: vetor(int=100); int & operator[ ](int

Leia mais

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

Programação. MEAer e LEE. Manipulação de ficheiros de texto. Bertinho Andrade da Costa. Instituto Superior Técnico. 2010/2011 1º Semestre Programação MEAer e LEE Bertinho Andrade da Costa 2010/2011 1º Semestre Instituto Superior Técnico Manipulação de ficheiros de texto Programação 2010/2011 IST-DEEC Manipulação de Ficheiros 1 Sumário Ficheiros

Leia mais

ALGORITMOS, ARQUITETURA E ARDUINO

ALGORITMOS, ARQUITETURA E ARDUINO INOVAÇÃO TECNOLÓGICA E EMPREENDEDORISMO ALGORITMOS, ARQUITETURA E ARDUINO Prof. Dr. Daniel Caetano 2017-2 Objetivos Rever alguns conceitos iniciais de algoritmos Tomar contato com alguns conceitos de arquitetura

Leia mais

Introdução à Programação. Operadores, Expressões Aritméticas e Entrada/Saída de Dados

Introdução à Programação. Operadores, Expressões Aritméticas e Entrada/Saída de Dados Introdução à Programação Operadores, Expressões Aritméticas e Entrada/Saída de Dados Programa em C #include int main main ( ) { Palavras Reservadas } float celsius ; float farenheit ; celsius

Leia mais

Linguagem de Programação C. Arquivos

Linguagem de Programação C. Arquivos Arquivos Cristiano Lehrer Introdução Em C um arquivo é apenas um conjunto de bytes colocados uns após os outros de forma sequencial: Utilização de arquivos: Fonte de dados para o programa: Trata-se de

Leia mais

Disciplina de Algoritmos e Programação

Disciplina de Algoritmos e Programação Disciplina de Algoritmos e Programação Aula Passada Prática com declaração e inicialização de variáveis Capacidade de representação (estouro de representação) Tamanho ocupado pela variável na memória (comando

Leia mais

Por que programar? Programação de Computadores Introdução a C++ É tudo questão de automatizar coisas. Alan de Freitas

Por que programar? Programação de Computadores Introdução a C++ É tudo questão de automatizar coisas. Alan de Freitas Por que programar? Programação de Computadores Introdução a C++ Utilizar computadores é claramente uma vantagem em nossas vidas... Nos ajuda a comunicar Nos ajuda a fazer planos Nos permite trabalhar menos

Leia mais

Estruturas de Repetição

Estruturas de Repetição Algoritmos e Estruturas de Dados I (DCC/003) Estruturas de Repetição Aula Tópico 4 (while, for) 1 Problema 10 Suponha que soma (+) e subtração (-) são as únicas operações disponíveis em C. Dados dois números

Leia mais

Linguagem C Entrada/Saída (console)

Linguagem C Entrada/Saída (console) Linguagem C Entrada/Saída (console) Objetivos Nos artigos anteriores foram utilizadas as funções scanf() e printf(), porém não entramos em maiores detalhes. Agora estudaremos essas e outras funções de

Leia mais

Introdução à Programação. Introdução a Linguagem C. Prof. José Honorato F. Nunes

Introdução à Programação. Introdução a Linguagem C. Prof. José Honorato F. Nunes Introdução à Programação Introdução a Linguagem C Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br Resumo da aula Introdução Variáveis Tipos de dados Operadores e Expressões: Operadores

Leia mais

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

USP - ICMC - SSC SSC o. Semestre Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria USP - ICMC - SSC SSC 0501-1o. Semestre 2011 Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria Prof. Fernando Santos Osório Email: fosorio [at] icmc. usp. br, gmail. com Página Pessoal: http://www.icmc.usp.br/~fosorio/

Leia mais

Linguagem C: Introdução

Linguagem C: Introdução Linguagem C: Introdução Linguagem C É uma Linguagem de programação genérica que é utilizada para a criação de programas diversos como: Processadores de texto Planilhas eletrônicas Sistemas operacionais

Leia mais

Programação Básica. Estrutura de um algoritmo

Programação Básica. Estrutura de um algoritmo Programação Básica Estrutura de um algoritmo Código-fonte Como vimos na aula anterior um algoritmo pode ser representado usando um fluxograma Um algoritmo pode também ser representado usando texto Esse

Leia mais

Programação I A Linguagem C. Prof. Carlos Alberto

Programação I A Linguagem C. Prof. Carlos Alberto Programação I A Linguagem C Prof. Carlos Alberto carlos.batista@facape.br carlos36_batista@yahoo.com.br 2 Origem A linguagem C foi desenvolvida em 1972, nos Laboratórios Bell, por Dennis Ritchie. Implementada

Leia mais

Outline. 33. Manipulação de arquivos DIM

Outline. 33. Manipulação de arquivos DIM Outline 33. Manipulação de arquivos DIM031 015.1 Leitura e escrita 3 s DIM031 33. Manipulação de arquivos 015.1 1 / 4 DIM031 33. Manipulação de arquivos 015.1 / 4 Arquivo = entidade de armazenamento de

Leia mais

ALGORITMOS E ESRUTRA DE DADOS I. Ponteiros Passagem por Valor e Referência Alocação de Memória

ALGORITMOS E ESRUTRA DE DADOS I. Ponteiros Passagem por Valor e Referência Alocação de Memória ALGORITMOS E ESRUTRA DE DADOS I Ponteiros Passagem por Valor e Referência Alocação de Memória 2 Agenda Ponteiros Conceitos gerais O que é Ponteiro? Declaração de Ponteiros Operadores para Ponteiros Exemplos

Leia mais

Aula 10 Alocação Dinâmica de Memória Listas Encadeadas. prof Leticia Winkler

Aula 10 Alocação Dinâmica de Memória Listas Encadeadas. prof Leticia Winkler Aula 10 Alocação Dinâmica de Memória Listas Encadeadas prof Leticia Winkler 1 Prof. Leticia Winkler 2 Alocação de Memória Reservar na memória (principal), o espaço para guardar a informação através da

Leia mais