Jump to content
Bernardo Vieira

Problemas de leitura de ficheiro

Recommended Posts

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...

Edited by Bernardo Vieira

Share this post


Link to post
Share on other 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!

Edited by 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!

Share this post


Link to post
Share on other sites
Marzkor

Bem não tenho a certeza mas pode ser pq \0 no final da string.

Edited by Marzkor
  • Vote 1

Share this post


Link to post
Share on other 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

Edited by Bernardo Vieira

Share this post


Link to post
Share on other 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?

  • Vote 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!

Share this post


Link to post
Share on other 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.

Edited by Marzkor

Share this post


Link to post
Share on other 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!

Edited by Bernardo Vieira

Share this post


Link to post
Share on other 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)

Edited by HappyHippyHippo

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

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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'

  • Vote 1

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

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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!

Share this post


Link to post
Share on other 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);
}

Edited by HappyHippyHippo
  • Vote 1

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

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.