Struct and dynamic array












-1














I'm new in c and sorry for my poor English.



I'm trying to write a program that ask to user if he want enter data (region, date of detection, mm of rain) using keyboard and save it in file or if he want give it file's name.
No problem at this time and file is written or read correctly.
File have this structure:



Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
....


Try with scanf() (not report main because there is no problem in it.



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese;
typedef struct data_s
{
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s
{
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s
{
tipo_dati_file* array;
int count;
} tipo_ritorna;

int conta_righe(char* Nome_f)
{
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

}
void crea_array (char* Nome_f)
{
int i,n;
char* regione= (char*)malloc(sizeof(char));
tipo_data data;
int mm_pioggia;
tipo_ritorna risultati;
FILE* file;
n = conta_righe(Nome_f);
printf("%dn",n);
tipo_dati_file* array = (tipo_dati_file*) malloc (n*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");
if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
for(i=0; i<=n; i++)
{
fscanf(file,"%s %d/%d/%d %dn",regione, &data.giorno, &data.mese, &data.anno, &mm_pioggia);
strcpy(array[i].regione, regione);
array[i].data.giorno=data.giorno;
array[i].data.mese= data.mese;
array[i].data.anno= data.anno;
array[i].mm_pioggia= mm_pioggia;
printf("%s %d/%d/%d %dn",array[i].regione,array[i].data.giorno, array[i].data.mese,array[i].data.anno,array[i].mm_pioggia);
}

fclose(file);
}


try with fgets()



#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese; typedef struct data_s {
int giorno;
tipo_mese mese;
int anno; } tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia; } tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count; } tipo_ritorna;

int conta_righe(char* Nome_f) {
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

} void crea_array (char* Nome_f, int v) {
int i=0,s;
char* r;
//tipo_ritorna risultati;
FILE* file;
//n = conta_righe(file);
tipo_dati_file* array = (tipo_dati_file*) malloc (v*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");

if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
if (feof(file)==0)
{
char* buf= (char*) malloc(v*sizeof(char));
/*while ( fgets( buf,10000, file) != NULL )
{
r = sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}*/
while(1)
{
r=fgets( buf,1000, file);
if (r!=NULL)
{
printf("%s",buf);
sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}
else exit(1);
}
}
else exit(1);

fclose(file); }









share|improve this question
























  • Please do publish your code. No matter how bad it is [or how bad you think it is], this is better than not showing it. We can only help you with what we see. There just isn't enough to work with, and many here will not help you further without seeing the code you've already written. See: stackoverflow.com/help/how-to-ask and follow the links, particularly: stackoverflow.com/help/mcve
    – Craig Estey
    Nov 23 '18 at 20:25










  • fist edit your post, it is barely readable. Then, what are your exact inputs, ouputs, and errors ? Where is your code ? We can't guess what you wrote and execute.
    – LoneWanderer
    Nov 23 '18 at 20:26










  • Don’t describe the code, show the code. Describing says ”this is basically what I’m telling the computer to do”. Problem is, computers don’t do “basically” what you tell them, they do exactly what you tell them. So tell us exactly what you’re telling the computer to do, i.e. show your code.
    – dbush
    Nov 23 '18 at 20:27












  • Ok i'll insert code my two try with fgets() and scanf() in first post. @LoneWanderer compiler don't gave me any error...
    – Allister
    Nov 23 '18 at 20:29












  • I post my code. Hope you can help me :)
    – Allister
    Nov 23 '18 at 20:47
















-1














I'm new in c and sorry for my poor English.



I'm trying to write a program that ask to user if he want enter data (region, date of detection, mm of rain) using keyboard and save it in file or if he want give it file's name.
No problem at this time and file is written or read correctly.
File have this structure:



Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
....


Try with scanf() (not report main because there is no problem in it.



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese;
typedef struct data_s
{
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s
{
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s
{
tipo_dati_file* array;
int count;
} tipo_ritorna;

int conta_righe(char* Nome_f)
{
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

}
void crea_array (char* Nome_f)
{
int i,n;
char* regione= (char*)malloc(sizeof(char));
tipo_data data;
int mm_pioggia;
tipo_ritorna risultati;
FILE* file;
n = conta_righe(Nome_f);
printf("%dn",n);
tipo_dati_file* array = (tipo_dati_file*) malloc (n*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");
if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
for(i=0; i<=n; i++)
{
fscanf(file,"%s %d/%d/%d %dn",regione, &data.giorno, &data.mese, &data.anno, &mm_pioggia);
strcpy(array[i].regione, regione);
array[i].data.giorno=data.giorno;
array[i].data.mese= data.mese;
array[i].data.anno= data.anno;
array[i].mm_pioggia= mm_pioggia;
printf("%s %d/%d/%d %dn",array[i].regione,array[i].data.giorno, array[i].data.mese,array[i].data.anno,array[i].mm_pioggia);
}

fclose(file);
}


try with fgets()



#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese; typedef struct data_s {
int giorno;
tipo_mese mese;
int anno; } tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia; } tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count; } tipo_ritorna;

int conta_righe(char* Nome_f) {
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

} void crea_array (char* Nome_f, int v) {
int i=0,s;
char* r;
//tipo_ritorna risultati;
FILE* file;
//n = conta_righe(file);
tipo_dati_file* array = (tipo_dati_file*) malloc (v*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");

if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
if (feof(file)==0)
{
char* buf= (char*) malloc(v*sizeof(char));
/*while ( fgets( buf,10000, file) != NULL )
{
r = sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}*/
while(1)
{
r=fgets( buf,1000, file);
if (r!=NULL)
{
printf("%s",buf);
sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}
else exit(1);
}
}
else exit(1);

fclose(file); }









share|improve this question
























  • Please do publish your code. No matter how bad it is [or how bad you think it is], this is better than not showing it. We can only help you with what we see. There just isn't enough to work with, and many here will not help you further without seeing the code you've already written. See: stackoverflow.com/help/how-to-ask and follow the links, particularly: stackoverflow.com/help/mcve
    – Craig Estey
    Nov 23 '18 at 20:25










  • fist edit your post, it is barely readable. Then, what are your exact inputs, ouputs, and errors ? Where is your code ? We can't guess what you wrote and execute.
    – LoneWanderer
    Nov 23 '18 at 20:26










  • Don’t describe the code, show the code. Describing says ”this is basically what I’m telling the computer to do”. Problem is, computers don’t do “basically” what you tell them, they do exactly what you tell them. So tell us exactly what you’re telling the computer to do, i.e. show your code.
    – dbush
    Nov 23 '18 at 20:27












  • Ok i'll insert code my two try with fgets() and scanf() in first post. @LoneWanderer compiler don't gave me any error...
    – Allister
    Nov 23 '18 at 20:29












  • I post my code. Hope you can help me :)
    – Allister
    Nov 23 '18 at 20:47














-1












-1








-1







I'm new in c and sorry for my poor English.



I'm trying to write a program that ask to user if he want enter data (region, date of detection, mm of rain) using keyboard and save it in file or if he want give it file's name.
No problem at this time and file is written or read correctly.
File have this structure:



Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
....


Try with scanf() (not report main because there is no problem in it.



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese;
typedef struct data_s
{
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s
{
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s
{
tipo_dati_file* array;
int count;
} tipo_ritorna;

int conta_righe(char* Nome_f)
{
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

}
void crea_array (char* Nome_f)
{
int i,n;
char* regione= (char*)malloc(sizeof(char));
tipo_data data;
int mm_pioggia;
tipo_ritorna risultati;
FILE* file;
n = conta_righe(Nome_f);
printf("%dn",n);
tipo_dati_file* array = (tipo_dati_file*) malloc (n*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");
if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
for(i=0; i<=n; i++)
{
fscanf(file,"%s %d/%d/%d %dn",regione, &data.giorno, &data.mese, &data.anno, &mm_pioggia);
strcpy(array[i].regione, regione);
array[i].data.giorno=data.giorno;
array[i].data.mese= data.mese;
array[i].data.anno= data.anno;
array[i].mm_pioggia= mm_pioggia;
printf("%s %d/%d/%d %dn",array[i].regione,array[i].data.giorno, array[i].data.mese,array[i].data.anno,array[i].mm_pioggia);
}

fclose(file);
}


try with fgets()



#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese; typedef struct data_s {
int giorno;
tipo_mese mese;
int anno; } tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia; } tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count; } tipo_ritorna;

int conta_righe(char* Nome_f) {
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

} void crea_array (char* Nome_f, int v) {
int i=0,s;
char* r;
//tipo_ritorna risultati;
FILE* file;
//n = conta_righe(file);
tipo_dati_file* array = (tipo_dati_file*) malloc (v*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");

if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
if (feof(file)==0)
{
char* buf= (char*) malloc(v*sizeof(char));
/*while ( fgets( buf,10000, file) != NULL )
{
r = sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}*/
while(1)
{
r=fgets( buf,1000, file);
if (r!=NULL)
{
printf("%s",buf);
sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}
else exit(1);
}
}
else exit(1);

fclose(file); }









share|improve this question















I'm new in c and sorry for my poor English.



I'm trying to write a program that ask to user if he want enter data (region, date of detection, mm of rain) using keyboard and save it in file or if he want give it file's name.
No problem at this time and file is written or read correctly.
File have this structure:



Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
....


Try with scanf() (not report main because there is no problem in it.



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese;
typedef struct data_s
{
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s
{
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s
{
tipo_dati_file* array;
int count;
} tipo_ritorna;

int conta_righe(char* Nome_f)
{
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

}
void crea_array (char* Nome_f)
{
int i,n;
char* regione= (char*)malloc(sizeof(char));
tipo_data data;
int mm_pioggia;
tipo_ritorna risultati;
FILE* file;
n = conta_righe(Nome_f);
printf("%dn",n);
tipo_dati_file* array = (tipo_dati_file*) malloc (n*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");
if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
for(i=0; i<=n; i++)
{
fscanf(file,"%s %d/%d/%d %dn",regione, &data.giorno, &data.mese, &data.anno, &mm_pioggia);
strcpy(array[i].regione, regione);
array[i].data.giorno=data.giorno;
array[i].data.mese= data.mese;
array[i].data.anno= data.anno;
array[i].mm_pioggia= mm_pioggia;
printf("%s %d/%d/%d %dn",array[i].regione,array[i].data.giorno, array[i].data.mese,array[i].data.anno,array[i].mm_pioggia);
}

fclose(file);
}


try with fgets()



#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef enum mese_e {Gen=1, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic} tipo_mese; typedef struct data_s {
int giorno;
tipo_mese mese;
int anno; } tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia; } tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count; } tipo_ritorna;

int conta_righe(char* Nome_f) {
int i=0;
char c;
FILE* file;
file=fopen(Nome_f,"r");
while ((c=fgetc(file))!=EOF)
{if(c=='n')
i++;}
fclose(file);
return i;

} void crea_array (char* Nome_f, int v) {
int i=0,s;
char* r;
//tipo_ritorna risultati;
FILE* file;
//n = conta_righe(file);
tipo_dati_file* array = (tipo_dati_file*) malloc (v*sizeof (tipo_dati_file));
file = fopen(Nome_f,"r");

if( file==NULL )
{
printf("Errore in apertura del file!");
exit(1);
}
if (feof(file)==0)
{
char* buf= (char*) malloc(v*sizeof(char));
/*while ( fgets( buf,10000, file) != NULL )
{
r = sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}*/
while(1)
{
r=fgets( buf,1000, file);
if (r!=NULL)
{
printf("%s",buf);
sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia);
printf("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno, array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}
else exit(1);
}
}
else exit(1);

fclose(file); }






c arrays struct






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 20:45







Allister

















asked Nov 23 '18 at 20:16









AllisterAllister

12




12












  • Please do publish your code. No matter how bad it is [or how bad you think it is], this is better than not showing it. We can only help you with what we see. There just isn't enough to work with, and many here will not help you further without seeing the code you've already written. See: stackoverflow.com/help/how-to-ask and follow the links, particularly: stackoverflow.com/help/mcve
    – Craig Estey
    Nov 23 '18 at 20:25










  • fist edit your post, it is barely readable. Then, what are your exact inputs, ouputs, and errors ? Where is your code ? We can't guess what you wrote and execute.
    – LoneWanderer
    Nov 23 '18 at 20:26










  • Don’t describe the code, show the code. Describing says ”this is basically what I’m telling the computer to do”. Problem is, computers don’t do “basically” what you tell them, they do exactly what you tell them. So tell us exactly what you’re telling the computer to do, i.e. show your code.
    – dbush
    Nov 23 '18 at 20:27












  • Ok i'll insert code my two try with fgets() and scanf() in first post. @LoneWanderer compiler don't gave me any error...
    – Allister
    Nov 23 '18 at 20:29












  • I post my code. Hope you can help me :)
    – Allister
    Nov 23 '18 at 20:47


















  • Please do publish your code. No matter how bad it is [or how bad you think it is], this is better than not showing it. We can only help you with what we see. There just isn't enough to work with, and many here will not help you further without seeing the code you've already written. See: stackoverflow.com/help/how-to-ask and follow the links, particularly: stackoverflow.com/help/mcve
    – Craig Estey
    Nov 23 '18 at 20:25










  • fist edit your post, it is barely readable. Then, what are your exact inputs, ouputs, and errors ? Where is your code ? We can't guess what you wrote and execute.
    – LoneWanderer
    Nov 23 '18 at 20:26










  • Don’t describe the code, show the code. Describing says ”this is basically what I’m telling the computer to do”. Problem is, computers don’t do “basically” what you tell them, they do exactly what you tell them. So tell us exactly what you’re telling the computer to do, i.e. show your code.
    – dbush
    Nov 23 '18 at 20:27












  • Ok i'll insert code my two try with fgets() and scanf() in first post. @LoneWanderer compiler don't gave me any error...
    – Allister
    Nov 23 '18 at 20:29












  • I post my code. Hope you can help me :)
    – Allister
    Nov 23 '18 at 20:47
















Please do publish your code. No matter how bad it is [or how bad you think it is], this is better than not showing it. We can only help you with what we see. There just isn't enough to work with, and many here will not help you further without seeing the code you've already written. See: stackoverflow.com/help/how-to-ask and follow the links, particularly: stackoverflow.com/help/mcve
– Craig Estey
Nov 23 '18 at 20:25




Please do publish your code. No matter how bad it is [or how bad you think it is], this is better than not showing it. We can only help you with what we see. There just isn't enough to work with, and many here will not help you further without seeing the code you've already written. See: stackoverflow.com/help/how-to-ask and follow the links, particularly: stackoverflow.com/help/mcve
– Craig Estey
Nov 23 '18 at 20:25












fist edit your post, it is barely readable. Then, what are your exact inputs, ouputs, and errors ? Where is your code ? We can't guess what you wrote and execute.
– LoneWanderer
Nov 23 '18 at 20:26




fist edit your post, it is barely readable. Then, what are your exact inputs, ouputs, and errors ? Where is your code ? We can't guess what you wrote and execute.
– LoneWanderer
Nov 23 '18 at 20:26












Don’t describe the code, show the code. Describing says ”this is basically what I’m telling the computer to do”. Problem is, computers don’t do “basically” what you tell them, they do exactly what you tell them. So tell us exactly what you’re telling the computer to do, i.e. show your code.
– dbush
Nov 23 '18 at 20:27






Don’t describe the code, show the code. Describing says ”this is basically what I’m telling the computer to do”. Problem is, computers don’t do “basically” what you tell them, they do exactly what you tell them. So tell us exactly what you’re telling the computer to do, i.e. show your code.
– dbush
Nov 23 '18 at 20:27














Ok i'll insert code my two try with fgets() and scanf() in first post. @LoneWanderer compiler don't gave me any error...
– Allister
Nov 23 '18 at 20:29






Ok i'll insert code my two try with fgets() and scanf() in first post. @LoneWanderer compiler don't gave me any error...
– Allister
Nov 23 '18 at 20:29














I post my code. Hope you can help me :)
– Allister
Nov 23 '18 at 20:47




I post my code. Hope you can help me :)
– Allister
Nov 23 '18 at 20:47












1 Answer
1






active

oldest

votes


















1














You have two primary problems I see in crea_array,




  1. You declare char* r; but then attempt to assign the return of sscanf (buf, "%s %d/%d/%d %dn", ... (e.g. r = sscanf (.... This is incorrect. sscanf returns type int representing the number of successful conversions that took place as specified in your format string (e.g. "%s %d/%d/%d %dn" would return 5 on success, and remove the 'n', it will cause problems). Your compiler should be screaming warnings at you. If not, you need to enable compiler warnings by adding -Wall -Wextra -pedantic as compiler options and do not accept code until it compiles without a single warning.


  2. crea_array must be declared as type tipo_dati_file * and it must return array; at the end. You must assign the return to a pointer back in the caller. You must also free (buf); before the return or you have just created a memory leak as there is no way to free() the memory you allocated for buf after the function returns. (further, if you are simply allocating 1000-char each time, just use a fixed buffer, e.g. char buf[1000]; and eliminate the need to allocate buf completely.


Putting it altogether, you could do something similar to:



#define MAXC 1000   /* if you need a constant, #define one (or more) */

tipo_dati_file *crea_array (char* Nome_f, int v)
{
int i = 0,
s,
r;
char buf[MAXC] = "";
//tipo_ritorna risultati;
FILE* file;

//n = conta_righe(file);
tipo_dati_file *array = malloc (v * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
exit (EXIT_FAILURE);
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
exit (EXIT_FAILURE);
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", array[i].regione,
&array[i].data.giorno, &array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fput ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

printf ("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno,
array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}

fclose (file);

return array;
}


Note: I have not compiled the code above.



Then in main, you could do something similar to:



tipo_dati_file *array = crea_array (name, v);


(note: you should also pass a 3rd parameter of type int *numelem so you can assign *numelem = i; before return making the number of elements filled available back in the caller if less than v are actually read)



If you will post a A Minimal, Complete, and Verifiable Example (MCVE), along with a sample data file (10 lines or so), I'm happy to help further and I can validate the code works -- as I will have something I can compile and run.



Edit Following Warnings Posted (in comments)



The two warnings are addressed in detail in the comments below the answer. Once those are resolved, you will run into a horrible SegFault as you are not allocating storage for array[i].regione.



In you nested set of structs:



typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;


regione is an uninitialized pointer that points to some indeterminate memory location (which you do not own). When you attempt to write characters there with sscanf (BOOM - SegFault -- most likely).



You have two choices (1) declare regione as a fixed array, e.g. char regione[CONST] (inefficient), or (2) read the string for regione into a temporary buffer and then allocate storage for strlen + 1 chars and copy the string from the temporary buffer to the new block of memory and assign the starting address for that block to regione (you can use strlen/malloc/memcpy or strdup -- if you have it, it does all three)



With that fix and a few tweaks to your crea_array function (like passing a pointer to int to hold the number of struct filled in array instead of v), you could do something like the following:



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

#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXDATA 64

typedef enum mese_e { Genv= 1, Feb, Mar, Apr, Mag, Giu,
Lug, Ago, Set, Ott, Nov, Dic
} tipo_mese;

typedef struct data_s {
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count;
} tipo_ritorna;

tipo_dati_file *crea_array (char *Nome_f, int *nelem)
{
int i = 0,
r;
char region[MAXC] = ""; /* temp buffer to hold array[i].regione */
char buf[MAXC] = "";
FILE* file;

tipo_dati_file *array = malloc (MAXDATA * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
return NULL;
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
return NULL;
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", region,
&array[i].data.giorno, (int*)&array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fputs ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

array[i].regione = strdup (region);
if (!array[i].regione) { /* strdup allocates - you must validate */
perror ("strdup-array[i].regione");
for (int j = 0; j < i; j++) /* on failure free prior mem */
free (array[j].regione); /* and return NULL */
free (array);
return NULL;
}

i++;
}

fclose (file);

*nelem = i; /* update nelem with number of struct filled */

return array;
}

int main (int argc, char **argv) {

int index = 0,
nelem = 0;
char *datafile = argc > 1 ? argv[1] : "dat/staterain.txt";
tipo_ritorna statistics[MAXDATA] = {{ .array = NULL }};

statistics[index].array = crea_array (datafile, &nelem);

if (statistics[index].array && nelem > 0) {
statistics[index].count = nelem;
for (int i = 0; i < statistics[index].count; i++) {
printf ("%-12s %02d/%02d/%4d %3dn",
statistics[index].array[i].regione,
statistics[index].array[i].data.giorno,
statistics[index].array[i].data.mese,
statistics[index].array[i].data.anno,
statistics[index].array[i].mm_pioggia);
free (statistics[index].array[i].regione); /* free strings */
}
free (statistics[index].array); /* free array */
}

return 0;
}


Example Use/Output



$ ./bin/staterain
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10


Memory Use/Error Check



In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.



It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.



For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.



$ valgrind ./bin/staterain
==3349== Memcheck, a memory error detector
==3349== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3349== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==3349== Command: ./bin/staterain
==3349==
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
==3349==
==3349== HEAP SUMMARY:
==3349== in use at exit: 0 bytes in 0 blocks
==3349== total heap usage: 5 allocs, 5 frees, 2,110 bytes allocated
==3349==
==3349== All heap blocks were freed -- no leaks are possible
==3349==
==3349== For counts of detected and suppressed errors, rerun with: -v
==3349== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


Always confirm that you have freed all memory you have allocated and that there are no memory errors.



Look things over and let me know if you have further questions.






share|improve this answer























  • Thanks! 1) I'll correct that things. 2) Function not should return array but two things: array and count ((number of file's lines). For this reason i have created struct ritorna_s. But i don't know if is the right way to do it...
    – Allister
    Nov 23 '18 at 22:05










  • " and do not accept code until it compiles without a single warning" I could not agree more
    – LoneWanderer
    Nov 23 '18 at 22:12










  • I enable compiler warning and compiler give me 5 warning. 'C:....Prova 4stack overflow modifica.c:74:30: warning: unknown conversion type character 0x20 in format [-Wformat=] sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia); ^ C:....Prova 4stack overflow modifica.c:74:30: warning: format '%d' expects argument of type 'int *', but argument 5 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=]'
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c:74:30: warning: too many arguments for format [-Wformat-extra-args] C:....Prova 4stack overflow modifica.c:46:13: warning: unused variable 's' [-Wunused-variable] int i=0,s; ^
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c: In function 'main': C:....Prova 4stack overflow modifica.c:130:28: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=] scanf ("%d/%d/%d", &data.giorno, &data.mese, &data.anno);
    – Allister
    Nov 23 '18 at 22:18











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452504%2fstruct-and-dynamic-array%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














You have two primary problems I see in crea_array,




  1. You declare char* r; but then attempt to assign the return of sscanf (buf, "%s %d/%d/%d %dn", ... (e.g. r = sscanf (.... This is incorrect. sscanf returns type int representing the number of successful conversions that took place as specified in your format string (e.g. "%s %d/%d/%d %dn" would return 5 on success, and remove the 'n', it will cause problems). Your compiler should be screaming warnings at you. If not, you need to enable compiler warnings by adding -Wall -Wextra -pedantic as compiler options and do not accept code until it compiles without a single warning.


  2. crea_array must be declared as type tipo_dati_file * and it must return array; at the end. You must assign the return to a pointer back in the caller. You must also free (buf); before the return or you have just created a memory leak as there is no way to free() the memory you allocated for buf after the function returns. (further, if you are simply allocating 1000-char each time, just use a fixed buffer, e.g. char buf[1000]; and eliminate the need to allocate buf completely.


Putting it altogether, you could do something similar to:



#define MAXC 1000   /* if you need a constant, #define one (or more) */

tipo_dati_file *crea_array (char* Nome_f, int v)
{
int i = 0,
s,
r;
char buf[MAXC] = "";
//tipo_ritorna risultati;
FILE* file;

//n = conta_righe(file);
tipo_dati_file *array = malloc (v * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
exit (EXIT_FAILURE);
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
exit (EXIT_FAILURE);
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", array[i].regione,
&array[i].data.giorno, &array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fput ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

printf ("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno,
array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}

fclose (file);

return array;
}


Note: I have not compiled the code above.



Then in main, you could do something similar to:



tipo_dati_file *array = crea_array (name, v);


(note: you should also pass a 3rd parameter of type int *numelem so you can assign *numelem = i; before return making the number of elements filled available back in the caller if less than v are actually read)



If you will post a A Minimal, Complete, and Verifiable Example (MCVE), along with a sample data file (10 lines or so), I'm happy to help further and I can validate the code works -- as I will have something I can compile and run.



Edit Following Warnings Posted (in comments)



The two warnings are addressed in detail in the comments below the answer. Once those are resolved, you will run into a horrible SegFault as you are not allocating storage for array[i].regione.



In you nested set of structs:



typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;


regione is an uninitialized pointer that points to some indeterminate memory location (which you do not own). When you attempt to write characters there with sscanf (BOOM - SegFault -- most likely).



You have two choices (1) declare regione as a fixed array, e.g. char regione[CONST] (inefficient), or (2) read the string for regione into a temporary buffer and then allocate storage for strlen + 1 chars and copy the string from the temporary buffer to the new block of memory and assign the starting address for that block to regione (you can use strlen/malloc/memcpy or strdup -- if you have it, it does all three)



With that fix and a few tweaks to your crea_array function (like passing a pointer to int to hold the number of struct filled in array instead of v), you could do something like the following:



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

#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXDATA 64

typedef enum mese_e { Genv= 1, Feb, Mar, Apr, Mag, Giu,
Lug, Ago, Set, Ott, Nov, Dic
} tipo_mese;

typedef struct data_s {
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count;
} tipo_ritorna;

tipo_dati_file *crea_array (char *Nome_f, int *nelem)
{
int i = 0,
r;
char region[MAXC] = ""; /* temp buffer to hold array[i].regione */
char buf[MAXC] = "";
FILE* file;

tipo_dati_file *array = malloc (MAXDATA * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
return NULL;
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
return NULL;
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", region,
&array[i].data.giorno, (int*)&array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fputs ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

array[i].regione = strdup (region);
if (!array[i].regione) { /* strdup allocates - you must validate */
perror ("strdup-array[i].regione");
for (int j = 0; j < i; j++) /* on failure free prior mem */
free (array[j].regione); /* and return NULL */
free (array);
return NULL;
}

i++;
}

fclose (file);

*nelem = i; /* update nelem with number of struct filled */

return array;
}

int main (int argc, char **argv) {

int index = 0,
nelem = 0;
char *datafile = argc > 1 ? argv[1] : "dat/staterain.txt";
tipo_ritorna statistics[MAXDATA] = {{ .array = NULL }};

statistics[index].array = crea_array (datafile, &nelem);

if (statistics[index].array && nelem > 0) {
statistics[index].count = nelem;
for (int i = 0; i < statistics[index].count; i++) {
printf ("%-12s %02d/%02d/%4d %3dn",
statistics[index].array[i].regione,
statistics[index].array[i].data.giorno,
statistics[index].array[i].data.mese,
statistics[index].array[i].data.anno,
statistics[index].array[i].mm_pioggia);
free (statistics[index].array[i].regione); /* free strings */
}
free (statistics[index].array); /* free array */
}

return 0;
}


Example Use/Output



$ ./bin/staterain
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10


Memory Use/Error Check



In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.



It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.



For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.



$ valgrind ./bin/staterain
==3349== Memcheck, a memory error detector
==3349== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3349== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==3349== Command: ./bin/staterain
==3349==
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
==3349==
==3349== HEAP SUMMARY:
==3349== in use at exit: 0 bytes in 0 blocks
==3349== total heap usage: 5 allocs, 5 frees, 2,110 bytes allocated
==3349==
==3349== All heap blocks were freed -- no leaks are possible
==3349==
==3349== For counts of detected and suppressed errors, rerun with: -v
==3349== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


Always confirm that you have freed all memory you have allocated and that there are no memory errors.



Look things over and let me know if you have further questions.






share|improve this answer























  • Thanks! 1) I'll correct that things. 2) Function not should return array but two things: array and count ((number of file's lines). For this reason i have created struct ritorna_s. But i don't know if is the right way to do it...
    – Allister
    Nov 23 '18 at 22:05










  • " and do not accept code until it compiles without a single warning" I could not agree more
    – LoneWanderer
    Nov 23 '18 at 22:12










  • I enable compiler warning and compiler give me 5 warning. 'C:....Prova 4stack overflow modifica.c:74:30: warning: unknown conversion type character 0x20 in format [-Wformat=] sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia); ^ C:....Prova 4stack overflow modifica.c:74:30: warning: format '%d' expects argument of type 'int *', but argument 5 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=]'
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c:74:30: warning: too many arguments for format [-Wformat-extra-args] C:....Prova 4stack overflow modifica.c:46:13: warning: unused variable 's' [-Wunused-variable] int i=0,s; ^
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c: In function 'main': C:....Prova 4stack overflow modifica.c:130:28: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=] scanf ("%d/%d/%d", &data.giorno, &data.mese, &data.anno);
    – Allister
    Nov 23 '18 at 22:18
















1














You have two primary problems I see in crea_array,




  1. You declare char* r; but then attempt to assign the return of sscanf (buf, "%s %d/%d/%d %dn", ... (e.g. r = sscanf (.... This is incorrect. sscanf returns type int representing the number of successful conversions that took place as specified in your format string (e.g. "%s %d/%d/%d %dn" would return 5 on success, and remove the 'n', it will cause problems). Your compiler should be screaming warnings at you. If not, you need to enable compiler warnings by adding -Wall -Wextra -pedantic as compiler options and do not accept code until it compiles without a single warning.


  2. crea_array must be declared as type tipo_dati_file * and it must return array; at the end. You must assign the return to a pointer back in the caller. You must also free (buf); before the return or you have just created a memory leak as there is no way to free() the memory you allocated for buf after the function returns. (further, if you are simply allocating 1000-char each time, just use a fixed buffer, e.g. char buf[1000]; and eliminate the need to allocate buf completely.


Putting it altogether, you could do something similar to:



#define MAXC 1000   /* if you need a constant, #define one (or more) */

tipo_dati_file *crea_array (char* Nome_f, int v)
{
int i = 0,
s,
r;
char buf[MAXC] = "";
//tipo_ritorna risultati;
FILE* file;

//n = conta_righe(file);
tipo_dati_file *array = malloc (v * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
exit (EXIT_FAILURE);
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
exit (EXIT_FAILURE);
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", array[i].regione,
&array[i].data.giorno, &array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fput ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

printf ("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno,
array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}

fclose (file);

return array;
}


Note: I have not compiled the code above.



Then in main, you could do something similar to:



tipo_dati_file *array = crea_array (name, v);


(note: you should also pass a 3rd parameter of type int *numelem so you can assign *numelem = i; before return making the number of elements filled available back in the caller if less than v are actually read)



If you will post a A Minimal, Complete, and Verifiable Example (MCVE), along with a sample data file (10 lines or so), I'm happy to help further and I can validate the code works -- as I will have something I can compile and run.



Edit Following Warnings Posted (in comments)



The two warnings are addressed in detail in the comments below the answer. Once those are resolved, you will run into a horrible SegFault as you are not allocating storage for array[i].regione.



In you nested set of structs:



typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;


regione is an uninitialized pointer that points to some indeterminate memory location (which you do not own). When you attempt to write characters there with sscanf (BOOM - SegFault -- most likely).



You have two choices (1) declare regione as a fixed array, e.g. char regione[CONST] (inefficient), or (2) read the string for regione into a temporary buffer and then allocate storage for strlen + 1 chars and copy the string from the temporary buffer to the new block of memory and assign the starting address for that block to regione (you can use strlen/malloc/memcpy or strdup -- if you have it, it does all three)



With that fix and a few tweaks to your crea_array function (like passing a pointer to int to hold the number of struct filled in array instead of v), you could do something like the following:



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

#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXDATA 64

typedef enum mese_e { Genv= 1, Feb, Mar, Apr, Mag, Giu,
Lug, Ago, Set, Ott, Nov, Dic
} tipo_mese;

typedef struct data_s {
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count;
} tipo_ritorna;

tipo_dati_file *crea_array (char *Nome_f, int *nelem)
{
int i = 0,
r;
char region[MAXC] = ""; /* temp buffer to hold array[i].regione */
char buf[MAXC] = "";
FILE* file;

tipo_dati_file *array = malloc (MAXDATA * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
return NULL;
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
return NULL;
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", region,
&array[i].data.giorno, (int*)&array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fputs ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

array[i].regione = strdup (region);
if (!array[i].regione) { /* strdup allocates - you must validate */
perror ("strdup-array[i].regione");
for (int j = 0; j < i; j++) /* on failure free prior mem */
free (array[j].regione); /* and return NULL */
free (array);
return NULL;
}

i++;
}

fclose (file);

*nelem = i; /* update nelem with number of struct filled */

return array;
}

int main (int argc, char **argv) {

int index = 0,
nelem = 0;
char *datafile = argc > 1 ? argv[1] : "dat/staterain.txt";
tipo_ritorna statistics[MAXDATA] = {{ .array = NULL }};

statistics[index].array = crea_array (datafile, &nelem);

if (statistics[index].array && nelem > 0) {
statistics[index].count = nelem;
for (int i = 0; i < statistics[index].count; i++) {
printf ("%-12s %02d/%02d/%4d %3dn",
statistics[index].array[i].regione,
statistics[index].array[i].data.giorno,
statistics[index].array[i].data.mese,
statistics[index].array[i].data.anno,
statistics[index].array[i].mm_pioggia);
free (statistics[index].array[i].regione); /* free strings */
}
free (statistics[index].array); /* free array */
}

return 0;
}


Example Use/Output



$ ./bin/staterain
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10


Memory Use/Error Check



In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.



It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.



For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.



$ valgrind ./bin/staterain
==3349== Memcheck, a memory error detector
==3349== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3349== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==3349== Command: ./bin/staterain
==3349==
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
==3349==
==3349== HEAP SUMMARY:
==3349== in use at exit: 0 bytes in 0 blocks
==3349== total heap usage: 5 allocs, 5 frees, 2,110 bytes allocated
==3349==
==3349== All heap blocks were freed -- no leaks are possible
==3349==
==3349== For counts of detected and suppressed errors, rerun with: -v
==3349== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


Always confirm that you have freed all memory you have allocated and that there are no memory errors.



Look things over and let me know if you have further questions.






share|improve this answer























  • Thanks! 1) I'll correct that things. 2) Function not should return array but two things: array and count ((number of file's lines). For this reason i have created struct ritorna_s. But i don't know if is the right way to do it...
    – Allister
    Nov 23 '18 at 22:05










  • " and do not accept code until it compiles without a single warning" I could not agree more
    – LoneWanderer
    Nov 23 '18 at 22:12










  • I enable compiler warning and compiler give me 5 warning. 'C:....Prova 4stack overflow modifica.c:74:30: warning: unknown conversion type character 0x20 in format [-Wformat=] sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia); ^ C:....Prova 4stack overflow modifica.c:74:30: warning: format '%d' expects argument of type 'int *', but argument 5 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=]'
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c:74:30: warning: too many arguments for format [-Wformat-extra-args] C:....Prova 4stack overflow modifica.c:46:13: warning: unused variable 's' [-Wunused-variable] int i=0,s; ^
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c: In function 'main': C:....Prova 4stack overflow modifica.c:130:28: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=] scanf ("%d/%d/%d", &data.giorno, &data.mese, &data.anno);
    – Allister
    Nov 23 '18 at 22:18














1












1








1






You have two primary problems I see in crea_array,




  1. You declare char* r; but then attempt to assign the return of sscanf (buf, "%s %d/%d/%d %dn", ... (e.g. r = sscanf (.... This is incorrect. sscanf returns type int representing the number of successful conversions that took place as specified in your format string (e.g. "%s %d/%d/%d %dn" would return 5 on success, and remove the 'n', it will cause problems). Your compiler should be screaming warnings at you. If not, you need to enable compiler warnings by adding -Wall -Wextra -pedantic as compiler options and do not accept code until it compiles without a single warning.


  2. crea_array must be declared as type tipo_dati_file * and it must return array; at the end. You must assign the return to a pointer back in the caller. You must also free (buf); before the return or you have just created a memory leak as there is no way to free() the memory you allocated for buf after the function returns. (further, if you are simply allocating 1000-char each time, just use a fixed buffer, e.g. char buf[1000]; and eliminate the need to allocate buf completely.


Putting it altogether, you could do something similar to:



#define MAXC 1000   /* if you need a constant, #define one (or more) */

tipo_dati_file *crea_array (char* Nome_f, int v)
{
int i = 0,
s,
r;
char buf[MAXC] = "";
//tipo_ritorna risultati;
FILE* file;

//n = conta_righe(file);
tipo_dati_file *array = malloc (v * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
exit (EXIT_FAILURE);
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
exit (EXIT_FAILURE);
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", array[i].regione,
&array[i].data.giorno, &array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fput ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

printf ("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno,
array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}

fclose (file);

return array;
}


Note: I have not compiled the code above.



Then in main, you could do something similar to:



tipo_dati_file *array = crea_array (name, v);


(note: you should also pass a 3rd parameter of type int *numelem so you can assign *numelem = i; before return making the number of elements filled available back in the caller if less than v are actually read)



If you will post a A Minimal, Complete, and Verifiable Example (MCVE), along with a sample data file (10 lines or so), I'm happy to help further and I can validate the code works -- as I will have something I can compile and run.



Edit Following Warnings Posted (in comments)



The two warnings are addressed in detail in the comments below the answer. Once those are resolved, you will run into a horrible SegFault as you are not allocating storage for array[i].regione.



In you nested set of structs:



typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;


regione is an uninitialized pointer that points to some indeterminate memory location (which you do not own). When you attempt to write characters there with sscanf (BOOM - SegFault -- most likely).



You have two choices (1) declare regione as a fixed array, e.g. char regione[CONST] (inefficient), or (2) read the string for regione into a temporary buffer and then allocate storage for strlen + 1 chars and copy the string from the temporary buffer to the new block of memory and assign the starting address for that block to regione (you can use strlen/malloc/memcpy or strdup -- if you have it, it does all three)



With that fix and a few tweaks to your crea_array function (like passing a pointer to int to hold the number of struct filled in array instead of v), you could do something like the following:



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

#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXDATA 64

typedef enum mese_e { Genv= 1, Feb, Mar, Apr, Mag, Giu,
Lug, Ago, Set, Ott, Nov, Dic
} tipo_mese;

typedef struct data_s {
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count;
} tipo_ritorna;

tipo_dati_file *crea_array (char *Nome_f, int *nelem)
{
int i = 0,
r;
char region[MAXC] = ""; /* temp buffer to hold array[i].regione */
char buf[MAXC] = "";
FILE* file;

tipo_dati_file *array = malloc (MAXDATA * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
return NULL;
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
return NULL;
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", region,
&array[i].data.giorno, (int*)&array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fputs ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

array[i].regione = strdup (region);
if (!array[i].regione) { /* strdup allocates - you must validate */
perror ("strdup-array[i].regione");
for (int j = 0; j < i; j++) /* on failure free prior mem */
free (array[j].regione); /* and return NULL */
free (array);
return NULL;
}

i++;
}

fclose (file);

*nelem = i; /* update nelem with number of struct filled */

return array;
}

int main (int argc, char **argv) {

int index = 0,
nelem = 0;
char *datafile = argc > 1 ? argv[1] : "dat/staterain.txt";
tipo_ritorna statistics[MAXDATA] = {{ .array = NULL }};

statistics[index].array = crea_array (datafile, &nelem);

if (statistics[index].array && nelem > 0) {
statistics[index].count = nelem;
for (int i = 0; i < statistics[index].count; i++) {
printf ("%-12s %02d/%02d/%4d %3dn",
statistics[index].array[i].regione,
statistics[index].array[i].data.giorno,
statistics[index].array[i].data.mese,
statistics[index].array[i].data.anno,
statistics[index].array[i].mm_pioggia);
free (statistics[index].array[i].regione); /* free strings */
}
free (statistics[index].array); /* free array */
}

return 0;
}


Example Use/Output



$ ./bin/staterain
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10


Memory Use/Error Check



In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.



It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.



For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.



$ valgrind ./bin/staterain
==3349== Memcheck, a memory error detector
==3349== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3349== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==3349== Command: ./bin/staterain
==3349==
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
==3349==
==3349== HEAP SUMMARY:
==3349== in use at exit: 0 bytes in 0 blocks
==3349== total heap usage: 5 allocs, 5 frees, 2,110 bytes allocated
==3349==
==3349== All heap blocks were freed -- no leaks are possible
==3349==
==3349== For counts of detected and suppressed errors, rerun with: -v
==3349== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


Always confirm that you have freed all memory you have allocated and that there are no memory errors.



Look things over and let me know if you have further questions.






share|improve this answer














You have two primary problems I see in crea_array,




  1. You declare char* r; but then attempt to assign the return of sscanf (buf, "%s %d/%d/%d %dn", ... (e.g. r = sscanf (.... This is incorrect. sscanf returns type int representing the number of successful conversions that took place as specified in your format string (e.g. "%s %d/%d/%d %dn" would return 5 on success, and remove the 'n', it will cause problems). Your compiler should be screaming warnings at you. If not, you need to enable compiler warnings by adding -Wall -Wextra -pedantic as compiler options and do not accept code until it compiles without a single warning.


  2. crea_array must be declared as type tipo_dati_file * and it must return array; at the end. You must assign the return to a pointer back in the caller. You must also free (buf); before the return or you have just created a memory leak as there is no way to free() the memory you allocated for buf after the function returns. (further, if you are simply allocating 1000-char each time, just use a fixed buffer, e.g. char buf[1000]; and eliminate the need to allocate buf completely.


Putting it altogether, you could do something similar to:



#define MAXC 1000   /* if you need a constant, #define one (or more) */

tipo_dati_file *crea_array (char* Nome_f, int v)
{
int i = 0,
s,
r;
char buf[MAXC] = "";
//tipo_ritorna risultati;
FILE* file;

//n = conta_righe(file);
tipo_dati_file *array = malloc (v * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
exit (EXIT_FAILURE);
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
exit (EXIT_FAILURE);
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", array[i].regione,
&array[i].data.giorno, &array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fput ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

printf ("%s %d/%d/%d %dn", array[i].regione, array[i].data.giorno,
array[i].data.mese, array[i].data.anno, array[i].mm_pioggia);
i++;
}

fclose (file);

return array;
}


Note: I have not compiled the code above.



Then in main, you could do something similar to:



tipo_dati_file *array = crea_array (name, v);


(note: you should also pass a 3rd parameter of type int *numelem so you can assign *numelem = i; before return making the number of elements filled available back in the caller if less than v are actually read)



If you will post a A Minimal, Complete, and Verifiable Example (MCVE), along with a sample data file (10 lines or so), I'm happy to help further and I can validate the code works -- as I will have something I can compile and run.



Edit Following Warnings Posted (in comments)



The two warnings are addressed in detail in the comments below the answer. Once those are resolved, you will run into a horrible SegFault as you are not allocating storage for array[i].regione.



In you nested set of structs:



typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;


regione is an uninitialized pointer that points to some indeterminate memory location (which you do not own). When you attempt to write characters there with sscanf (BOOM - SegFault -- most likely).



You have two choices (1) declare regione as a fixed array, e.g. char regione[CONST] (inefficient), or (2) read the string for regione into a temporary buffer and then allocate storage for strlen + 1 chars and copy the string from the temporary buffer to the new block of memory and assign the starting address for that block to regione (you can use strlen/malloc/memcpy or strdup -- if you have it, it does all three)



With that fix and a few tweaks to your crea_array function (like passing a pointer to int to hold the number of struct filled in array instead of v), you could do something like the following:



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

#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define MAXDATA 64

typedef enum mese_e { Genv= 1, Feb, Mar, Apr, Mag, Giu,
Lug, Ago, Set, Ott, Nov, Dic
} tipo_mese;

typedef struct data_s {
int giorno;
tipo_mese mese;
int anno;
} tipo_data;

typedef struct dati_file_s {
char* regione;
tipo_data data;
int mm_pioggia;
} tipo_dati_file;

typedef struct ritorna_s {
tipo_dati_file* array;
int count;
} tipo_ritorna;

tipo_dati_file *crea_array (char *Nome_f, int *nelem)
{
int i = 0,
r;
char region[MAXC] = ""; /* temp buffer to hold array[i].regione */
char buf[MAXC] = "";
FILE* file;

tipo_dati_file *array = malloc (MAXDATA * sizeof *array);
file = fopen (Nome_f, "r");

if (file == NULL) {
printf ("Errore in apertura del file!");
return NULL;
}

if (!array) { /* if you allocate, you must validate - every time */
perror ("malloc-array");
return NULL;
}

while (fgets (buf, MAXC, file) != NULL)
{
r = sscanf (buf, "%s %d/%d/%d %d", region,
&array[i].data.giorno, (int*)&array[i].data.mese,
&array[i].data.anno, &array[i].mm_pioggia);

if (r != 5) { /* validate return of every (s)scanf funciton */
fputs ("error: failed to parse buf.n", stderr);
continue; /* get next line */
}

array[i].regione = strdup (region);
if (!array[i].regione) { /* strdup allocates - you must validate */
perror ("strdup-array[i].regione");
for (int j = 0; j < i; j++) /* on failure free prior mem */
free (array[j].regione); /* and return NULL */
free (array);
return NULL;
}

i++;
}

fclose (file);

*nelem = i; /* update nelem with number of struct filled */

return array;
}

int main (int argc, char **argv) {

int index = 0,
nelem = 0;
char *datafile = argc > 1 ? argv[1] : "dat/staterain.txt";
tipo_ritorna statistics[MAXDATA] = {{ .array = NULL }};

statistics[index].array = crea_array (datafile, &nelem);

if (statistics[index].array && nelem > 0) {
statistics[index].count = nelem;
for (int i = 0; i < statistics[index].count; i++) {
printf ("%-12s %02d/%02d/%4d %3dn",
statistics[index].array[i].regione,
statistics[index].array[i].data.giorno,
statistics[index].array[i].data.mese,
statistics[index].array[i].data.anno,
statistics[index].array[i].mm_pioggia);
free (statistics[index].array[i].regione); /* free strings */
}
free (statistics[index].array); /* free array */
}

return 0;
}


Example Use/Output



$ ./bin/staterain
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10


Memory Use/Error Check



In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.



It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.



For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.



$ valgrind ./bin/staterain
==3349== Memcheck, a memory error detector
==3349== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3349== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==3349== Command: ./bin/staterain
==3349==
Texas 03/03/2015 1
California 06/02/2013 5
Utah 03/01/2014 10
==3349==
==3349== HEAP SUMMARY:
==3349== in use at exit: 0 bytes in 0 blocks
==3349== total heap usage: 5 allocs, 5 frees, 2,110 bytes allocated
==3349==
==3349== All heap blocks were freed -- no leaks are possible
==3349==
==3349== For counts of detected and suppressed errors, rerun with: -v
==3349== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


Always confirm that you have freed all memory you have allocated and that there are no memory errors.



Look things over and let me know if you have further questions.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 24 '18 at 1:06

























answered Nov 23 '18 at 21:32









David C. RankinDavid C. Rankin

40.6k32648




40.6k32648












  • Thanks! 1) I'll correct that things. 2) Function not should return array but two things: array and count ((number of file's lines). For this reason i have created struct ritorna_s. But i don't know if is the right way to do it...
    – Allister
    Nov 23 '18 at 22:05










  • " and do not accept code until it compiles without a single warning" I could not agree more
    – LoneWanderer
    Nov 23 '18 at 22:12










  • I enable compiler warning and compiler give me 5 warning. 'C:....Prova 4stack overflow modifica.c:74:30: warning: unknown conversion type character 0x20 in format [-Wformat=] sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia); ^ C:....Prova 4stack overflow modifica.c:74:30: warning: format '%d' expects argument of type 'int *', but argument 5 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=]'
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c:74:30: warning: too many arguments for format [-Wformat-extra-args] C:....Prova 4stack overflow modifica.c:46:13: warning: unused variable 's' [-Wunused-variable] int i=0,s; ^
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c: In function 'main': C:....Prova 4stack overflow modifica.c:130:28: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=] scanf ("%d/%d/%d", &data.giorno, &data.mese, &data.anno);
    – Allister
    Nov 23 '18 at 22:18


















  • Thanks! 1) I'll correct that things. 2) Function not should return array but two things: array and count ((number of file's lines). For this reason i have created struct ritorna_s. But i don't know if is the right way to do it...
    – Allister
    Nov 23 '18 at 22:05










  • " and do not accept code until it compiles without a single warning" I could not agree more
    – LoneWanderer
    Nov 23 '18 at 22:12










  • I enable compiler warning and compiler give me 5 warning. 'C:....Prova 4stack overflow modifica.c:74:30: warning: unknown conversion type character 0x20 in format [-Wformat=] sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia); ^ C:....Prova 4stack overflow modifica.c:74:30: warning: format '%d' expects argument of type 'int *', but argument 5 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=]'
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c:74:30: warning: too many arguments for format [-Wformat-extra-args] C:....Prova 4stack overflow modifica.c:46:13: warning: unused variable 's' [-Wunused-variable] int i=0,s; ^
    – Allister
    Nov 23 '18 at 22:17










  • C:....Prova 4stack overflow modifica.c: In function 'main': C:....Prova 4stack overflow modifica.c:130:28: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=] scanf ("%d/%d/%d", &data.giorno, &data.mese, &data.anno);
    – Allister
    Nov 23 '18 at 22:18
















Thanks! 1) I'll correct that things. 2) Function not should return array but two things: array and count ((number of file's lines). For this reason i have created struct ritorna_s. But i don't know if is the right way to do it...
– Allister
Nov 23 '18 at 22:05




Thanks! 1) I'll correct that things. 2) Function not should return array but two things: array and count ((number of file's lines). For this reason i have created struct ritorna_s. But i don't know if is the right way to do it...
– Allister
Nov 23 '18 at 22:05












" and do not accept code until it compiles without a single warning" I could not agree more
– LoneWanderer
Nov 23 '18 at 22:12




" and do not accept code until it compiles without a single warning" I could not agree more
– LoneWanderer
Nov 23 '18 at 22:12












I enable compiler warning and compiler give me 5 warning. 'C:....Prova 4stack overflow modifica.c:74:30: warning: unknown conversion type character 0x20 in format [-Wformat=] sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia); ^ C:....Prova 4stack overflow modifica.c:74:30: warning: format '%d' expects argument of type 'int *', but argument 5 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=]'
– Allister
Nov 23 '18 at 22:17




I enable compiler warning and compiler give me 5 warning. 'C:....Prova 4stack overflow modifica.c:74:30: warning: unknown conversion type character 0x20 in format [-Wformat=] sscanf( buf, "%s% d/%d/%d %dn", array[i].regione, &array[i].data.giorno, &array[i].data.mese, &array[i].data.anno, &array[i].mm_pioggia); ^ C:....Prova 4stack overflow modifica.c:74:30: warning: format '%d' expects argument of type 'int *', but argument 5 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=]'
– Allister
Nov 23 '18 at 22:17












C:....Prova 4stack overflow modifica.c:74:30: warning: too many arguments for format [-Wformat-extra-args] C:....Prova 4stack overflow modifica.c:46:13: warning: unused variable 's' [-Wunused-variable] int i=0,s; ^
– Allister
Nov 23 '18 at 22:17




C:....Prova 4stack overflow modifica.c:74:30: warning: too many arguments for format [-Wformat-extra-args] C:....Prova 4stack overflow modifica.c:46:13: warning: unused variable 's' [-Wunused-variable] int i=0,s; ^
– Allister
Nov 23 '18 at 22:17












C:....Prova 4stack overflow modifica.c: In function 'main': C:....Prova 4stack overflow modifica.c:130:28: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=] scanf ("%d/%d/%d", &data.giorno, &data.mese, &data.anno);
– Allister
Nov 23 '18 at 22:18




C:....Prova 4stack overflow modifica.c: In function 'main': C:....Prova 4stack overflow modifica.c:130:28: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'tipo_mese * {aka enum mese_e *}' [-Wformat=] scanf ("%d/%d/%d", &data.giorno, &data.mese, &data.anno);
– Allister
Nov 23 '18 at 22:18


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452504%2fstruct-and-dynamic-array%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Contact image not getting when fetch all contact list from iPhone by CNContact

count number of partitions of a set with n elements into k subsets

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks