Jump to content
PsySc0rpi0n

Abrir ficheiro, ler e converter

Recommended Posts

PsySc0rpi0n

Boas...

Estava aqui a fazer umas experiências, mas como há já algum tempo que não pego nesta matéria em concreto.

O que pretendo, mesmo que não faça muito sentido, é:

Abrir um ficheiro txt que foi previamente criado por mim.

Ler o ficheiro e colocar em memória, numa strcut, os dados lidos.

Fazer uma busca rápida por um dos elementos dessa strcut.

Se encontrar o que foi pesquisado, o programa deve escrever num ficheiro em formato bin, o conteúdo da struct que está em memória.

Para já o code que tenho ainda não está a funcionar bem, e precisava de ajuda para corrigir o que está mal.

#include <stdio.h>
#include <stdlib.h>
FILE *pTextFile, *pBinaryFile;
char buffer;
int load_file_mem (char *file_name){
  if ((pTextFile = fopen(file_name, "r")) == NULL){
  perror("Error: ");
  exit (-1);
  }
  if ((pBinaryFile = fopen(file_name, "wb")) == NULL){
  perror ("Could not open data file:");
  exit (-1);
  } else {
  printf ("test");
  while (feof (pTextFile)){
	 fread(&buffer, 1, 1, pTextFile);
	 fwrite(&buffer, 1, 1, pBinaryFile);
  }
  }
  fclose(pTextFile);
  fclose(pBinaryFile);
  return 0;
}
int main (void) {
  load_file_mem ("khars_data_base.fght");
  return 0;
}


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo
#include <stdio.h>
#include <stdlib.h>

struct Data {
   char name[256];
};

int load_file_mem(char *file_name, struct Data* memory) {
   FILE *fd = NULL;

   if ((fd = fopen(file_name, "r")) == NULL){
       perror("Error: ");
       return -1;
  }

  // TODO : read file to memory array

  fclose(fd);

  return 0;
}

int main(void) {
   struct Data memory[256];

   load_file_mem ("khars_data_base.fght", memory);

   return 0;
}


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

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Bom voltei aqui à tentativa de abrir files e fazer isto de outra maneira. Se calhar compliquei mas...

Tenho dois warnings que sei a razão deles, só não sei como os contornar, até porque o programa crasha antes do printf (Success11!\n); e o printf (Success12!\n);.

O code é:

#include <stdio.h>
#include <stdlib.h>
#define BUFFER 256
int file_open (FILE *pFile) {
   if ((pFile = fopen ("mkxm_data_file.dat", "a+")) == NULL) {
    perror ("Error:");
    exit (-1);
   }
   printf ("Success!\n");
   return 1;
}
void get_file_size (FILE *pFile, long *lSize) {
   printf ("Success10!\n");
   fseek (pFile, 0, SEEK_END);
   printf ("Success11!\n");
   *lSize = ftell (pFile);
   printf ("Success12!\n");
   rewind (pFile);
   printf ("Success13!\n");
}
void alloc_mem (char *tmp_char, long *lSize) {
   if ((tmp_char = (char *) malloc (sizeof (char)*(*lSize))) == NULL) {
    perror ("Error:");
    exit (-2);
   }
}
int main(){
   FILE *pTextFile = NULL;
   char *tmp = NULL;
   long *lSize = NULL;
   size_t res;
   file_open(pTextFile);
   printf ("Success1!\n");
   get_file_size(pTextFile, lSize);
   printf ("Success2!\n");
   alloc_mem(tmp, lSize);
   printf ("Success3!\n");
   res = fread (tmp, 1, lSize, pTextFile);
   printf ("Success4!\n");
   if (res != lSize){
    fputs ("Reading error",stderr);
    exit (-3);
   }
   fclose (pTextFile);
   free (tmp);
   return 0;
}

Os warning são:

||=== Build: Debug in MKX_M_FW_Calc (compiler: GNU GCC Compiler) ===|

C:\Users\AM06\Documents\MKX_M_FW_Calc\main.c||In function 'main':|

