Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Bernardo Vieira

Problemas de leitura de ficheiro

Mensagens Recomendadas

Bernardo Vieira

Bem eu hoje decidi trabalhar com ficheiros, mas pareçe que isto decidiu complicar


void lerficheiro(char nome[]) {
long tamanho;
char * saida;
size_t resposta;
FILE * ficheiro;
ficheiro=fopen(nome,"r");


fseek (ficheiro , 0 , SEEK_END);
tamanho = ftell (ficheiro);
rewind (ficheiro);

printf("%ld-",tamanho);//é so um guia...
if(!tamanho) {
  printf("Vazio\n");
  exit (EXIT_FAILURE);
}
saida = (char*) malloc (tamanho+1);

if (saida == NULL) {
fputs ("Erro de alocacao",ficheiro);
  exit (EXIT_FAILURE);
}

resposta = fread (saida,1,tamanho,ficheiro);

if (resposta != tamanho) {
  fputs ("Erro de leitura",ficheiro);
  exit (EXIT_FAILURE);
}

fclose (ficheiro);
printf("%s",saida);
}

este é uma parte do codigo, porque por agora o problema está aqui, quer dizer, nao é bem um problema, digamos que nessa linha "saida = (char*) malloc (tamanho+1);" eu vi num tutorial "saida = (char*) malloc (sizeof(char)*tamanho);" mas quando eu usei isso depois do texto normal aparecia outros caracteres, deve ser memoria livre, sei la, enfim, isso deu certo dessa forma

entao eu gostaria de tirar essa pequena duvida,

porque "saida = (char*) malloc (sizeof(char)*tamanho);" assim dá errado ?

é porque char ocupada 16 bytes e entao tem no minimo 16 caracteres obrigatoriamente? entao e o calculo ? char*tamanho?

confuso

PS. Nao sei porque a tabulacao aqui no forum nao aparece, mas tou com preguiça de ficar a dar espaços...

Editado por Bernardo Vieira

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Porque, em C, as strings sao terminadas por um caracter com valor 0, que faz parte da string.

A string "abc" precisa de 4 espacos para ser guardada em memoria: 1 para o 'a', outro para 'b', mais um para o 'c', e finalmente, um quarto espaco para o '\0'.

Ignorando possiveis problemas relacionados com o fim de linha (e ficheiros binarios com bytes de valor 0), se o ficheiro, no disco, tem 1793 bytes, para o meteres numa string de C, em memoria, precisas de, no minimo, 1794 bytes!

Editado por pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Bernardo Vieira

sim sim, isso eu sei, dai o meu "malloc (tamanho+1);" por acaso já tenho essa experiencia do \0 de outras linguagens, mas tambem se nao tivesse isso a unica coisa que acontecia era cortar-me a ultima letra

mas nao é isso, tipo, se eu usar "saida = (char*) malloc (sizeof(char)*tamanho);" aparece algo do genero "ábcdéfghI-úBz}" até ao h tá certo, depois é que nao, mas se eu só colocar até d entao aparece algo como "ábcdÄ|{úaxZ"

@EDIT espera, agora já só tem um carater de sobra e o código é o mesmo o.O

@EDIT mentira, se aumentar o numero de caracteres no ficheiro, o problema aumenta "ábcdasdfggfdsfghgfdsdfgh9U=½P¯" isso é a saida e no ficheiro só está até ao ultimo h

@EDIT agora esta a dar o mesmo problema com o meu codigo "ábcdasdfggfdsfghgfdsdfghles\CommVj²ÄÖã" essa é a saida, e supostamente só deveria ir até ao ultimo h

Editado por Bernardo Vieira

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Isso tem todo o aspecto de ser problemas do charset.

Diz-me uma coisa: como 'e que alteras o ficheiro? como 'e que corres o teu programa?

Alteras no Notepad e corres numa "Command Shell" talvez???

Se nao usares cedilhas, acentos e outras "portuguezices", o teu programa funciona bem?

  • Voto 1

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Marzkor

"mas tambem se nao tivesse isso a unica coisa que acontecia era cortar-me a ultima letra"

Não, por exemplo o caso de uma simples string estática se não tiver \0 o que vai acontecer é que o sistema não sabe quando parar, então o restos dos caracteres é o que estiver em memória. Mesmo que não esteja lá nada ele vai escrever!

Pq uma string não é nada mais do que um array de caracteres.

P.S Corrige-me Pmg se estiver errado.

Editado por Marzkor

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Bernardo Vieira

