Depois de aberto o arquivo, deve-se extrair o seu conteúdo, usando funções como fgets()
, fscanf()
e fread()
. Eu prefiro usar a função fread()
, pois é a mais rápida das três e a única que pode extrair o conteúdo do arquivo inteiro de uma vez só, sem a necessidade de usar estruturas de repetição. A velocidade do processamento da função fread()
pode não fazer diferença em arquivos pequenos, mas em arquivos grandes (~1 MB), as outras funções são tão lentas que podem levar horas, enquanto a fread()
pode fazer o serviço na mesma velocidade, ou quase, que quando feita em arquivos pequenos.
Use a função fseek()
para seguir até o fim do arquivo e colha o offset do fim do arquivo para uma variável chamada tamanho, usando a função ftell()
. Após isso, use a fread()
para ler o arquivo e passar seu conteúdo para uma variável, chamada fonte. No Windows de 32 bit, há um limite de ~2 MB para ser dividido para todas as variáveis estáticas e isso pode ser um problema se o arquivo que for aberto pelo nosso programa for maior do que isso. Uma solução, é declarar variáveis muito grandes de forma dinâmica, usando alocação de memória dinâmica, a qual se limita a quantidade de memória disponível no computador. Use a informação da variável tamanho na função malloc()
, para indicar o tamanho a ser alocado para a variável fonte. Normalmente, multiplica-se o tamanho desejado pelo tamanho em bytes do tipo de dado usado, mas como estamos usando o tipo char
, não é necessário fazer isso, já que a quantidade de bytes do tipo char
é igual a 1. Para outros tipos, usa-se o seguinte modelo:
tipo *nome = (tipo *) malloc(tamanho * sizeof(tipo));
Segue um exemplo, onde se deseja alocar um vetor de 256 itens, do tipo int
:
int *vetor = (int *) malloc(256 * sizeof(int));
Também, a conversão do retorno de malloc()
, pelo fato do seu retorno ser do tipo void *
, é opcional em C, mas é obrigatório em C++. Por isso, eu resolvi coloca-lo no código, para permitir compatibilidade.
Também deve verificar se o programa conseguiu alocar memória, pois se não conseguir alocar memória e mesmo assim tentar colocar algo na variável, haverá um problema e o programa terminará de forma abrupta. Use a função memset()
para limpar a variável fonte. Também, a memória deve ser liberada, usando a função free()
. Atualmente, a maioria dos sistemas operacionais liberam a memória automaticamente, após o programa terminar, mas é uma boa prática fazer isso manualmente (se uma variável dinâmica deixar de ser usada e o programa for realizar outras tarefas, é necessário a liberação de memória manualmente, senão a memória se esgotará e os programas deixarão de funcionar corretamente). Não se esqueça de incluir as bibliotecas stdlib.h e string.h. Ficará assim:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int c;
FILE *arquivo; // Deve-se usar o asterisco aqui, por ser ponteiro
if (argc >= 2) // Se tiver 2 ou mais argumentos
{
arquivo = fopen(argv[1], "rb"); // Abre o arquivo especificado
if (arquivo == NULL) // Se não conseguir abrir o arquivo
{
puts("ERRO: Não foi possível abrir o arquivo!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1; // Encerra o programa
}
}
else
{
return 0; // Encerra o programa
}
fseek(arquivo, 0, SEEK_END);
int tamanho = ftell(arquivo); // Offset do fim do arquivo, que equivale ao tamanho do arquivo
rewind(arquivo); // Rebobina o arquivo
// Aloca memória, com um byte adicional para o nulo (usado em strings em C)
char *fonte = (char *) malloc(tamanho + 1);
if (fonte == NULL) // Verifica se consegui alocar memoria
{
puts("ERRO: Não há memória o suficiente!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
memset(fonte, 0, tamanho * sizeof(char)); // Preencherá a variável fonte com zeros (para "limpar")
size_t size = fread(fonte, 1, tamanho, arquivo);
fonte[tamanho] = 0; // Põe o sinal de fim (nulo)
if (size != tamanho * sizeof(char))
{
puts("ERRO: Não foi possível ler o arquivo!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
free(fonte);
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 0;
}
A função malloc()
é usada para alocar a memória, sendo que precisa de um argumento especificando a quantidade de memória desejada. Se conseguir alocar memória, devolverá o endereço da memória disponível para fonte. Caso contrário, devolverá zero. O segundo argumento de fread()
serve para indicar quantos bytes tem cada elemento do arquivo. Estamos usando ASCII, o que equivale a 1 byte por elemento. Esse número poderia ser maior se estivéssemos usando Unicode.
« parte anterior próxima parte »
0 comentários:
Postar um comentário