C:\Users\AM06\Documents\MKX_M_FW_Calc\main.c|45|warning: passing argument 3 of 'fread' makes integer from pointer without a cast [enabled by default]|

c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\..\..\..\..\include\stdio.h|412|note: expected 'size_t' but argument is of type 'long int *'|

C:\Users\AM06\Documents\MKX_M_FW_Calc\main.c|47|warning: comparison between pointer and integer [enabled by default]|

||=== Build finished: 0 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|

||=== Run: Debug in MKX_M_FW_Calc (compiler: GNU GCC Compiler) ===|

||=== Run: Debug in MKX_M_FW_Calc (compiler: GNU GCC Compiler) ===|

Estou a usar o Code::Blocks


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo

se sabes a razão dos warnings, então deverias eliminar-los, até porque é a razão da aplicação estoirar : um ponteiro não é um valor de tamanho !!!

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

#define FILE_PATH "mkxm_data_file.dat"
#define FILE_OPEN_METHOD "a+"

FILE* file_open (void) {
   FILE* pFile = NULL;
   if ((pFile = fopen(FILE_PATH, FILE_OPEN_METHOD)) == NULL) {
       perror ("Error:");
       exit (-1);
   }
   return pFile;
}

size_t get_file_size(FILE *pFile) {
   size_t size;

   fseek(pFile, 0, SEEK_END);
   size = ftell(pFile);
   fseek(pFile, 0, SEEK_SET);

   return size;
}

char* alloc_mem(size_t size) {
   char* buffer = NULL;

   if ((buffer = malloc(size)) == NULL) {
       perror ("Error:");
       exit (-2);
   }

   return buffer;
}

int main(){
   FILE* pFile = NULL;
   size_t size = 0;
   char* buffer = NULL;
   size_t res = 0;

   pFile = file_open();
   size = get_file_size(pFile);
   buffer = alloc_mem(size);

   res = fread(buffer, 1, size, pFile);
   if (res != size) {
       fputs("Reading error",stderr);
       exit(-3);
   }

   fclose(pFile);
   free(buffer);

   return 0;
}

Edited by HappyHippyHippo

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

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Espero que não leves a mal, mas alterei duas ou três no code mas penso que não terá qualquer influência na funcionalidade.

No entanto o programa dá erro ao alocar a memória!

Diz: " Not enough space". Será uma questão de permissões (estou no PC do trabalho)?

Code:

#include <stdio.h>
#include <stdlib.h>
#define FILE_PATH "mkxm_data_file.dat"
#define FILE_OPEN_METHOD "a+"
void file_open (FILE *pFile) {
if ((pFile = fopen(FILE_PATH, FILE_OPEN_METHOD)) == NULL) {
	perror ("Error1");
	exit (-1);
}
}
size_t get_file_size(FILE *pFile) {
size_t size;
fseek(pFile, 0, SEEK_END);
size = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
return size;
}
char* alloc_mem(size_t size, char *buffer) {
if ((buffer = malloc(size)) == NULL) {
	perror ("Error2");
	exit (-2);
}
return buffer;
}
int main(){
FILE* pFile = NULL;
size_t size = 0, res = 0;
char *buffer = NULL;
file_open(pFile);
size   = get_file_size(pFile);
buffer = alloc_mem(size, buffer);
res = fread(buffer, 1, size, pFile);
if (res != size) {
	fputs("Reading error",stderr);
	exit(-3);
}
fclose(pFile);
free(buffer);
return 0;
}

Nota: o que alterei foi apenas para evitar estar a declarar variáveis repetidas, nomeadamente as variáveis pFile e buffer.

Será que o que alterei, fazer passagem por referência é o que está a dar cabo da alocação de memória?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo

quando uma função termina, as variáveis locais à função são destruídas, por isso, as tuas alterações não fazem sentido.

além disso o código actual foi testado e funciona perfeitamente


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

Share this post


Link to post
Share on other sites
PsySc0rpi0n

quando uma função termina, as variáveis locais à função são destruídas, por isso, as tuas alterações não fazem sentido.

além disso o código actual foi testado e funciona perfeitamente

