Saturday 8 July 2017

C Arquivo Manipulação Opções Binárias


C Programação Manipulação de arquivos usando open (), read (), write () e close () Os exemplos anteriores de tratamento de arquivos lidam com FCB (File Control Blocks). Em sistemas MSDOS v3.x (ou superior) e UNIX, o tratamento de arquivos geralmente é feito usando alças, ao invés de blocos de controle de arquivos. Escrever programas usando alças garante a portabilidade do código-fonte entre os diferentes sistemas operacionais. Usando alças permite ao programador tratar o arquivo como um fluxo de caracteres. Os modos de acesso disponíveis são As permissões são A função open () retorna um valor inteiro, que é usado para se referir ao arquivo. Se não tiver êxito, retornará -1 e definirá a variável global errno para indicar o tipo de erro. A função read () tenta ler nbytes do arquivo associado com handle e coloca os caracteres lidos no buffer. Se o arquivo é aberto usando OTEXT, ele remove retornos de carro e detecta o final do arquivo. A função retorna o número de bytes lidos. No final do arquivo, 0 é retornado, em erro retorna -1, definindo errno para indicar o tipo de erro que ocorreu. A função write () tenta escrever nbytes de buffer para o arquivo associado com handle. Nos arquivos de texto, ele expande cada LF para um CRLF. A função retorna o número de bytes gravados no arquivo. Um valor de retorno de -1 indica um erro, com o errno configurado adequadamente. A função close () fecha o arquivo associado ao identificador. A função retorna 0 se for bem-sucedida, -1 para indicar um erro, com errno definido apropriadamente. Copyright B Brown. 1984-1999. Todos os direitos reservados. Usando namespace std é considerado má prática. Então você quer se livrar disso. Em seguida, você deve dar-lhe variáveis ​​nomes melhores. O arquivo e o arquivo1 são um pouco descritivos. Ambos dizem que é um arquivo, mas nem diz que tipo de arquivo. Verifique também se você realmente conseguiu abrir o arquivo. Por exemplo, o arquivo pode ser somente de gravação (e o arquivo file. write () funciona, mas seu arquivo1.read () falha), somente leitura (e seu arquivo. write () falha, mas seu arquivo1.read () Funciona), ou nem (e ambos falham). O que é esse 4. pelo caminho O número de elementos em sua altura é um número mágico. Ele pode mudar em algum momento, e você tem que atualizá-lo em todo o seu programa. Isso é propenso a erros. É um pouco bom para um pequeno programa como este, mas em programas maiores, você quer dar a esse número um nome (veja acima), algo como HEIGHTLENGTH. O mesmo é válido para BINARY. DAT. Você não quer usar acidentalmente BINARY. Dar pela segunda vez. Por último, mas não menos importante: use o elenco de estilo C como último recurso. Você está procurando um reinterpretcastltchargt. By the way, se possível, manter o escopo de suas variáveis ​​pequeno: Ive também acrescentou alguns espaços em branco. Tenha em mente: você escreve código tanto para a máquina quanto para o ser humano que vai ler esse código mais tarde. Esse ser humano pode ser você ou seu supervisor. Certifique-se de que é fácil de read. Binary arquivos com C R. A. Ford Department of Math. E Ciência da Computação Mount Allison University Sackville, NB Introdução Usando fluxos para processamento de arquivos é certamente possível em C, mas a maioria dos livros didáticos C não incluem qualquer informação sobre a funcionalidade completa dos córregos. Este documento foi formado para ajudar os alunos com um fundo em C e estruturas de dados com uma descrição completa da biblioteca de fluxo C. O documento é baseado na documentação da biblioteca GNU CPP que às vezes não é fácil de ler, especialmente sem exemplos. Os operadores de inserção e extração (ou seja, ltlt e são destinados a serem usados ​​por programas para escrever e ler a partir de arquivos de texto, é assumido que o programador está familiarizado com as diferenças entre esses dois formatos de arquivo. Na realidade, há dezenas de extensões com pouco Documentação de fluxos de texto comuns. Uma seção adicional será adicionada a este documento posteriormente. Noções básicas do arquivo IO O acesso a um arquivo binário de um programa C (ao não usar as funções C antigas) exige primeiro anexar uma variável de fluxo ao arquivo . As classes usuais de fluxo de fluxo (fluxo de arquivos de saída) e ifstream (fluxo de arquivos de entrada) ainda são os tipos de fluxos a serem usados. Um tipo adicional chamado fstream é fornecido, o que permite que arquivos sejam lidos e lidos se isso É uma propriedade desejável (no design de programas de tipo de banco de dados, isso é geralmente o caso.) Antes de qualquer operação pode ter lugar em um arquivo, é claro que deve ser aberto e quando você terminar o arquivo, Ele deve ser fechado para evitar perda de dados. Abrindo um Fluxo O ifstream e ofstream têm funções de membro denominadas open que são usadas para anexar o fluxo a um nome de arquivo físico e abrir o arquivo para leitura ou escrita. A função de membro aberto também fornece um par de argumentos opcionais que não são frequentemente descritos. O protótipo mais geral desta função é O formato que eu usei indica que os argumentos mode e prot são opcionais. O primeiro argumento é sempre o nome do arquivo no disco ao qual o fluxo será anexado. O modificador const é incluído para que um programador possa escrever o nome do arquivo (dentro de aspas duplas) na chamada de função. A única parte complicada sobre como usar a função de membro aberto é sob sistemas baseados em DOS (inclui o Windows) em que diretórios são separados por um recall que o caractere de barra invertida tem um significado especial em strings C. O parâmetro prot é usado para especificar a proteção (permissão) do arquivo em sistemas operacionais multiusuários como o Unix. Ele permite que você especifique quais usuários são autorizados a olhar para este arquivo. Em DOSWindows, esse parâmetro nunca é usado. O parâmetro de modo geralmente é deixado de fora ao lidar com arquivos de texto, mas existem algumas situações muito úteis em arquivos binários para que esse parâmetro deve ser definido. Existem várias opções que podem ser dadas para este parâmetro. Se você precisar especificar mais de um deles basta colocar uma barra vertical entre eles. Ios :: in Isso indica que o fluxo será usado para entrada. Isso pode parecer redundante para ifstreams que são marcados automaticamente para entrada quando eles são abertos, mas ele tem que ser usado ocasionalmente. Quando você chama aberto sem um segundo parâmetro, o parâmetro é assumido como sendo ios :: in, mas se você fornecer qualquer outro parâmetro como ios :: binário, você precisará especificar que o arquivo também é um arquivo de entrada. Ios :: out Isso indica que o fluxo será usado para a saída. Como ios :: neste pode parecer redundante para ofstream s, mas pela mesma razão como acima, geralmente tem de ser dado. Ios :: ate Isso faz com que o ponteiro do arquivo aponte no final do arquivo quando o arquivo é aberto. Ios :: trunc Isso faz com que todos os dados existentes no arquivo sejam descartados (apagados) quando o arquivo for aberto. Tenha muito cuidado para não usar esta opção em um arquivo que você não deseja destruir ios :: binário Isso faz com que o arquivo seja acessado como um arquivo binário. Provavelmente você precisará definir esta opção. Se você esquecer de definir essa opção, muitos problemas estranhos ocorrerão ao ler certos caracteres como o fim da linha eo final do arquivo. Exemplo de abrir um arquivo binário: Escrevendo para um arquivo binário, mencionei uma vez que ltlt é usado para gravar dados em um arquivo de texto. Se você tivesse uma variável x que continha o valor 354 e você usasse o arquivo outfile de estatuto ltlt x isso faria com que o caractere 3, o caractere 5 eo caractere 4 fossem escritos (em forma ASCII) para o arquivo. Esta não é a forma binária que só exigiria 16 bits. A classe ofstream fornece uma função de membro denominada write que permite que as informações sejam escritas em forma binária para o fluxo. O protótipo da função de gravação é Esta função faz com que n bytes sejam escritos a partir do local de memória dado pelo buffer ao disco e move o ponteiro do arquivo à frente n bytes. Os tipos de parâmetros requerem um pouco de explicação. Mesmo que o tipo de retorno seja ofstreamamp, o valor de retorno geralmente é ignorado pela maioria dos programadores. O ponteiro de buffer é de tipo void isso permite que qualquer tipo de variável seja usado como o primeiro parâmetro. Você não deve estar escrevendo funções com parâmetros vazios, esta é uma parte muito complicada da programação. O tipo streamsize é simplesmente um inteiro positivo. É raro que você saiba exatamente quantos bytes uma determinada variável é. Para obter essas informações, C fornece uma macro (como uma função) chamada sizeof que leva exatamente um parâmetro e retorna o tamanho do parâmetro em termos de bytes necessários para o armazenamento. Abaixo está um exemplo de usar a macro sizeof para obter o tamanho de uma variável e escrever o conteúdo de uma variável para o disco. Observe o uso de uma estrutura em vez de uma classe que você não deve usar este método para escrever classes para arquivos binários Consulte a seção intitulada Escrita Classes para Arquivos para obter uma descrição de como isso deve ser feito. Leitura de um arquivo binário Ler dados de um arquivo binário é como escrever, exceto que a função agora é chamada de leitura em vez de escrever. Ao ler dados de um arquivo, há um par de coisas novas a serem observadas: É responsabilidade de O programador para garantir que o buffer seja grande o suficiente para armazenar todos os dados que estão sendo lidos. O seguinte segmento de código provavelmente resultaria em uma falha a menos que o tamanho de um número inteiro fosse de 7 bytes (número improvável): int main () int x ifstream infile infile. open (silly. dat, ios :: binário ios :: in) infile. read (ampx, 7) lê 7 bytes em uma célula que é 2 ou 4 Depois de ler algo do arquivo, a função de membro fail () deve ser chamada para determinar se a operação foi concluída com êxito. Em C, nenhuma operação de arquivo faz com que o programa parar. Se ocorrer um erro e você não verificar, o seu programa será executado sem problemas. Veja uma seção mais adiante neste documento sobre a detecção de erros. Ponteiro de arquivo Sempre que os dados são lidos ou escritos em um arquivo, os dados são colocados ou retirados de um local dentro do arquivo descrito pelo ponteiro do arquivo. Em um arquivo de acesso seqüencial, as informações são sempre lidas do início ao fim e cada vez que n bytes é lido ou escrito, o ponteiro do arquivo é movido n bytes à frente. Em um arquivo de acesso aleatório, podemos mover o ponteiro do arquivo para locais diferentes para ler dados em vários locais dentro de um arquivo. Pense em um banco de dados cheio de itens de loja. Quando o item é digitalizado no check-out, o código de barras é usado para procurar uma descrição e preço do item. Se o arquivo fosse de acesso seqüencial, teríamos que começar a pesquisar no início do arquivo, o que provavelmente é mais lento do que gostaríamos. Isso não é um curso de processamento de arquivos, mas basta dizer que se pudéssemos mover o ponteiro do arquivo diretamente para o registro contendo os dados que teríamos que ler a partir do arquivo apenas uma vez. A função de membro tellp () tem um protótipo de A forma Esta função não aceita parâmetros, mas retorna a localização dada em bytes desde o início do arquivo onde o ponteiro do arquivo está atualmente sentado. A próxima leitura ou gravação terá lugar a partir desta localização. A função de membro seekp () tem um protótipo do formulário void seekp (localização streampos, int relative) Isso faz com que o ponteiro do arquivo se mova para outro local dentro do arquivo. A localização especifica o número de bytes que serão usados ​​para determinar a localização e o parâmetro relativo indica se este é algum tipo de solicitação de posicionamento absoluto ou relativo. Os valores possíveis para relativo são: ios :: beg Isso indica que a localização é o número de bytes desde o início do arquivo. Ios :: cur Isso indica que a localização é o número de bytes da localização atual do ponteiro do arquivo. Isso permite um posicionamento relativo do ponteiro do arquivo. Ios :: end Isso indica que a localização é o número de bytes a partir do final do arquivo. Consideramos um exemplo que usa a obtenção e configuração da localização do ponteiro do arquivo: int main () int x streampos pos ifstream infile infile. open (silly. dat, ios :: iões binários :: in) infile. seekp (243, ios: : Implorar) mover 243 bytes para o arquivo infile. read (ampx, sizeof (x)) pos infile. tellg () cout ltlt O ponteiro do arquivo está agora na posição ltlt endl infile. seekp (0, ios :: end) Procurar o final do arquivo infile. seekp (-10, ios :: cur) fazer backup de 10 bytes infile. close () Escrever classes para arquivos binários A maneira mais fácil de armazenar registros em arquivos é usar uma struct Se você está mantendo Track de registros em estruturas de memória usando classes, em seguida, salvar essas classes para o disco leva um pouco de trabalho extra. Você não pode simplesmente usar uma função de membro de gravação e fornecer o endereço do objeto como o buffer. A razão para isso é a presença de funções de membros. Não faria sentido para salvar as funções de membro essas funções membro acabam ficando salvo como locais de memória que faria com que seu computador para falhar se você já carregou um do disco com um local de memória antiga. É possível escrever objetos no disco, mas requer que o objeto tenha uma função de membro associada a ele. Minha abordagem usual é inserir uma função de membro chamada ler e gravar em cada função de membro. Essas funções devem ter um fstream como um parâmetro como o fluxo para salvar a si mesmo. Seu programa deve, em seguida, abra o fluxo e chamar a função de membro com o fluxo apropriado. A função membro deve então passar por cada campo de dados do objeto escrevendo-os em uma ordem específica. A função membro lida deve recuperar as informações do disco exatamente na mesma ordem. O exemplo para esta seção é um pouco envolvido, por isso Ive eliminado as funções de membro não-arquivo. Começar incluir ltiostream. h incluir ltstdlib. h incluir ltfstream. h O que foi errado Nesta seção, vou apontar um par de métodos para determinar se uma operação de arquivo foi bem sucedida e, caso contrário, alguns métodos de determinar de forma aproximada o que deu errado . Após cada operação de disco, um programa bem escrito irá chamar a função membro fail () para ver se a operação foi concluída com êxito. Cabe ao programador determinar o que deve ocorrer quando uma operação de arquivo é incorreta. Essencialmente existem três possibilidades: Ignore o problema e espero que isso nunca aconteça. Esta é uma boa abordagem para lidar com erros de pequenos programas escritos para testar uma idéia, mas uma versão totalmente funcional de um programa nunca deve assumir que o usuário não vai cometer um erro. Se ocorrer um erro, chame exit (EXITFAILURE) e termine o programa. Isso é ligeiramente melhor do que apenas esperar que isso não aconteça, mas em uma versão completa de um programa, isso pode ser um verdadeiro incômodo para o usuário. Pense no que aconteceria se você gastasse 5 horas escrevendo um ensaio e tentei salvá-lo para o T: o que não existia. Se o seu programa acabou de abortar, você perderia 5 horas de trabalho. Quando ocorre um erro, deixe o usuário tentar corrigir o erro e tentar novamente a operação. Este é o método preferido no que diz respeito ao usuário, mas geralmente não é trivial para o programa. Você deve tentar implementar isso tanto quanto possível. Ocorre uma situação infeliz ao lidar com erros, geralmente são coisas físicas que os tornam dependentes do sistema operacional. Em seguida, vou listar a abordagem ANSI (padrão) para lidar com erros e a abordagem DOS para lidar com erros. A abordagem ANSI é muito mais geral e, portanto, as mensagens de erro não será preciso, mas a abordagem ANSI funcionará não importa qual compilador C você usar. A manipulação de erro do DOS elimina alguma da confusão sobre o que aconteceu mas obviamente é somente boa em máquinas do DOS que suportam a biblioteca (Turbo C, Borland C, e GNU G suportam esta biblioteca). Para tornar as coisas um pouco mais feias, parece não haver suporte de erro incorporado em fluxos diferentes da função fail (). Para combater erros, temos que confiar em algumas funções C existentes que não são problema para usar de C, pois C é simplesmente uma extensão de C. ANSI Errors ANSI C suporta uma variável global (oh não, uma variável global) chamada errno que pode ser Acessado através da inclusão de errno. h Quando ocorrem erros, a variável é definida como um código de erro padrão que deve ser equivalente em todos os sistemas operacionais. Há muitos códigos de erro para incomodar a lista neste documento. Normalmente, a melhor maneira de descobrir todos os códigos de erro é olhar para a página do manual ou ajuda on-line procurando na palavra-chave errno. O arquivo de inclusão define um conjunto de constantes que podem ser usadas para determinar o tipo de erro que ocorreu. Por exemplo, o código de erro 22 indica que o arquivo que você acabou de tentar não existe. Uma maneira um pouco melhor de dizer 22 é usar a constante ENOENT. Há uma função em stdio. h chamado perror que leva uma seqüência de caracteres como um parâmetro. Quando essa função é chamada, a seqüência de caracteres é exibida na tela, seguida de dois pontos e, em seguida, por uma mensagem que descreve o valor em errno. Isso pode ser útil se você não deseja escrever manipuladores de erros e apenas quiser que o programa pare. Abaixo está um programa simples que lê um nome de arquivo do usuário, abre o arquivo e exibe o fato de que a unidade não estava pronta, o arquivo não existia ou a mensagem de erro padrão. Principal () ifstream data char filename50 cout ltlt arquivo para abrir cin. getline (filename, 50) data. open (filename) se (data. fail ()) switch (errno) caso EACCES: este é definido se o drive não estiver pronto No DOS cout ltlt Unidade não pronta ou permissão negada ltlt endl break case ENOENT: cout ltlt Não foi possível encontrar este arquivo ltlt endl break default: perror (abrir arquivo de dados) sair (EXITFAILURE) um programa real então volta para trás e peça ao usuário para tente novamente. . DOS Erros estendidos Se você olhar os erros dados na lista ANSI, você notará que muitos deles são realmente orientados para o DOS, ou seja, você não sabe com certeza se um setor estava ruim em um disco ou a porta da unidade foi deixada aberta. Isso ocorre porque o padrão ANSI estava mais ou menos definido no sistema UNIX, onde esses tipos de erros nunca são vistos pelos usuários. A maioria dos compiladores baseados em DOS fornece algumas funções para acessar o erro estendido do DOS, o que normalmente fornece uma descrição muito mais precisa do erro. Manipulação de arquivos na linguagem C Um arquivo representa uma seqüência de bytes no disco onde um grupo de dados relacionados está armazenado . O arquivo é criado para armazenamento permanente de dados. É uma estrutura pronta. Em linguagem C, usamos um ponteiro de estrutura do tipo de arquivo para declarar um arquivo. C fornece uma série de funções que ajudam a executar operações básicas de arquivos. A seguir estão as funções, criar um novo arquivo ou abrir um arquivo existente lê um caractere de um arquivo escreve um caractere para um arquivo lê um conjunto de dados de um arquivo escreve um conjunto de dados para um arquivo lê um número inteiro de um arquivo escreve um Inteiro para um arquivo, defina a posição para o ponto de desejo, dá a posição atual no arquivo, defina a posição para o ponto de início. Abrir um arquivo ou criar um arquivo. A função fopen () é usada para criar um novo arquivo ou para abrir um arquivo existente. Aqui o nome do arquivo é o nome do arquivo a ser aberto eo modo especifica o propósito de abrir o arquivo. Modo pode ser dos seguintes tipos, fp é o ponteiro FILE (FILE fp), que irá manter a referência para o arquivo aberto (ou criado). Abre um arquivo de texto no modo de leitura abre ou cria um arquivo de texto no modo de escrita. Abre um arquivo de texto no modo de anexar abre um arquivo de texto no modo de leitura e escrita abre um arquivo de texto no modo de leitura e escrita abre um arquivo de texto no modo de leitura e escrita abre um arquivo binário no modo de leitura abre ou cria um arquivo binário No modo de escrita abre um arquivo binário no modo de anexar abre um arquivo binário no modo de leitura e escrita abre um arquivo binário no modo de leitura e escrita abre um arquivo binário em modo de leitura e escrita. Fechando um arquivo A função fclose () é usada Para fechar um arquivo já aberto. Aqui a função fclose () fecha o arquivo e retorna o zero no sucesso, ou EOF se houver um erro no fechamento do arquivo. Este EOF é uma constante definida no arquivo de cabeçalho stdio. h. Operação InputOutput no Arquivo Na tabela acima, discutimos sobre várias funções de arquivo IO para executar a leitura e gravação no arquivo. Getc () e putc () são funções mais simples usadas para ler e gravar caracteres individuais em um arquivo. Leitura e escrita a partir do arquivo usando fprintf () e fscanf () Neste programa, criamos dois ponteiros de ARQUIVO e ambos referem-se ao mesmo arquivo, mas em modos diferentes. A função fprintf () escreve diretamente no arquivo, enquanto fscanf () lê a partir do arquivo, que pode ser impresso na função printf () do console usinf padrão. Diferença entre o Modo de Gravação e Modo de Gravação (w) eo modo de Anexar (a), ao abrir um arquivo são quase iguais. Ambos são usados ​​para escrever em um arquivo. Em ambos os modos, o novo arquivo é criado se ele já não existe. A única diferença que eles têm é, quando você abre um arquivo no modo de gravação, o arquivo é redefinido, resultando na exclusão de quaisquer dados já presentes no arquivo. Enquanto no modo anexar isso não acontecerá. O modo de anexar é usado para anexar ou adicionar dados aos dados existentes do arquivo (se houver). Assim, quando você abre um arquivo no modo Append (a), o cursor está posicionado no final dos dados atuais no arquivo. Leitura e escrita em um arquivo binário Um arquivo binário é semelhante ao arquivo de texto, mas contém apenas grandes dados numéricos. Os modos de abertura são mencionados na tabela para os modos de abertura acima. As funções fread () e fwrite () são usadas para ler e gravar é um arquivo binário. Fread () também é usado da mesma maneira, com os mesmos argumentos como a função fwrite (). Abaixo mencionado é um exemplo simples de escrever em um arquivo binário fseek (), ftell () e rewind () funções fseek () - É usado para mover o controle de leitura para diferentes posições usando a função fseek. Ftell () - Indica a posição do byte da posição atual do cursor no ponteiro do arquivo. Rebobinar () - Move o controle para o início do arquivo. Alguns exemplos de programas de tratamento de arquivos

No comments:

Post a Comment