Ora, "portuguezices" ahaha, vá eu estou a usar Eclipse Juno

tipo, abro o ficheiro e escrevo nele

quanto ás "portuguezices", se te referias ao "á", ja tirei e o resultado é o mesmo

como assim problemas do charset ?

sim, mas Marzkor, o programa vai rodar até encontrar um \0 que no caso é um pouco á frente do que eu quero!

Editado por Bernardo Vieira

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Não, por exemplo o caso de uma simples string estática se não tiver \0 o que vai acontecer é que o sistema não sabe quando parar, então o restos dos caracteres é o que estiver em memória. Mesmo que não esteja lá nada ele vai escrever!

não

uma string estática tem sempre o caracter '\0'

nota que uma string estática é uma escrita no código com o auxilio das aspas (")

-------

1º - coloca o último caracter do memória alocada com o valor '\0'

2º - coloca o exactamente o texto no ficheiro e o que foi apresentado (com porteguezises e sem porteguezises)

Editado por HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Marzkor

não

uma string estática tem sempre o caracter '\0'

nota que uma string estática é uma escrita no código com o auxilio das aspas (")

Sim, mas por exemplo se não tiveres era o que ia acontecer.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Sim, mas por exemplo se não tiveres era o que ia acontecer.

qualquer outro tipo de criação/escrita de strings, sim, sem o '\0' o printf irá continuar a imprimir caracteres da memória até ter a sorte de encontrar um


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Marzkor

"mas tambem se nao tivesse isso a unica coisa que acontecia era cortar-me a ultima letra"

Só estava a comentar esta afirmação, mas o melhor é ficar calado. xD

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Bernardo Vieira

cárma home! aprendemos com os erros vale? se não fosse isso eu nao tava aqui a fazer figura de ignorante! xD

PS. Eclipse nao comilou depois de eu escrever aquilo xD

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

HappyHippyHippo, referias-te a fazer isto ? saida[tamanho+1]='\0';

não, estava a dizer:

// array com X elementos, o último é X-1
saida[tamanho]='\0'

  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Bernardo Vieira

agora funcionou, só que basicamente a minha pergunta era,

Nao é suposto aquilo funcionar certo logo de inicio? É que neste "printf("%ld-",tamanho);//é so um guia..." dá o tamanho exato, entao é só colocar +1 nao percebo porque é que colocar +10 prae! o.O

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Bernardo Vieira

sim...viu os comentarios anteriores? por exemplo, se eu tiver umas 5 letras no ficheiros, saiem mais 5 ou 6 caracteres invalidos!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

não faço ideia do que andas a fazer, mas se for o que foi dito, a aplicação deverá correr sem problemas :

código exemplo baseado no teu:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
 long tamanho;
 char * saida;
 size_t resposta;
 FILE * ficheiro;

 if (argc < 2)
 {
   printf("Nome do ficheiro em falta\n");
   exit (EXIT_FAILURE);
 }

 ficheiro = fopen(argv[1], "r");

 fseek(ficheiro, 0, SEEK_END);
 tamanho = ftell(ficheiro);
 fseek(ficheiro, 0, SEEK_SET);

 if(!tamanho)
 {
   printf("Vazio\n");
   fclose(ficheiro); // fechar antes de sair da app
   exit (EXIT_FAILURE);
 }
 saida = (char*) malloc(tamanho + 1);
 saida[tamanho] = '\0';

 if(saida == NULL)
 {
   printf("Erro de alocacao\n");
   fclose(ficheiro); // fechar antes de sair da app
   free(saida); // limpeza
   exit(EXIT_FAILURE);
 }

 resposta = fread(saida, 1, tamanho, ficheiro);
 fclose(ficheiro);

 if (resposta != tamanho)
 {
    printf("Erro de leitura\n");
    free(saida); // limpeza
    exit(EXIT_FAILURE);
 }

 printf("%s",saida);

  free(saida); // limpeza
 exit(EXIT_SUCCESS);
}

Editado por HappyHippyHippo
  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Bernardo Vieira

sim, deu certo, mas se tirar o saida[tamanho] = '\0'; o resultado volta a nao ficar certo e resulta "abcdasdfggfdsfghgfdsdfghhn Files_;u­Pv" sendo que só deveria ir até ao ultimo h

ok! tá visto que sem isso nao funciona

obrigado a todos, Like pra quem me ajudou, obrigado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

sim, deu certo, mas se tirar o saida[tamanho] = '\0'; o resultado volta a nao ficar certo

isso já foi explicado acima


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.