Sim, não estava a duvidar do teu código... E percebo o que dizes à cerca das variáveis dentro das funções que são destruídas quando a função termina, mas era apenas uma questão de não estar a declarar as variáveis duas vezes quando as podemos passar por referência (sempre vou treinando mais um pouco esta minha dificuldade de sempre de passar valores por referência e ponteiros)!

O código que eu alterei não funciona devido às alterações que fiz ou será uma questão de permissões, visto estar no PC do trabalho que tem restrições de permissões?

Edited;

Já vi que não tem a ver com as permissões! O que correu mal nas alterações que eu fiz?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo

vais fazer um pequeno teste:

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

#define FILE_PATH "mkxm_data_file.dat"
#define FILE_OPEN_METHOD "a+"

void file_open (FILE *pFile) {
   if ((pFile = fopen(FILE_PATH, FILE_OPEN_METHOD)) == NULL) {
       perror ("Error1");
       exit (-1);
   }
}

int main(){
   FILE* pFile = NULL;

   file_open(pFile);
   printf("ponteiro para o stream : %p\n", (void *)pFile);

   if (pFile)
       fclose(pFile);

   return 0;
}


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

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Esse printf deu "ponteiro para o stream: 0000000"...


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Não sei... Terá a ver com tipos de dados? Penso que não. Formatação no printf, %p? Também acho que não. Acho que não sei!

Edited; Também não deve ser pelo cast que fizeste!

Edited 2; Espera, deixa cá ver mais uma hipótese!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo

testa agora este :

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

#define FILE_PATH "mkxm_data_file.dat"
#define FILE_OPEN_METHOD "a+"

void file_open (FILE *pFile) {
   if ((pFile = fopen(FILE_PATH, FILE_OPEN_METHOD)) == NULL) {
       perror ("Error1");
       exit (-1);
   }
}

int main(){
   FILE* pFile = (FILE*) 1;

   file_open(pFile);
   printf("ponteiro para o stream : %p\n", (void *)pFile);

   if (pFile)
       fclose(pFile);

   return 0;
}

Edited by HappyHippyHippo

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

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Esse último teste crashou, pelo menos aqui, mas mostrou o resultado: "ponteiro para o stream 00000001"

Mas eu acho que estou a ver o que queres dizer. Como o *pFile é um endereço de memória (mas que também é um valor numérico) e no fundo está a ser passado como valor e não como referência, ele dá asneira! Teríamos talvez que usar um ponteiro para um ponteiro, não?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo

já percebeste a razão do meu código inicial ?

sim, o problema é que todas as chamadas em C são chamadas com passagem por valor. o que estás a fazer com colocar um ponteiro como argumento da função, não é mais do que passar o valor do ponteiro (endereço de memória a que o ponteiro referência).

se pretendes alterar dentro da função o valor da variável da função "main", tens de passar o valor da posição de memória da variável e não o valor que esta contem.


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

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Então mas e não dá para evitar aquelas declarações do pFile e do buffer em ambas as funções? Na main e nas outras duas? Usando ponteiros para ponteiros?

