memory in c programming - c

Hi i try to read a tkt input file to use it in my structure and it works fine but when i try to read the value image or adresse or nom it's empty
someone have any idea?
this is the code :
int nombre_radio(char* fichier_radio)
{
FILE* fichier = NULL;
char buf[TAILLE_MAX_RADIO]="";
int i;
fichier = fopen(fichier_radio, "r");
if (fichier != NULL)
{
i=0;
while (fgets(buf, TAILLE_MAX_RADIO, fichier) != NULL)
{
i++;
}
}
fclose(fichier);
return(i);
}
/* fonction pour récuperer l'image*/
void get_radio(int numero, char* fichier_radio, char* nom, char* adresse, char* image)
{
FILE* fichier = NULL;
char chaine[TAILLE_MAX_RADIO];
int i;
char im_temp[102400];
fichier = fopen(fichier_radio, "r");
if (fichier != NULL)
{
i=0;
while (fgets(chaine, TAILLE_MAX_RADIO, fichier) != NULL && i<numero){i++;}
strcpy(nom, strtok(chaine, "\t"));
strcpy(adresse, strtok(NULL, "\t"));
strcpy(im_temp, strtok(NULL, "\t"));
if (strstr(im_temp, "\n") != NULL)
strncpy(image, im_temp, strlen(im_temp)-1);
else
strncpy(image, im_temp, strlen(im_temp));
}
fclose(fichier);
return;
}
this is the two function to read txt file and to use it to extract image adresse and nom
and i use the functions here:
int i;
char fichier_radio[1024];
strcpy(fichier_radio,"liste_radio.txt");
int nombre_Radio = nombre_radio(fichier_radio);
recording_asset *assets = malloc(sizeof(recording_asset) * 5000);
printf("nombre %d",nombre_Radio);
char *adresse = malloc (sizeof (*adresse) * 256);
char *nom = malloc (sizeof (*nom) * 256);
char *image = malloc (sizeof (*image) * 256);
for(i=0; i<nombre_Radio; i++){
get_radio(i, fichier_radio, nom, adresse, image);
printf("image : ",image[i]);
}

Could you check fclose(fichier);:
If fichier is a null pointer, fclose should not be called. It results in a undefined behavior, hence might explain the crash you are observing.
You should put fclose(fichier); inside your if (fichier != NULL) check condition.
In nombre_radio, please initialize i to a proper value, you will return garbage value if fichier is NULL.

Related

How to write CSV fields on a binary file?

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?
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;
}
...

C program crash inverse file txt

