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(®dados[i].nroInscricao, sizeof(int), 1, ArqBin);
regdados[i].nota = atof(getfield(line, 2));
fwrite(®dados[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?
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(®dados[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;
}
...