Eu sei que provavelmente estarei a complicar, mas já agora queria saber!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo
// ...
void file_open (FILE **pFile) {
       if ((*pFile = fopen(FILE_PATH, FILE_OPEN_METHOD)) == NULL) {
// ...
       file_open(&pFile);
// ...


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

Share this post


Link to post
Share on other sites
PsySc0rpi0n

yes... Também já consegui...

#include <stdio.h>
#include <stdlib.h>
#define FILE_PATH "mkxm_data_file.dat"
#define FILE_OPEN_METHOD "a+"
void file_open (FILE **pFile) {
    if ((*pFile = fopen(FILE_PATH, FILE_OPEN_METHOD)) == NULL) {
		    perror ("Error1");
		    exit (-1);
    }
}
void get_file_size(FILE **pFile, size_t size) {
    fseek(*pFile, 0, SEEK_END);
    size = ftell(*pFile);
    fseek(*pFile, 0, SEEK_SET);
}
void alloc_mem(size_t size, char *buffer) {
    if ((buffer = malloc(size)) == NULL) {
		    perror ("Error2");
		    exit (-2);
    }
}
int main(){
    FILE *pFile = NULL;
    size_t size = 0, res = 0;
    char *buffer = NULL;
    file_open(&pFile);
    get_file_size(&pFile, size);
    alloc_mem(size, buffer);
    res = fread(buffer, 1, size, pFile);
    printf ("Success!\n");
    if (res != size) {
		    fputs("Reading error",stderr);
		    exit(-3);
    }
    fclose(pFile);
    free(buffer);
    return 0;
}

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Este sistema de idetação é que dá cabo de mim... De cada vez que edito um post, isto fico logo tudo descontrolado!

Edited;

Agora sim... Já está a dar certo!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Bom, senão me engano agora o code está a funcionar.

#include <stdio.h>
#include <stdlib.h>
#define FILE_PATH	 "mkxm_data_file.dat"
#define FILE_OPEN_METHOD "a+"
#define BUFF			 7
#define CLEAR_INPUT while (getchar () != '\n') /*void*/
#ifdef _WIN32
#define CLEAR_SCREEN system ("cls")
#else
#define CLEAR_SCREEN puts("\x1b[H\x1b[2J")
#endif

typedef struct DatCalc {
int fusion;
int level;
char tier[bUFF];
int bat_num;
}DatCalc;
void file_open (FILE **pFile) {
if ((*pFile = fopen(FILE_PATH, FILE_OPEN_METHOD)) == NULL) {
 perror ("Error1");
 exit (-1);
}
}
void get_file_size(FILE *pFile, size_t *size) {
fseek(pFile, 0, SEEK_END);
*size = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
}
void alloc_mem(size_t size, char **buffer) {
if ((*buffer = malloc(size)) == NULL) {
 perror ("Error2");
 exit (-2);
}
}
int main(){
FILE *pFile = NULL;
size_t size = 0, res = 0;
char *buffer = NULL;
DatCalc tmp_calc [3];
int i;
file_open(&pFile);
get_file_size(pFile, &size);
alloc_mem(size, &buffer);
res = fread(buffer, 1, size, pFile);

if (res != size) {
 fputs("Reading error", stderr);
 exit(-3);
}
printf ("Mortal Kombat X Mobile FW XP Calculator\n");
for (i = 0; i < 3; i++) {
 printf ("Enter the kard fusion level of fighter nº %d:\n", i + 1);
 scanf (" %d", &tmp_calc [i].fusion);
 printf ("Enter the kard level of fighter nº %d:\n", i + 1);
 scanf (" %d", &tmp_calc [i].level);
 CLEAR_INPUT;
 printf ("Enter the kard tier of fighter nº %d:\n", i + 1);
 fgets (tmp_calc[i].tier, BUFF, stdin);
 printf ("******************************\n");
}
printf ("Enter Match Difficulty (1, 3, 5, 7):\n");
scanf (" %d", &tmp_calc[i - 1].bat_num);
CLEAR_SCREEN;
for (i = 0; i < 3; i++) {
 printf ("Kard %d Fusion Level: %d\n", i + 1, tmp_calc[i].fusion);
 printf ("Kard %d Level: %d\n", i + 1, tmp_calc[i].level);
 printf ("Kard %d Tier: %s\n", i + 1, tmp_calc[i].tier);
 printf ("******************************\n");
}
printf ("Match Difficulty: %d\n", tmp_calc[i - 1].bat_num);
fclose(pFile);
free(buffer);
return 0;
}

Bom, isto acho que está mais ou menos como eu queria mas o output tem um new line não desejado na última iteracção do 2º for da função main. O output está assim:

Kard 1 Fusion Level: 4

Kard 1 Level: 50

Kard 1 Tier: Silver

******************************

Kard 2 Fusion Level: 6

Kard 2 Level: 50

Kard 2 Tier: Silver

******************************

Kard 3 Fusion Level: 1

Kard 3 Level: 50

Kard 3 Tier: Gold

nnnnnnnnnnnnnnnnnnn

******************************

Match Difficulty: 5

Onde está a fila de "n"'s, está um new line que não consegui descobrir porque está a aparecer!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

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.