Struct and dynamic array
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
|
show 6 more comments
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
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
|
show 6 more comments
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
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
c arrays struct
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
|
show 6 more comments
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
|
show 6 more comments
1 Answer
1
active
oldest
votes
You have two primary problems I see in crea_array
,
- You declare
char* r;
but then attempt to assign the return ofsscanf (buf, "%s %d/%d/%d %dn", ...
(e.g.r = sscanf (...
. This is incorrect.sscanf
returns typeint
representing the number of successful conversions that took place as specified in your format string (e.g."%s %d/%d/%d %dn"
would return5
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.
crea_array
must be declared as typetipo_dati_file *
and it mustreturn array;
at the end. You must assign the return to a pointer back in the caller. You must alsofree (buf);
before thereturn
or you have just created a memory leak as there is no way tofree()
the memory you allocated forbuf
after the function returns. (further, if you are simply allocating1000-char
each time, just use a fixed buffer, e.g.char buf[1000];
and eliminate the need to allocatebuf
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.
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
|
show 3 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
You have two primary problems I see in crea_array
,
- You declare
char* r;
but then attempt to assign the return ofsscanf (buf, "%s %d/%d/%d %dn", ...
(e.g.r = sscanf (...
. This is incorrect.sscanf
returns typeint
representing the number of successful conversions that took place as specified in your format string (e.g."%s %d/%d/%d %dn"
would return5
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.
crea_array
must be declared as typetipo_dati_file *
and it mustreturn array;
at the end. You must assign the return to a pointer back in the caller. You must alsofree (buf);
before thereturn
or you have just created a memory leak as there is no way tofree()
the memory you allocated forbuf
after the function returns. (further, if you are simply allocating1000-char
each time, just use a fixed buffer, e.g.char buf[1000];
and eliminate the need to allocatebuf
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.
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
|
show 3 more comments
You have two primary problems I see in crea_array
,
- You declare
char* r;
but then attempt to assign the return ofsscanf (buf, "%s %d/%d/%d %dn", ...
(e.g.r = sscanf (...
. This is incorrect.sscanf
returns typeint
representing the number of successful conversions that took place as specified in your format string (e.g."%s %d/%d/%d %dn"
would return5
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.
crea_array
must be declared as typetipo_dati_file *
and it mustreturn array;
at the end. You must assign the return to a pointer back in the caller. You must alsofree (buf);
before thereturn
or you have just created a memory leak as there is no way tofree()
the memory you allocated forbuf
after the function returns. (further, if you are simply allocating1000-char
each time, just use a fixed buffer, e.g.char buf[1000];
and eliminate the need to allocatebuf
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.
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
|
show 3 more comments
You have two primary problems I see in crea_array
,
- You declare
char* r;
but then attempt to assign the return ofsscanf (buf, "%s %d/%d/%d %dn", ...
(e.g.r = sscanf (...
. This is incorrect.sscanf
returns typeint
representing the number of successful conversions that took place as specified in your format string (e.g."%s %d/%d/%d %dn"
would return5
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.
crea_array
must be declared as typetipo_dati_file *
and it mustreturn array;
at the end. You must assign the return to a pointer back in the caller. You must alsofree (buf);
before thereturn
or you have just created a memory leak as there is no way tofree()
the memory you allocated forbuf
after the function returns. (further, if you are simply allocating1000-char
each time, just use a fixed buffer, e.g.char buf[1000];
and eliminate the need to allocatebuf
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.
You have two primary problems I see in crea_array
,
- You declare
char* r;
but then attempt to assign the return ofsscanf (buf, "%s %d/%d/%d %dn", ...
(e.g.r = sscanf (...
. This is incorrect.sscanf
returns typeint
representing the number of successful conversions that took place as specified in your format string (e.g."%s %d/%d/%d %dn"
would return5
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.
crea_array
must be declared as typetipo_dati_file *
and it mustreturn array;
at the end. You must assign the return to a pointer back in the caller. You must alsofree (buf);
before thereturn
or you have just created a memory leak as there is no way tofree()
the memory you allocated forbuf
after the function returns. (further, if you are simply allocating1000-char
each time, just use a fixed buffer, e.g.char buf[1000];
and eliminate the need to allocatebuf
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.
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
|
show 3 more comments
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
|
show 3 more comments
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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