I'm creating a program in C. I want this program to invert a txt file, avec geojson coordinates.
The program is running good, but when the txt file is too long, the programe crash....!
I think there is a problem with the memory but i don't find how to solucionate it.
Thanks in advance !
There my main.c :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pile.h"
#include "pile_function.h"
#define TAILLE_MAX 5000 // Tableau de taille 1000
int main(int argc, char *argv[]) {
FILE* fichier = NULL;
FILE* fichier_creer = NULL;
char chaine[TAILLE_MAX] = ""; // Chaîne vide de taille TAILLE_MAX
char concat[TAILLE_MAX] = "";
char final[TAILLE_MAX] = "";
const char s[2] = "]";
char *token = malloc(sizeof(*token));
Pile *tas;
if ((tas = (Pile *) malloc (sizeof (Pile))) == NULL)
return -1;
initialisation (tas);
fichier = fopen(argv[1], "r+");
if (fichier != NULL)
{
// On peut lire et écrire dans le fichier
printf("Ouverture du fichier\n");
fgets(chaine, TAILLE_MAX, fichier);
fichier_creer = fopen("Fichier_Inverser.txt", "a+");
if (fichier != NULL)
{
printf("Ouverture du fichier_creer\n");
/* get the first token */
token = strtok(chaine, s);
/* walk through other tokens */
while( token != NULL )
{
strcpy(concat, token);
strcat(concat, s);
empiler(tas, concat);
token = strtok(NULL, s);
memset (concat, 0, sizeof (concat));
}
while( tas->taille != 0 )
{
strcpy (final, depiler(tas));
fputs(final, fichier_creer);
}
printf("\nFichier mise a jour\n");
fclose(fichier_creer);
printf("\nFermeture du fichier du fichier_creer\n");
}
else
{
printf("Impossible d'ouvrir le fichier_creer");
}
fclose(fichier);
printf("Fermeture du fichier du fichier\n");
}
else
{
printf("Impossible d'ouvrir le fichier");
}
return EXIT_SUCCESS;
}
There is my pile.h :
typedef struct ElementListe{
char *donnee;
struct ElementListe *suivant;
} Element;
typedef struct ListeRepere{
Element *debut;
int taille;
} Pile;
/* initialisation */
void initialisation (Pile *tas);
/* EMPILER*/
int empiler (Pile *tas, char *donnee);
/* DEPILER*/
char *depiler (Pile *tas);
/* Affichage de élément en haut de la pile (LastInFirstOut) */
#define pile_donnee(tas) tas->debut->donnee
/* Affiche la pile */
void affiche (Pile *tas);
There is my pile_function.h:
void initialisation (Pile * tas){
tas->debut = NULL;
tas->taille = 0;
}
int empiler (Pile * tas, char *donnee){
Element *nouveau_element;
if ((nouveau_element = (Element *) malloc (sizeof (Element))) == NULL)
return -1;
if ((nouveau_element->donnee = (char *) malloc (50 * sizeof (char))) == NULL)
return -1;
strcpy (nouveau_element->donnee, donnee);
nouveau_element->suivant = tas->debut;
tas->debut = nouveau_element;
tas->taille++;
}
char *depiler(Pile *pile)
{
if (pile == NULL)
{
exit(EXIT_FAILURE);
}
char *chaine = malloc(sizeof(*chaine));
Element *elementDepile = pile->debut;
if (pile != NULL && pile->debut != NULL)
{
strcpy (chaine, elementDepile->donnee);
pile->debut = elementDepile->suivant;
free(elementDepile);
}
pile->taille--;
return chaine;
}
void affiche (Pile * tas){
Element *courant;
int i;
courant = tas->debut;
for(i=0;i<tas->taille;++i){
printf("%s\n", courant->donnee);
courant = courant->suivant;
}
}
There is for exemple a list of coordinate, it doesn't work :
[2.2528324,49.0413749],[2.2530099,49.0409694],[2.2529714,49.0409477],[2.2529531,49.040845],[2.2528231,49.040697],[2.2525572,49.0405152],[2.2521051,49.0402405],[2.2518017,49.0400133],[2.2515308,49.0397237],[2.2514333,49.0395455],[2.2514103,49.0394521],[2.2514134,49.0393256],[2.25172,49.0383752],[2.2517745,49.0380228],[2.2518929,49.0377766],[2.2520333,49.0375694],[2.2522566,49.0373093],[2.2523922,49.0372076],[2.2525084,49.036936],[2.2528797,49.0363597],[2.2529077,49.0362346],[2.2528555,49.0359416],[2.2527984,49.0358494],[2.2527631,49.0358471],[2.2494004,49.0368099],[2.2445056,49.0382113],[2.2438535,49.0351289],[2.2434025,49.0334159],[2.2433668,49.0333207],[2.2424539,49.0292753],[2.242455,49.0290301],[2.2425994,49.0285152],[2.2425996,49.0284322],[2.241938,49.0267597],[2.241008,49.0254301],[2.2405995,49.0251103],[2.2405338,49.0250148],[2.2404128,49.0247205],[2.2403438,49.0244781],[2.2403436,49.0243775],[2.239998,49.0235028],[2.2399302,49.0233991],[2.2398091,49.0233274],[2.2397032,49.0232808],[2.2395594,49.0232176],[2.2394263,49.0231172],[2.2393327,49.0230396],[2.2392098,49.0229535],[2.2387176,49.0225323],[2.238216,49.0221354],[2.237813,49.0218217],[2.2375089,49.0214585],[2.2373633,49.0215158],[2.2371741,49.0213435],[2.2364466,49.0204618],[2.2363631,49.0202973],[2.2359734,49.0197239],[2.2358766,49.0195764],[2.23573,49.0192646],[2.2356873,49.0192694],[2.235498,49.0189371],[2.2354933,49.0189123],[2.2352065,49.0184121],[2.23519,49.0184137],[2.2350145,49.0184304],[2.2348705,49.0184441],[2.2342795,49.0177464],[2.2340851,49.017802],[2.2338829,49.0175392],[2.2338473,49.017546],[2.2331775,49.0168764],[2.2327003,49.0163514],[2.2326684,49.0163499],[2.231627,49.0154023],[2.2312705,49.0150763],[2.2311292,49.0149744],[2.2302659,49.0144945],[2.2301856,49.0144539]
But with the same list but short , it works :
[2.2528324,49.0413749],[2.2530099,49.0409694],[2.2529714,49.0409477],[2.2529531,49.040845],[2.2528231,49.040697],[2.2525572,49.0405152],[2.2521051,49.0402405],[2.2518017,49.0400133],[2.2515308,49.0397237],[2.2514333,49.0395455],[2.2514103,49.0394521],[2.2514134,49.0393256],[2.25172,49.0383752],[2.2517745,49.0380228],[2.2518929,49.0377766],[2.2520333,49.0375694],[2.2522566,49.0373093],[2.2523922,49.0372076],[2.2525084,49.036936],[2.2528797,49.0363597]
I'm a begineer..so maybe i'm not doing it good.
Thanks you for your reply.
Jordan
char *chaine = malloc(sizeof(*chaine)); => Here sizeof(*chaine) == 1 because type is char * so pointed type is char and sizeof(char) == 1. You probably want char *chaine = (char *) malloc(strlen(elementDepile->donnee) * sizeof(char));
– Fefux

