I'm trying to read from a file using C and after shrinking the size using realloc
I get corrupted data. I don't really see what the problem could be.
Here's the function that returns the string :
char *read_string(FILE *fichier) {
char car = 0;
size_t size = 1;
char *symbole = realloc(NULL, sizeof(char) * size);
char *s;
size_t len = 0;
if (!symbole)
return symbole;
else
s = symbole;
do {
car = getc(fichier);
} while (car != '"' && car != EOF);
if (car == EOF)
return EOFP;
else {
car = getc(fichier);
while (car != '"' ) {
s[len] = car;
car = getc(fichier);
len++;
if (len == size) {
symbole = realloc(s, sizeof(char) * (size += 1));
if (!symbole)
return symbole;
else
s = symbole;
}
}
s[len] = '\0' ;
symbole = realloc(s, sizeof(char) * len);
if (!symbole) {
printf("WTF");
return symbole;
} else
s = symbole;
return s;
}
}
My main
function is:
int main(int argc, char *argv[]) {
FILE *fichier = NULL;
fichier = fopen("C:/Users/Nabila K/Documents/test.json", "r");
if ((fichier != NULL)) {
while (feof(fichier) == 0) {
char *test = read_string(fichier);
if (test == NULL) {
printf("test == NULL\n");
exit(1);
} else
if (test == EOFP) {
} else {
printf("%s\n", test);
free(test);
}
}
fclose(fichier);
} else {
exit(EXIT_FAILURE);
}
return 0;
}
UPDATE
My json file looks something like this :
{
"KARIM BENNI" : {
"2017-08-07 09:50:50" : {
"Anomalie" : {
"description" : "Test",
"theme" : "Engins mobiles"
},
"date" : "2017-08-07",
"date_now" : "2017-08-07 09:50:50",
"entite" : "USINE LAMINAGE A FROID",
"etat" : "Cree",
"nb_personne" : 2,
"temps" : 5,
"visiteur" : "KARIM BENNI",
"visite" : "AHMED RABII",
"zone" : "COUPE"
}
}
}
There are multiple issues in your code:
char car = 0;
is incorrect: you must define car
as int
to correctly distinguish all values returned by getc()
, especially EOF
.
while (feof(fichier) == 0)
is always wrong. Learn why there: Why is “while ( !feof (file) )” always wrong?
EOFP
is not defined, you should probably use NULL
instead for more clarity.
the final realloc()
to shrink the allocated block is one byte too short. You must keep len+1
bytes for len
characters plus the null terminator.
Here is a simplified and corrected version:
#include <stdio.h>
#include <stdlib.h>
char EOFP[1]; /* special value used to signal end of file */
char *read_string(FILE *file) {
int c;
size_t size, len;
char *symbol;
char *s;
while ((c = getc(file)) != '"') {
if (c == EOF)
return EOFP;
}
size = 16;
len = 0;
symbol = malloc(size);
if (symbol == NULL) {
/* allocation failure */
return NULL;
}
while ((c = getc(file)) != '"') {
if (c == EOF) {
/* premature end of file in the middle of a string */
free(symbol);
return EOFP;
}
if (len + 2 < size) {
size += size;
s = realloc(symbol, size);
if (s == NULL) {
/* allocation failure */
free(symbol);
return NULL;
}
symbol = s;
}
symbol[len++] = c;
}
symbol[len] = '\0';
s = realloc(symbol, len + 1);
return s ? s : symbol;
}
int main(int argc, char *argv[]) {
FILE *file = fopen("C:/Users/Nabila K/Documents/test.json", "r");
if (file != NULL)) {
char *test;
while ((test = read_string(file)) != EOFP) {
if (test == NULL) {
printf("test == NULL\n");
exit(1);
} else {
printf("%s\n", test);
free(test);
}
}
fclose(file);
} else {
exit(EXIT_FAILURE);
}
return 0;
}
Notes:
\"
or \n
, \\
etc.