Jump to content

Recommended Posts

Posted (edited)

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
Posted (edited)

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!

Posted (edited)

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
Posted

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!

Posted (edited)

"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
Posted (edited)

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
Posted (edited)

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
Posted

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.

Posted

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

Posted (edited)

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
Posted

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • 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.