growing struct array in function

I have a file which is includes multiple commands. When i see the right command, I must add dynamically created struct in struct array.
I created struct but i cant add it to array in main() function.
Here is what i did:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct book{
char name[30];
int page_number;
};
int main()
{
FILE *fp;
fp = fopen("input.txt", "r");
if(fp == NULL){
printf("Error opening file.");
}
read_line(fp);
fclose(fp);
return 0;
}
void read_line(FILE *fp){
char str[100];
while(1){
if(fgets(str, 100, fp) != NULL){
printf("%s", str);
split_line(str);
} else {
break;
}
}
}
void split_line(char *line){
char ** res = NULL;
char * p = strtok (line, " ");
int n_spaces = 0, i;
/* split string and append tokens to 'res' */
while (p) {
res = realloc (res, sizeof (char*) * ++n_spaces);
if (res == NULL){
printf("Memory allocation failed!");
} else {
res[n_spaces-1] = p;
p = strtok (NULL, " ");
}
}
/* realloc one extra element for the last NULL */
res = realloc (res, sizeof (char*) * (n_spaces+1));
res[n_spaces] = 0;
command_check(res);
free(res);
}
void command_check(char **tokens){
if(strcmp(tokens[0], "CREATEBOOK") == 0){
create_book(tokens);
} else if (strcmp(tokens[0], "REMOVEBOOK") == 0){
remove_book(tokens);
}
}
void create_book(char **tokens){
book created_book;
strcpy(created_book.name, tokens[1]);
created_book.page_number = atoi(tokens[2]);
//then what im stuck here
}

How Read File And Separate Values

