-1

I have the following code:

typedef struct RegDados{

    char removido; //  deve ser inicializado com '-'
    int encadeamento; // deve ser inicializado com -1
    int nroInscricao; // nao aceita valores repetidos nem nulos
    double nota;
    char data[10]; // checar tipo
    char *cidade;
    int sizecid;
    char tagCampo4;
    char *nomeEscola;
    int sizesch;
    char tagCampo5;
}RegDados;

char * strtokEvenEmpty(char * s, const char * seps){

  static char * p = NULL;

  if (s != NULL)
    p = s;
  else if (p == NULL)
    return NULL;
  else
    s = p;

  while (*p) {
    if (strchr(seps, *p)) {
      *p++ = 0;
      return s;
    }
    p += 1;
  }
  return (*s) ? s : NULL;
}

const char * getfield(char* line, int num){

  const char * tok;

  for (tok = strtokEvenEmpty(line, ","); tok; tok = strtokEvenEmpty(NULL, ",\n")){
    if (!--num)
      return tok;
  }
  return NULL;
}

int main(){

  FILE * stream = fopen("trabalho1.csv.csv", "r+");
  FILE * ArqBin = fopen("test.bin","wb");
  RegDados regdados[5000];
  RegCab regcab;
  int i = 0;

  if(ArqBin == NULL) printf("Error");

  if (stream != NULL) {
    char line[1024];
    while (fgets(line, 1024, stream)) {  

      regdados[i].nroInscricao = atoi(getfield(line, 1));
      fwrite(&regdados[i].nroInscricao, sizeof(int), 1, ArqBin);

      regdados[i].nota =  atof(getfield(line, 2));
      fwrite(&regdados[i].nota, sizeof(double), 1, ArqBin); 

      strcpy(regdados[i].data, getfield(line, 3));                             
      fwrite(regdados[i].data, sizeof(char), 100, ArqBin);  

      regdados[i].cidade = getfield(line, 4);
      fwrite(regdados[i].cidade, sizeof(char), 100, ArqBin);

      regdados[i].nomeEscola = getfield(line, 5);
      fwrite(regdados[i].nomeEscola, sizeof(char), 100, ArqBin);  

      i++;
    }
    fclose(stream);
    fclose(ArqBin);
  }
  else{
    printf("Error");
  }
}

It already parses the fields of my file, but I can't write them on a binary file, because when I try to write, I get a lot of null fields, which doesn't happen when I don't write.

My CSV file looks like:

nroInscricao,nota,data,cidade,nomeEscola

13893,353.9,26/11/2016,,FRANCISCO RIBEIRO CARRIL

13595,472.2,,Salgueiro,ALFREDO GUEDES

13894,614.4,28/11/2016,Recife,JOAO DE MOURA GUIMARAES

13880,403.2,29/11/2016,Fortaleza,ANTONIO DIAS PASCHOAL PR

13881,373.7,,Sao Jose da Tapera,DONIZETTI TAVARES DE LIM

13882,394.8,01/12/2016,Sao Bernardo do Cam,JUSTINO GOMES DE CASTRO

How can I write the each field on a binary file?

mch
  • 9,424
  • 2
  • 28
  • 42
  • Unless I can understand what *"because it gets really weird."* means, I would suggest looking at this possible duplicate [Read/Write to binary files in C](https://stackoverflow.com/questions/17598572/read-write-to-binary-files-in-c) – Duck Dodgers Apr 16 '19 at 07:33
  • 2
    "get's really weird" is not a description. And I don't see you trying to write to a file anywhere in the code. – klutt Apr 16 '19 at 07:36
  • Where are your `#include`s? – Jabberwocky Apr 16 '19 at 07:46
  • Explain what you want, what difference the 'binary' file must have compared with the csv file ? – bruno Apr 16 '19 at 07:47
  • I dunno, but I get this error also when trying your code: `error: unknown type name ‘RegCab’; did you mean ‘RegDados’?` – Duck Dodgers Apr 16 '19 at 07:53
  • `atof(getfield(line, 2))` : consider that `getfield(line, 2)` may return `NULL`. – Jabberwocky Apr 16 '19 at 07:54
  • `fwrite(regdados[i].data, sizeof(char), 100, ArqBin);`: you write 100 chars but the `data` is only 10 chars long.... and many other issues like that.... – Jabberwocky Apr 16 '19 at 07:55
  • out of the fact it is normal you produce several 0 you use wrongly _getfield_ and you bypass fields, see my answer – bruno Apr 16 '19 at 08:04

1 Answers1

2

when I try to write, I get a lot of null fields, which doesn't happen when I don't write.

this is normal, the internal representation of number can contains several 0, for instance doing :

fwrite(&regdados[i].nroInscricao, sizeof(int), 1, ArqBin);

if regdados[i].nroInscricao values 7 and your int are on 32bits that will write 3 times 0 and 1 time 7 (the order depends if you are on little/big endian).

Of course it is the same with the strings you write with a fixed size, so the padding characters can have any value including 0 (there are not initialized)


Your way to extract the fields with getfield is expensive because you extract the first token, then to get the second you have to bypass the first token, then to get the third you have to bypass the 2 first tokens etc.

A better way is to do getfield(line, 1) then getfield(NULL, 1) to get the second token, then to do getfield(NULL, 1) to get the third etc, so in fact the second argument is always 1 and you can remove its management


You try to open trabalho1.csv.csv, probably you want to open trabalho1.csv


In

if(ArqBin == NULL) printf("Error");

if (stream != NULL) {

it is not enough to print error, you must not continue, can be

if(ArqBin == NULL) 
  printf("Error");
else if (stream != NULL) {

or better replace

FILE * stream = fopen("trabalho1.csv.csv", "r+");
FILE * ArqBin = fopen("test.bin","wb");
...
if(ArqBin == NULL) printf("Error");

if (stream != NULL) {
  ...
}
else{
  printf("Error");
}

by something like

FILE * stream = fopen("trabalho1.csv.csv", "r+");

if (stream == NULL) {
  fprintf(stderr, "cannot open input file rabalho1.csv.csv");
  return -1;
}

FILE * ArqBin = fopen("test.bin","wb");

if (ArqBin == NULL) {
  fprintf(stderr, "cannot open output file test.bin");
  fclose(stream); /* really useful if you do not stop execution */
  return -1;
}
...
bruno
  • 32,421
  • 7
  • 25
  • 37
  • "You have to call getfield all the times giving 1 as the second argument, so in fact that argument is useless and each time you have to return the next token" I don't really get this part, if I pass 1 as the second argument all the times, I just fill my struct with the content of the first field... – Rafaela Souza Apr 16 '19 at 08:42
  • 1
    @RafaelaSouza ah yes, sorry, I supposed you do not give _line_ but NULL from the second calls. I edit my answer – bruno Apr 16 '19 at 08:44
  • @RafaelaSouza why do you write the read csv file in a binary file, what is the interest ? – bruno Apr 16 '19 at 08:50
  • Actually I have a lot more to do, but I was really stuck on that part, thank you! – Rafaela Souza Apr 16 '19 at 08:58