Flávio Augusto de FreitasAlgoritmos e Estruturas de Dados III usando C/C++http://flavioaf.blogspot.comC/C++Tutorial 1 (usa...
Clique no botão      para criar uma nova pasta1 INTRODUÇÃO                                        na Área de Trabalho. Dig...
3.2 EDITANDO O TEXTO    Notou a linha destacada (com fundo azulado).    Esta a linha corrente de edição do texto. Use as  ...
4 UM EXEMPLO COMPLETO                              Observe que na parte em que editamos o código,                         ...
Caso alguma coisa não esteja salva, o Dev-C++       unidade de fita magnética, um disco, uma porta    mostrará a seguinte ...
operacional e onde possa ser incluída uma           Entretanto, você verá frequentemente escrito    especificação de camin...
int, mas somente o caractere de mais baixa            Obviamente, o mesmo método pode ser aplicado    ordem é usado.      ...
função ferror() deve ser chamada imediatamente        // Lê arquivos e exibe-os na tela.    após cada operação com o arqui...
lido, ele fará parte da string (diferente de gets()).   Quando o arquivo for aberto para dados binários,    A string resul...
/* lê uma matriz em disco */                                 O seguinte código lê o 235º byte do arquivo    #include<stdio...
void display(long int numlido) {                             /* localiza uma palavra especificada pela linha de     long i...
9.1 FPRINTF() E FSCANF()                             Corra para o próximo tutorial.     Comportam-se como printf() e scanf...
Upcoming SlideShare
Loading in …5
×

Tutorial dev cpp 001 - criação, leitura e alteração de arquivos

11,736 views

Published on

Algoritmos e Estruturas de Dados III

Published in: Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
11,736
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
274
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Tutorial dev cpp 001 - criação, leitura e alteração de arquivos

  1. 1. Flávio Augusto de FreitasAlgoritmos e Estruturas de Dados III usando C/C++http://flavioaf.blogspot.comC/C++Tutorial 1 (usando Dev-C++ versão 4.9.9.2) 2012
  2. 2. Clique no botão para criar uma nova pasta1 INTRODUÇÃO na Área de Trabalho. Digite o nome ProjetoOlaEsta série de tutoriais foi escrita usando o e pressione a tecla Enter. Dê dois cliques naMicrosoft Windows 7 Ultimate e o Bloodshed pasta ProjetoOla, recém criada. Em seguida, naDev-C++ versão 4.9.9.2, que pode ser baixada em mesma janela, observe que o projeto já tem nomehttp://www.bloodshed.net. (Ola.dev).2 EXECUTANDO O DEV-C++ Clique no botão Iniciar, depois clique em Todos Clique no botão Salvar. A seguinte tela é os programas; em mostrada: seguida clique em Bloodshed Dev-C++; finalmente clique em Dev-C++. 3 O AMBIENTE DO DEV-C++ 3.1 CONFIGURANDO A LINGUAGEM Meu Dev-C++ está em inglês, o que faço? Clique no menu Tools, 3.1 ENTENDENDO O AMBIENTE DO depois clique em Environment Options. Na DEV-C++ janela que se abre, clique Observe na tela que há um menu principal e na aba Interface. Onde algumas barras de ferramentas. Logo abaixo a está escrito English janela é dividida em duas partes. (Original), mude para Portuguese (Brazil) e A parte da esquerda é o navegador do projeto. clique no botão Ok. Clique no sinal de + ao lado de Ola. Veja que o Dev-C++ mostra os arquivos que compõem o 3.2 CRIANDO SEU projeto. Em nosso caso, há apenas o main.cpp. PRIMEIRO APLICATIVO A parte da direita mostra o arquivo selecionado. Depois de executar o Observe que a aba mostra o nome do arquivo eprograma, clique no menu Arquivo, depois um sinal de (*).aponte o mouse para a opção Novo e clique emProjeto... . Na janela que se abre, clique em Isto significa que ainda não salvamos o arquivo corrente. Vamos salvá-lo agora. Clique no menuAinda na mesma janela, onde está escrito Arquivo, depois clique em Salvar. Na caixa queProjeto1, mude para Ola. Clique no botão Ok. aparece, não modifique nada, apenas clique noAgora, vamos salvar previamente nosso projeto. botão Salvar. Observe que o (*) sumiu. SempreNa janela que se abriu, no lado esquerdo, clique que alterarmos o código o Dev-C++ mostra o (*),no botão Área de Trabalho (ou Desktop, se estiver indicando que precisamos salvar o arquivo.escrito).
  3. 3. 3.2 EDITANDO O TEXTO Notou a linha destacada (com fundo azulado). Esta a linha corrente de edição do texto. Use as teclas de setas do teclado para mover-se pelo texto. Experimente agora. Para inserir texto basta deslocar o cursor usando as teclas de setas e digitar. Mas não faça nada ainda. Veja também que várias palavras aparecem ou coloridas, ou em negrito. O Dev-C++ destaca as palavras reservadas da linguagem com diversas cores e negritos ou itálicos. Assim você não se perde com muita frequência. Continue lendo. 3.3 EXECUTANDO O PROGRAMA Mas o que está escrito? O que são estes códigos? Vamos executar o programa e ver o que acontece. #include <cstdlib> Clique no menu Executar e depois em Compilar #include <iostream> & Executar, como abaixo: Estas duas linhas incluem as bibliotecas de códigos necessárias para que o programa execute. Cada programa terá tantas bibliotecas quantas forem preciso. Há centenas delas. using namespace std; Isto é padrão no Dev-C++. Todo programa deste tutorial terá esta linha de código. int main(int argc, char *argv[]) Esta é a declaração da função main. Todo programa em C/C++ tem pelo menos uma função com o nome main. Isto é obrigatório. Ou pressione F9, que é a tecla de atalho. Aliás, Vamos analisar esta linha: vários menus têm alguma tecla de atalho. Aprenda as principais: Ctrl-S salva o arquivo O int, diz que a função main deve retornar um selecionado; Ctrl-F localiza texto; Para compilar e valor inteiro ao final da execução. Isto é feito pela executar o programa, basta pressionar F9, sem linha de código return EXIT_SUCCESS;. Entre ter de ir até o menu Executar. Após a execução, a parênteses existem dois argumentos, que são seguinte tela se apresenta: valores que podem ser passados para o programa, quando ele é executado. Aqui int argc indica quantos argumentos foram passados e char *argv[] é a lista de argumentos que foram passados. Finalmente system("PAUSE"); indica ao compilador para mostrar uma mensagem padronizada do sistema operacional. É aquela mensagem “Pressione qualquer tecla para continuar. . .” que apareceu quando você executou o programa. Pressione qualquer tecla e o programa termina, voltando ao Dev-C++.1
  4. 4. 4 UM EXEMPLO COMPLETO Observe que na parte em que editamos o código, uma linha ficou marcada com fundo vermelho Modifique o código do programa para que fique escuro. É a linha onde o Dev-C++ encontrou um como na imagem abaixo: erro. Mas que erro? Abaixo da janela de código, observe a linha destacada com fundo cinza. Na coluna Linha, vemos qual linha está o erro encontrado (linha 11). Na coluna Mensagem, podemos ler a mensagem que indica que o Dev-C++ não encontrou a função ‘prinf’. Voltando ao código, descobrimos o erro: digitamos incorretamente o nome da função printf (faltando a letra t) e o Dev-C++ nos avisou. Basta corrigir e tentar compilar novamente, pressionando F9. Para ver um erro ocorrendo, experimente trocar a palavra char por Após a digitação, pressione Ctrl-S para salvar o chr e tente executar novamente o programa. arquivo. Pressione F9 para executar o programa. A seguinte janela aparece: Se o programa compilar e executar corretamente, você deverá ver uma tela preta, com uma mensagem solicitando o seu nome: Insira o seu nome: Digite seu nome (Flavio, por exemplo) e pressione Enter. Em seguida, o programa solicitará sua idade: Insira a sua idade: Digite sua idade (42, por exemplo) e pressione Enter. Em seguida o programa mostra uma mensagem, parecida com o exemplo abaixo. Ela mostra o progresso da compilação. É importante você observar as partes O seu nome eh Flavio e tem 42 anos. Pressione qualquer tecla para continuar. . . e Pressione qualquer tecla, Enter, por exemplo, e o que mostram se houve erros (Errors) ou avisos programa termina e retorna ao compilador. (Warnings), respectivamente. Avisos não precisam ser levados tão a sério, ao menos por 5 ENDENTAÇÃO enquanto para você, mas erros sim, pois É o alinhamento do texto. Observe que o código impedem o programa de executar. Caso haja um entre { } está deslocado para a direita. Isto é ou mais erros, após a compilação, o compilador importante para a visualização e entendimento se mostrará assim: do código escrito. Quanto maior for seu código, ou seja, quanto mais linhas de código tiver seu programa, mais importante será a endentação. 6 SAINDO DO DEV-C++ Agora que terminamos este programa, podemos sair do ambiente do Dev-C++. Para isto, clique no menu Arquivo e depois clique na opção Sair.2
  5. 5. Caso alguma coisa não esteja salva, o Dev-C++ unidade de fita magnética, um disco, uma porta mostrará a seguinte tela: serial, etc. Adotaremos esta nomenclatura aqui. Um ponteiro de arquivo é uma variável-ponteiro do tipo FILE que é definida em stdio.h. Para ler ou escrever em um arquivo de disco, o programa deve declarar uma (ou mais de uma se formos trabalhar com mais de um arquivo simultaneamente) variável ponteiro de arquivo. Para obter uma variável ponteiro de arquivo, usa- se uma declaração semelhante a esta ao Basta clicar no botão Yes para o Dev-C++ salvar declararmos as demais variáveis do programa: o arquivo e terminar. Se desistir de sair do Dev- FILE *fp; C++ basta clicar no botão Cancel e você continuará com o Dev-C++ aberto. onde fp é o nome que escolhemos para a variável (podia ser qualquer outro). 7 REABRINDO O ÚLTIMO FUNÇÕES MAIS COMUNS DE ARQUIVO PROJETO Função Operação Entre novamente no Dev-C++ (se tiver esquecido, fopen() Abre um fluxo volte ao tópico número 2). Com o Dev-C++ aberto, fclose() Fecha um fluxo clique no menu Arquivo e depois aponte o mouse putc() Escreve um caractere para um fluxo para a opção Reabrir. Clique na opção com o getc() Lê um caractere para um fluxo número 0 (zero). Pronto, reabrimos o projeto Ola. fseek() Procura por um byte especificado no fluxo Se não estiver vendo o código do programa, clique fprintf() É para um fluxo aquilo que printf() é no sinal de + ao lado de Ola (lado esquerdo da para o console tela, no navegador de projeto), depois clique em fscanf() É para um fluxo aquilo que scanf() é main.cpp, que aparece embaixo de Ola. O código para o console deve aparecer no lado direito. feof() Retorna verdadeiro se o fim do arquivo é encontrado 8 ENTRADA E SAÍDA DE DISCO ferror() Retorna verdadeiro se ocorreu um erro fread() Lê um bloco de dados de um fluxo Agora que já relembramos o uso do DevC++ e um fwrite() Escreve um bloco de dados para um pouquinho de linguagem C/C++, vamos ao que fluxo realmente interessa nesse tutorial, ou seja, rewind() Reposiciona o localizador de posição de trabalhar com arquivos em disco. arquivo no começo do arquivo remove() Apaga um arquivo 8.1 O PONTEIRO DE ARQUIVO : A linha comum que une o sistema de E/S de 8.2 ABRINDO UM ARQUIVO disco do DevC++ é o ponteiro de arquivo. Um A função fopen() serve a dois propósitos. ponteiro de arquivo é um ponteiro para uma área Primeiro, ela abre um fluxo para uso e liga um na memória (buffer) onde estão contidos vários arquivo com ele. Segundo, retorna o ponteiro de dados sobre o arquivo a ler ou escrever, tais arquivo associado àquele arquivo. Mais como o nome do arquivo, estado e posição frequentemente, e para o resto desta discussão, o corrente. O buffer apontado pelo ponteiro de arquivo é um arquivo em disco. A função fopen() arquivo é a área intermediária entre o arquivo no tem este protótipo: disco e o programa. FILE *fopen(char *nome_de_arquivo, char *modo); Este buffer intermediário entre arquivo e programa é chamado fluxo, e no jargão dos onde modo é um string contendo o estado programadores é comum falar em funções que desejado para abertura. O nome do arquivo deve operam fluxos em vez de arquivos. Isto se deve ao ser um string de caracteres que compreende um fato de que um fluxo é uma entidade lógica nome de arquivo válido para o sistema genérica, que pode estar associada a uma3
  6. 6. operacional e onde possa ser incluída uma Entretanto, você verá frequentemente escrito especificação de caminho (PATH). assim: Como determinado, a função fopen() retorna um FILE *out; ponteiro de arquivo que não deve ter o valor alterado pelo seu programa. Se um erro ocorre if((out=fopen("test","w"))==NULL) { quando se está abrindo um arquivo, fopen() puts("não posso abrir o arquivon"); retorna um nulo. exit(1); } Como a Tabela abaixo mostra, um arquivo pode ser aberto ou em modo texto ou em modo A macro NULL é definida em STDIO.H. Esse binário. No modo texto, as sequências de retorno método detecta qualquer erro na abertura do de carro e alimentação de formulários são arquivo como um arquivo protegido contra escrita transformadas em sequências de novas linhas na ou disco cheio, antes de tentar escrever nele. Um entrada. Na saída, ocorre o inverso: novas linhas nulo é usado porque no ponteiro do arquivo são transformadas em retorno de carro e nunca haverá aquele valor. Também introduzido alimentação de formulário. Tais transformações por esse fragmento está outra função de não acontecem em um arquivo binário. biblioteca: exit(). Uma chamada à função exit() faz com que haja uma terminação imediata do Valores para modo programa, não importando de onde a função exit() é chamada. Ela tem este protótipo Modo Significado (encontrado em STDLIB.H): "r" Abre um arquivo para leitura "w" Cria um arquivo para escrita void exit(int val); "a" Acrescenta dados para um arquivo existente O valor de val é retornado para o sistema "rb" Abre um arquivo binário para leitura operacional. Por convenção, um valor de retorno "wb" Cria um arquivo binário para escrita 0 significa término com sucesso para o DOS. "ab" Acrescenta dados a um arquivo binário Qualquer outro valor indica que o programa existente terminou por causa de algum problema "r+" Abre um arquivo para leitura/escrita (retornado para a variável ERRORLEVEL em "w+" Cria um arquivo para leitura/escrita arquivos “batch” do DOS). "a+" Acrescenta dados ou cria um arquivo para leitura/escrita Se você usar a função fopen() para abrir um "r+b" Abre um arquivo binário para arquivo, qualquer arquivo preexistente com o leitura/escrita mesmo nome será apagado e o novo arquivo "w+b" Cria um arquivo binário para iniciado. Se não existirem arquivos com o nome, leitura/escrita então será criado um. Se você quiser acrescentar "a+b" Acrescenta ou cria um arquivo binário dados ao final do arquivo, deve usar o modo "a". para leitura/escrita Para se abrir um arquivo para operações de "rt" Abre um arquivo texto para leitura leitura é necessário que o arquivo já exista. Se ele "wt" Cria um arquivo texto para escrita não existir, será retornado um erro. Finalmente, "at" Acrescenta dados a um arquivo texto se o arquivo é aberto para escrita/leitura, as "r+t" Abre um arquivo-texto para operações feitas não apagarão o arquivo, se ele leitura/escrita existir; entretanto, se não existir, será criado. "w+t" Cria um arquivo texto para leitura/escrita "a+t" Acrescenta dados ou cria um arquivo 8.3 ESCREVENDO UM CARACTERE texto para leitura/escrita A função putc() é usada para escrever caracteres para um fluxo que foi previamente aberto para Se você deseja abrir um arquivo para escrita com escrita pela função fopen(). A função é declarada o nome test você deve escrever como FILE *ofp; int putc(int ch, FILE *fp); ofp = fopen ("test", "w"); onde fp é o ponteiro de arquivo retornado pela função fopen() e ch, o caractere a ser escrito. Por razões históricas, ch é chamado formalmente de4
  7. 7. int, mas somente o caractere de mais baixa Obviamente, o mesmo método pode ser aplicado ordem é usado. tanto a arquivos textos como a arquivos binários. Se uma operação com a função putc() for 8.6 FECHANDO UM ARQUIVO satisfatória, ela retornará o caractere escrito. Em caso de falha, um EOF é retornado. EOF é uma A função fclose() é usada para fechar um fluxo macrodefinição em STDIO.H que significa fim do que foi aberto por uma chamada à função arquivo. fopen(). Ela escreve quaisquer dados restantes na área intermediária (fluxo) no arquivo e faz um 8.4 LENDO UM CARACTERE fechamento formal em nível de sistema operacional do arquivo. Uma falha no fechamento A função getc() é usada para ler caracteres do de um arquivo leva a todo tipo de problemas, fluxo aberto em modo de leitura pela função incluindo-se perda de dados, arquivos destruídos fopen(). A função é declarada como e a possibilidade de erros intermitentes no seu programa. Uma chamada à função fclose() int getc(FILE *fp) também libera os blocos de controle de arquivo onde fp é um ponteiro de arquivo do tipo FILE (FCB) associados ao fluxo e deixa-os disponíveis retornado pela função fopen(). para reutilização. Por razoes históricas, a função getc() retorna um Como você provavelmente sabe, o sistema inteiro, porém o byte de mais alta ordem é zero. operacional limita o número de arquivos abertos que você pode ter em um dado momento, de A função getc() retornará uma marca EOF modo que pode ser necessário fechar alguns quando o fim do arquivo tiver sido encontrado ou arquivos antes de abrir outros.( Comando FILES= um erro tiver ocorrido. Portanto, para ler um no autoexec.bat). arquivo-texto até que a marca de fim de arquivo seja mostrada, você poderá usar o seguinte A função fclose() é declarada como: código: int fclose(FILE*fp); ch=getc(fp); onde fp é o ponteiro do arquivo retornado pela while(ch!=EOF) { chamada à função fopen(). Um valor de retorno ch=getc(fp); igual a zero significa uma operação de } fechamento com sucesso; qualquer outro valor indica um erro. Você pode usar a função padrão 8.5 USANDO A FUNÇÃO FEOF() ferror() (discutida a seguir) para determinar e O sistema de arquivo do DevC++ também pode reportar quaisquer problemas. Geralmente, o operar com dados binários. Quando um arquivo é único momento em que a função fclose() falhará é aberto para entrada binária, é possível encontrar quando um disquete tiver sido prematuramente um valor inteiro igual à marca de EOF. Isso pode removido do drive ou não houver mais espaço no fazer com que, na rotina anterior, seja indicada disco. uma condição de fim de arquivo, ainda que o fim de arquivo físico não tenha sido encontrado. Para ferror() e rewind() resolver esse problema, foi incluída a função A função ferror() é usada para determinar se uma feof() que é usada para determinar o final de um operação em um arquivo produziu um erro. Se arquivo quando da leitura de dados binários. A um arquivo é aberto em modo texto e ocorre um função feof() tem este protótipo: erro na leitura ou na escrita, é retornado EOF. Você usa a função ferror() para determinar o que int feof(FILE *fp); aconteceu. A função ferror() tem o seguinte protótipo: O seu protótipo está em STDIO.H. Ela retorna verdadeiro se o final do arquivo tiver sido int ferror(FILE*fp); encontrado; caso contrário, é retornado um zero. Portanto, a seguinte rotina lê um arquivo binário onde fp é um ponteiro válido para um arquivo. até que o final do arquivo seja encontrado. ferror() retorna verdadeiro se um erro ocorreu durante a última operação com o arquivo e falso, while(!feop(fp))ch=getc(fp); caso contrário. Uma vez que cada operação em arquivo determina uma condição de erro, a5
  8. 8. função ferror() deve ser chamada imediatamente // Lê arquivos e exibe-os na tela. após cada operação com o arquivo; caso #include <stdio.h> contrário, um erro pode ser perdido. O protótipo #include <stdlib.h> de função ferror() está no arquivo STDIO.H. main(int argc, char *argv[]) { A função rewind() recolocará o localizador de FILE *fp; posição do arquivo no início do arquivo char ch; especificado como seu argumento. O seu if(argc!=3) { protótipo é: puts("Você se esqueceu de informar o nome do arquivo e o modo!"); void rewind(FILE*fp); exit(1); onde fp é um ponteiro de arquivo. O protótipo } para a função rewind() está no arquivo STDIO.H. if((fp=fopen(argv[1], argv[2]))==NULL){ // experimentar "rb"/"rt" e testar newline 8.6 USANDO FOPEN(), GETC(), PUTC() E puts("O arquivo não pode ser aberto!"); FCLOSE() exit(1); // Grava em disco dados digitados no teclado } // até teclar $ ch= getc(fp); // lê um caractere #include <stdio.h> while(ch!=EOF) { #include <stdlib.h> putchar(ch); // imprime na tela main(int argc, char *argv[]) { ch=getc(fp); FILE *fp; } char ch; return 0; if(argc!=3) { } puts("Você se esqueceu de informar o nome do arquivo e o modo!"); 8.7 GETW() E PUTW() exit(1); Funcionam exatamente como putc() e getc() só } que em vez de ler ou escrever um único if((fp=fopen(argv[1], argv[2]))==NULL) { caractere, leem ou escrevem um inteiro. // experimentar "wb"/"wt" e testar newline puts("O arquivo não pode ser aberto!"); Protótipos: exit(1); int putw(int i, FILE *fp); } int getw(FILE *fp); do { Header: stdio.h // getche() não funcionaria aqui porque Exemplo: // getchar() pega o caracteres do teclado e vai putw(100, saida); // armazenando no buffer até o newline. ch=getchar(); escreve o inteiro 100 no arquivo apontado por if(EOF==putc(ch, fp)) { saída. puts("Erro ao escrever no arquivo!"); break; } 8.8 FGETS() E FPUTS() } while (ch!=$); Funcionam como gets() e puts() só que leem e fclose(fp); escrevem em fluxos. return 0; // código de retorno OK p/ DOS. OPCIONAL Protótipos: } char *fputs(char *str, FILE *fp); char *fgets(char *str, int tamanho, FILE *fp); Observação fgets() lê uma string de um fluxo especificado até que um newline seja lido OU tamanho-1 caracteres tenham sido lidos. Se um newline é6
  9. 9. lido, ele fará parte da string (diferente de gets()). Quando o arquivo for aberto para dados binários, A string resultante termina com um nulo. fread() e fwrite() podem ler e escrever qualquer tipo de informação. O programa a seguir escreve Header: stdio.h um float em um arquivo de disco chamado teste.dat: 8.9 FREAD() E FWRITE() #include<stdio.h> Leem e escrevem blocos de dados em fluxos. #include<stdlib.h> Protótipos: #include<math.h> unsigned fread(void *buffer, int num_bytes, int main() { count, FILE *fp); FILE *fp; unsigned fwrite(void *buffer, int num_bytes, int float f=M_PI; count, FILE *fp); if((fp=fopen("teste.dat","wb"))==NULL) { puts("Nao posso abrir arquivo!"); Header: stdio.h exit(1); No caso de fread(), buffer é um ponteiro para } uma área da memória que receberá os dados if(fwrite(&f, sizeof(float), 1, fp)!=1) puts("Erro lidos do arquivo. escrevendo no arquivo!"); fclose(fp); No caso de fwrite(), buffer é um ponteiro para return 0; uma área da memória onde se encontram os } dados a serem escritos no arquivo. Como o programa anterior ilustra, a área Buffer usualmente aponta para uma matriz ou intermediária de armazenamento pode ser (e estrutura (a ser visto adiante). frequentemente é) simplesmente uma variável. O número de bytes a ser lido ou escrito é Uma das aplicações mais úteis de fread() e especificado por num_bytes. fwrite() é o armazenamento e leitura rápidos de matrizes e estruturas (estrutura é uma entidade O argumento count determina quantos itens lógica a ser vista adiante) em disco: (cada um tendo num_bytes de tamanho) serão lidos ou escritos. /* escreve uma matriz em disco */ #include<stdio.h> O argumento fp é um ponteiro para um arquivo #include<stdlib.h> de um fluxo previamente aberto por fopen(). main() { A função fread() retorna o número de itens lidos, FILE *fp; que pode ser menor que count caso o final de float exemplo[10][10]; arquivo (EOF) seja encontrado ou ocorra um erro. int i,j; A função fwrite() retorna o número de itens if((fp=fopen("exemplo.dat","wb"))==NULL) { escritos, que será igual a count exceto na puts("Nao posso abrir arquivo!"); ocorrência de um erro de escrita. exit(1); } for(i=0; i<10; i++) { for(j=0; j<10; j++) { exemplo[i][j] = (float) i+j; /* lei de formação dos elementos da matriz */ } } /* o código a seguir grava a matriz inteira em um único passo: */ if(fwrite(exemplo, sizeof(exemplo), 1, fp)!=1) { puts("Erro ao escrever arquivo!");exit(1);} fclose(fp); return 0; }7
  10. 10. /* lê uma matriz em disco */ O seguinte código lê o 235º byte do arquivo #include<stdio.h> chamado test: #include<stdlib.h> FILE *fp; main() { char ch; FILE *fp; float exemplo[10][10]; if((fp=fopen("teste","rb"))==NULL) { int i,j; puts("Nao posso abrir arquivo!"); if((fp=fopen("exemplo.dat","rb"))==NULL) { exit(1); puts("Nao posso abrir arquivo!"); } exit(1); fseek(fp,234,SEEK_SET); } ch=getc(fp); /* lê um caractere na posição 235º */ // o código a seguir lê a matriz inteira em A função fseek() retorna zero se houve sucesso ou // um único passo: um valor não zero se houve falha no if(fread(exemplo, sizeof(exemplo), 1, fp)!=1) { posicionamento do localizador de posição do puts("Erro ao ler arquivo!"); arquivo. exit(1); // utilitário de visualização de disco usando } // fseek() visualiza setores de 128 de bytes // do disco e apresenta em ASCII e hexadecimal for(i=0; i<10; i++) { // digite -1 para deixar o programa for(j=0; j<10; j++) printf("%3.1f ", exemplo[i][j]); #include <stdio.h> printf("n"); #include <ctype.h> /* isprint() necessita */ } #include <stdlib.h> fclose(fp); return 0; #define TAM 128 /* TAM = 128 */ } char buf[TAM]; /* global */ 8.10 ACESSO RANDÔMICO A ARQUIVOS : FSEEK() void display(); A função fseek() indica o localizador de posição main(int argc, char *argv[]) { do arquivo. FILE *fp; Protótipo: long int setor, numlido; int fseek(FILE *fp, long numbytes, int origem); if(argc!=2) { puts("Uso: tmp nome_do_arquivo");exit(1);} Header: stdio.h // esqueceu de digitar o nome de arquivo if((fp=fopen(argv[1],"rb"))==NULL) {  fp é um ponteiro para o arquivo retornado por puts("Nao posso abrir arquivo!"); uma chamada à fopen(). exit(1);  numbytes (long int) é o número de bytes a } partir da origem até a posição corrente. for(;;) {  origem é uma das seguintes macros printf("Informe o setor (-1 p/ terminar): "); definidas em stdio.h: scanf("%ld",&setor); if(setor<0) break; Valor if(fseek(fp, setor*TAM, SEEK_SET)) { Origem Nome da Macro numérico puts("Erro de busca!"); começo do arquivo SEEK_SET 0 exit(1); posição corrente SEEK_CUR 1 } fim do arquivo SEEK_END 2 if((numlido=fread(buf,1,TAM,fp)) != TAM) { Portanto, para procurar numbytes do começo do puts("EOF encontrado!"); arquivo, origem deve ser SEEK_SET. Para } procurar da posição corrente em diante, origem é display(numlido); SEEK_CUR. Para procurar numbytes do final do } arquivo de trás para diante, origem é SEEK_END. return 0; }8
  11. 11. void display(long int numlido) { /* localiza uma palavra especificada pela linha de long int i,j; comando em um arquivo redirecionado para stdin, mostra a linha e seu número */ for(i=0; i<=numlido/16 ; i++) { // controla a indexação de linhas: /* rodar no prompt do DOS o seguinte comando: // 0 a 8 (128/16 = 8) tmp argv < tmp.c */ for(j=0; j<16; j++) printf("%2X ", buf[i*16+j]); #include<string.h> /* strstr() necessita */ // imprime 16 col. em hexa #include<stdio.h> printf(" "); /* separa mostrador hexa do ascii */ main(int argc, char *argv[]) { for(j=0; j<16; j++) { char string[128]; /* imprime 16 col. em ascii: (só imprimíveis) */ int line=0; if(isprint(buf[i*16+j])) printf("%c",buf[i*16+j]); else printf("."); while(fgets(string, sizeof(string),stdin)) { } ++line; printf("n"); if(strstr(string, argv[1])) } printf("%02d %s",line,string); } } } 9 OS FLUXOS-PADRÕES O fluxo stderr é usado para mostrar mensagens Toda vez que um programa começa a execução, de erro na tela, quando a saída do programa esta são abertos 5 fluxos padrões: redirecionada p/ outro dispositivo que não seja a tela:  stdin (aponta p/ o teclado se não redirecionado pelo DOS. Ex: MORE < #include <stdio.h> FILE.TXT)  stdout (aponta p/ a tela se não redirecionado main(int argc, char *argv[]) { pelo DOS. Ex : DIR > PRN) FILE *fp;  stderr (recebe mensagens de erro - aponta int count; para a tela) char letter;  stdprn (aponta p/ a impressora)  stdaux (aponta p/ a porta serial) if(argc!=2) { puts("Digite o nome do arquivo!");exit(1); Para entender o funcionamento destes fluxos, } note que putchar() é definida em stdio.h como: if(!(fp = fopen(argv[1],"w"))) { #define putchar(c) putc(c,stdout) fputs("Erro na abertura do arquivo",stderr); // 2ª opção: e a função getchar() é definida como // puts("Erro na abertura do arquivo"); // -> vai p/ stdout, isto é, tela #define getchar() getc(stdin) // ou outro dispositivo exit(1); Ou seja, estes fluxos permitem serem lidos e } escritos como se fossem fluxos de arquivos. Toda else entrada de dado de um programa é feita por stdin for(letter=A’; letter<=Z; letter++) e toda saída por stdout: putc(letter, fp); fclose(fp); } Se a saída deste programa (stdout) for redirecionada para algum outro arquivo, a mensagem de erro forçosamente aparecerá na tela porque estamos escrevendo em stderr.9
  12. 12. 9.1 FPRINTF() E FSCANF() Corra para o próximo tutorial. Comportam-se como printf() e scanf() só que escrevem e leem de arquivos de disco. Todos os códigos de formato e modificadores são os mesmos. Protótipos: int fprintf(FILE *fp, char *string_de_controle, lista_de_argumentos); int fscanf(FILE *fp, char *string_de_controle, lista_de_argumentos); Header: stdio.h Embora fprintf() e fscanf() sejam a maneira mais fácil de ler e escrever tipos de dados nos mais diversos formatos, elas não são as mais eficientes em termos de tamanho de código resultante e velocidade. Quando o formato de leitura e escrita for de importância secundária, deve-se dar preferência a fread() e fwrite(). // imprime os quadrados de 0 a 10 no arquivo // quad.dat no formato número - quadrado #include<stdio.h> #include<stdlib.h> main() { int i; FILE *out; if((out=fopen("quad.dat","wt"))==NULL) { // sempre texto c/ fscanf() e fprintf() puts("Nao posso abrir arquivo!"); exit(1); } for (i=0; i<=10; i++) { fprintf(out,"%d %dn", i , i*i); } fclose(out); } Deixaremos o exemplo de uso de fscanf() para o próximo tutorial (Alocação Dinâmica). Apagando arquivos: remove() int remove(char *nome_arquivo); Retorna zero em caso de sucesso e não zero se falhar. 10 TERMINAMOS Terminamos por aqui. Clique no menu Arquivo, depois clique na opção Sair.10

×