Por que o ftell retorna 0 nesta função?
Pergunta
Quando eu executar o meu programa e eu escolha para ver a lista de produtos, ele não imprime nada.Depois de algum tempo, eu descubra que o valor de fl_size
é sempre 0.Por que isso?
void view_prdct_code_list() {
FILE *stock = fopen("stock.dat","r+");
assert(stock);
int fl_size=ftell(stock);
int prd_size= sizeof(product);
int quantity= fl_size/prd_size;
printf("fl_size=%d",fl_size);
fseek(stock,0,SEEK_SET);
prdct cprd= (product *)malloc (sizeof(product)*quantity);
assert(cprd);
int i;
fread(cprd,prd_size,quantity,stock);
for (i=0;i<quantity;i++){
printf("PRODUCT CODE: %d\n",cprd->code);
}
free(cprd);
fclose(stock);
}
Solução
ftell
não retorna o tamanho total do arquivo;ele retorna a atual ler ou escrever posição dentro do arquivo.Você chamar ftell
imediatamente depois de abrir o arquivo, de modo que a posição é o início do arquivo.Você pode usar fseek(stock, 0, SEEK_END)
a busca até o final antes de chamar ftell
, ou você pode cair para baixo de uma camada e usar fstat(fileno(stock))
para obter o tamanho do arquivo diretamente a partir do sistema operativo.
Outras notas:
- Nenhuma dessas opções funcionar se você estiver lendo a partir de um tubo.(Em geral, você precisará verificar o sucesso de cada uma de suas operações de acesso a arquivos.)
fread
não é garantido para ler o arquivo inteiro em um gole, mesmo se você pedir a ele para.- Como 'alk' aponta,
ftell
retorna umlong
, nãoint
. - Você deve abrir este aparentemente-arquivo binário com o modo de
"r+b"
. - Arquivos binários com nenhum arquivo de cabeçalho (e, em particular, sem número mágico, de , pelo menos, quatro bytes no deslocamento zero) são uma Coisa Ruim.
- Não converter o valor de retorno de
malloc
.(É necessário para fazer isso em C++, mas em C é não só desnecessário, ele pode se esconder erros.)
Outras dicas
Verifique a página de manual para ftell
, por exemplo este: http://linux.die.net/man/3/ftell
Aqui é a parte relevante: "O ftell() função obtém o valor atual do indicador de posição do arquivo para o fluxo apontado por stream."
Quando você abrir o arquivo, a posição do cursor será no início.Assim, a distância de início, vai ser zero.Portanto, ftell
retorna zero.
Para encontrar o tamanho de ficheiro, consulte este link: Como posso obter o tamanho de um arquivo em C?.Aqui está um trecho de código em resumo:
fseek(fp, 0L, SEEK_END);
sz = ftell(fp);
Certifique-se de chamar fseek(fp, 0L, SEEK_SET);
após acima.
Porque ftell
retorna o tamanho do início até a posição atual do arquivo.
fseek(stock,0,SEEK_SET);
Significa que você defina a posição para a primeira mordida do arquivo.
Além disso, você tem que definir fl_size=ftell(stock);
depois de o fseek
.