I'm trying to read a file like this:
nInp=20
nOut=1
NLaye=3
hid=30
er=0.001
epo=100
epoRep=100
pscpa=0
tip=Aggr
net=emi
numPrec=0.25
prec=NH3;NOX;PM10;SO2;VOC
rag=4
and I must read only the values after the =, and with the prec's values, I must separate every single value (delimited with ;) with a new line and then I write those into a new file like:
NH3
NOX
PM10
SO2
VOC
To read after equals symbolt there is no problems, but I can't to separate price.
This is my function:
void settaggiRete(char values[20][50]){
char line[50];
int i = 0, j = 0;
char str[10][20];
FILE *conf = fopen("conf.txt", "r");
if(conf == NULL){
printf("Impossibile apripre il file conf\n");
exit(EXIT_FAILURE);
}
//Ciclo sulle linee del file di configurazione
while(fgets(line, sizeof(line), configRete) != NULL){
// Leggo i valori contenuti dopo =
if(i==10){
char * str = values[10];
sscanf(line, "%*[^=]=%s", values[i]);
while ((token = strsep(line, ";")) != NULL){
str[j] = token;
j++;
}
}else{
sscanf(line, "%*[^=]=%s", values[i]);
}
i++;
}
fclose(configRete);
}
So How can I separate that values??
You can't assign to the array like this
str[j] = token;
try
strcpy(str[j], token);
althought that is dangerous to do, so you could
size_t length = strlen(token);
if (length >= sizeof(str[j]))
length = sizeof(str[j]) - 1;
memcpy(str[j], token, length);
str[j][length] = '\0';
notice that you are writing safe code at the expense of trimming the token, so a better approach is to use dynamic allocation.
You also, redeclared str inside the loop, so delete this line
char * str = values[10];
which is presumably wrong depending on how you declared values.
do separate at main.
like this :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void settaggiRete(char values[20][50]){
char line[50];
int i = 0;
FILE *conf = fopen("conf.txt", "r");
if(conf == NULL){
printf("Impossibile apripre il file conf\n");
exit(EXIT_FAILURE);
}
while(fgets(line, sizeof(line), conf) != NULL){
sscanf(line, "%*[^=]=%49s", values[i++]);
}
fclose(conf);
}
int main(void){
char values[20][50] = {{0}};
char *value11[25];
int i, v11 = 0;
settaggiRete(values);
for(i=0;i<20;i++){
if(!*values[i])
break;
if(i==11){
char *token, *p = values[11];
int j = 0;
while(token = strsep(&p, ";")){
value11[v11++] = token;
}
for(j = 0; j < v11; ++j){
printf("values[11][%d]=%s\n", j, value11[j]);
}
} else {
printf("values[%d]=%s\n", i, values[i]);
}
}
return 0;
}

segmentation fault only using valgrind

I'm programming a spellchecker for an class assignment. The first step is to load a list separated by "\n" in a "dict" (that actually is a char** dict_main).
The procedure to load the dict is the next:
void dict_load(char *fname){
FILE *loaded_file = fopen(fname, "r");
char **aux = NULL;
int a = 0;
char word[MAX_WORD_SIZE];
//Checks whether fname was successfully loaded or not
if(loaded_file == NULL){
perror("Could not load dict\n");
exit(1);
} else {
while(fgets(word, MAX_WORD_SIZE, loaded_file) != NULL){
main_size++;
while(aux == NULL){
//To ensure that aux is not NULL
aux = realloc(dict_main, main_size);
}
dict_main = aux;
aux = NULL;
//Allocs space enough to store word
dict_main[main_size-1] = calloc(MAX_WORD_SIZE, sizeof(char));
strcpy(dict_main[main_size-1], word);
}
}
//Just for debbuging, prints each string in dict_main
for(a = 0; a<main_size; a++){
fprintf(stdout, "%s", dict_main[a]);
}
fclose(loaded_file);
}
This seems to work when I run it normaly, but when I use valgrind, I get a segfault when it tries to printf the strings.
This is the only procedure that runs in the program, this is main:
int main(int argc, char **argv){
char *dict;
//int i;
if (argc < 2)
{
printf("spellchecker.c: nro de argumentos erroneo. Deben ser <documento> [<diccionario>].\n");
return (1);
}
dict = (argc >=3) ? argv[2] : "dict.txt";
dict_main = calloc(main_size, sizeof(char*));
dict_load(dict);
free(dict_main);
printf("El documento %s ha sido procesado. Resultados en out.txt\n", argv[1]);
Is there something I'm missing and gets me that SegFault when I run it with valgrind?
}

Resources