Program crashes when reading first data point - c

I want to see what student have the best mark in the class.
So I make this ,but i don't know where I am wrong
struct Date {
char name[31];
float mark;
};
struct Date * Read(unsigned int n,struct Date *d){
int i;
for(i=0;i<n;i++){
getchar();
fgets(d[i].name, 31, stdin);
scanf("%f",d[i].mark);
}
return d;
}
int main(){
unsigned int n;
struct Date *d;
scanf("%u",&n);
d = (struct Date*) malloc(n*sizeof(struct Date));
d=Read(n,d);
free(date);
return 0;
}
after i read the mark the program crash.
Can someone help me and explain what to change?
Thanks a lot.

The crash is most likely due to this:
scanf("%f",d[i].mark);
You should pass the address as argument to read a float value. It should be:
scanf("%f", &d[i].mark);
Technically, this is undefined behaviour..
Compile with all warnings enabled. gcc warns even without any specific options:
warning: format %f expects argument of type âfloat *â, but argument 2 has type double [-Wformat=]
scanf("%f",d[i].mark);

Related

C Insert int and doubles inside structure

I have a problem with a small project, I have to create a structure containing a person's data,I have to do data entry via a function using pointers.
I don't understand why when I try to enter the weight the program ends with this error:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
I made an example of the code that is giving me problems:
typedef struct{
char name[DIM];
char surname[DIM];
int height;
float weight;
}Record;
int main() {
Record subj;
insRecord(&subj);
}
void insRecord(Record *subj){
printf("\nName ");
scanf("%64[^\n]s", subj->name);
cleanBuffer();
printf("\nSurname ");
scanf("%64[^\n]s", subj->surname);
cleanBuffer();
printf("\nEight ");
scanf("%3s", subj->height);
cleanBuffer();
printf("\nWeight ");
scanf("%6s", subj->weight);
cleanBuffer();
}
int cleanBuffer(){
int cont= 0;
char c;
do{
cont++;
c = getchar();
}while(c != '\n');
return cont;
}
(I only wrote the main functions).
Furthermore, compiler is giving warnings on height and weight scanf() statements:
Format specifies type 'char *' but the argument has type 'int' (for height)
Format specifies type 'char *' but the argument has type 'double' (for weight)
Could you tell me how can I solve?
PS the project is divided into several files (3 files).
In main.c I wrote the insRecord() function, in struct.h I wrote the Record structure, in struct.c I wrote cleanBuffer() function.
You are reading a string (%s) and try to store that in a float. If you use the flag %f for weight and %d for height it will probably work better. Remember that you should provide a pointer to the float and int that you want to store the data in, you are not doing that in your example.
Have a look at the scanf documentation:
https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm
Good luck

Inputting structure members into printf function and too many arguments error

Hi can anybody tell me the issue of what's going on in the printf function? I keep getting an error of
warning: format ‘%i’ expects argument of type ‘int’, but argument 2
has type ‘char *’ [-Wformat=] time2.hour, time2.min, time2.sec,
time3.hour, time3.min, time3.sec);
and then
warning: too many arguments for format [-Wformat-extra-args]
Anybody give some pointers as to how to fix? Thanks
#include <stdio.h>
struct time
{
int hour;
int min;
int sec;
};
int main (void)
{
struct time time1, time2, time3;
struct time elapsed_time (struct time time1, struct time time2);
printf("Enter your first time (hh:mm:ss) : ");
scanf ("%i:%i:%i", &time1.hour, &time1.min, &time1.sec);
printf("Enter your second time (hh:mm:ss) : ");
scanf ("%i:%i:%i", &time2.hour, &time2.min, &time2.sec);
time3 = elapsed_time(time1,time2);
printf("The time difference between %.2i:%.2i:%.2i & %.2i:%.2i:%.2i",
"is %.2i:%.2i:%.2i.\n", time1.hour, time1.min, time1.sec,
time2.hour, time2.min, time2.sec, time3.hour, time3.min, time3.sec);
return 0;
}
struct time elapsed_time (struct time time1, struct time time2)
{
struct time time3 = { 0, 0, 0 };
time3.hour = time2.hour - time1.hour;
time3.min = time2.min - time1.min;
time3.sec = time2.sec - time1.sec;
return time3;
}
It looks like you have two string literals in your long printf statement, but the printf statement only allows one string at the beginning, and it must be the one that contains all the %.2i format placeholders.
Right now, printf gets the first one, and then tries to use the second string as an input argument to the first.
Join those two strings into 1 string, and it should work.

Why does the compiler complain about this `sprintf` argument?

The following code used to compile fine. I migrated the project to a new version and now the compiler is complaining about one of my sprintf arguments. Here is the warning:
warning: format '%02d' expects type 'int', but argument 12 has type 'double'
FYI, the IDE is MPLAB X 2.35 and the compiler is XC 1.34. I have optimizations turned off and I have tried clean/build. I can only suspect that maybe the struct alignment is out of whack. I am hoping I am just missing the obvious, such as not being able to count.
Offending code:
typedef struct _AnalysisEvent
{
unsigned short id;
unsigned char day;
unsigned char month;
unsigned char year;
unsigned char hour;
unsigned char minute;
unsigned char second;
unsigned int duration;
double min;
double max;
double avg;
} AnalysisEvent;
AnalysisEvent AnalysisEvents[ANALYSIS_MAX_COUNT][ANALYSIS_EVENTS_MAX_COUNT];
unsigned char AnalysisEventGetValueStrAlt(unsigned short id, unsigned char index, char *buffer, int length)
{
if (Analysis[id].count > index)
{
sprintf(buffer, "Analysis ID: %d\r\nEvent ID: %d\r\nMin: %.2f\r\nMax: %.2f\r\nAvg: %.2f\r\nTime: %02d/%02d/%02d %02d:%02d:%02d\r\nDuration: %d\r\n",
id,
index,
AnalysisEvents[id][index].min,
AnalysisEvents[id][index].max,
AnalysisEvents[id][index].avg,
AnalysisEvents[id][index].month,
AnalysisEvents[id][index].day,
AnalysisEvents[id][index].year,
AnalysisEvents[id][index].hour,
AnalysisEvents[id][index].min,
AnalysisEvents[id][index].second,
AnalysisEvents[id][index].duration
);
return index;
}
else
{
return 0;
}
}
Argument 12 is:
AnalysisEvents[id][index].min,
You probably want:
AnalysisEvents[id][index].minute,
In your case, the offending part is
%02d/%02d/%02d %02d:%02d:%02d\r\
^^^
The corresponding argument is AnalysisEvents[id][index].min, type double. You used %d.
FWIW, maybe the answer you want is
"the argument number in the warning message is the total of the ones supplied to sprintf(), counting from buffer itself, not only the ones supplied as the argument to the format."

Scanf not behaving as expected

I am trying to use scanf() to input values to a structure using pointers.Can you help me to understand why my code is not working
This is my code:
#include<stdio.h>
struct student
{
int no;
float marks;
}st[2],*s;
main()
{
printf("enter the values");
for(s=st;s<st+2;s++)
{
scanf("%d%d",&s->no,&s->marks);
}
for(s=st;s<st+2;s++)
{
printff("%d\t%d\t",s->no,s->marks);
}
}
in this code scanf is not working properly,it is taking only the first value
You are using the wrong format specifier. %d is used for ints while %f is used for floats. Use
scanf("%d%f",&s->no,&s->marks);
and
printf("%d\t%f\t",s->no,s->marks);
instead as s->marks is a float, not an int. Using the wrong format specifier leads to Undefined Behavior.
#include<stdio.h>
struct student
{
int no;
float marks;
}st[2],*s;
main()
{
printf("enter the values");
for(s=st;s<st+2;s++)
{
scanf("%d%f",&s->no,&s->marks);
}
for(s=st;s<st+2;s++)
{
printf("%d\t%f\t",s->no,s->marks);
}
}
U have to use %f for float
In the structure you have taken two variable one is int type and other is float type but while doing scanf(taking input) you are doing %d for float whereas it should be %f for float .This is a very minor mistake but you should try to avoid it on your own by just looking at your code carefully :)
Happy coding

Fail to read a value from a struture in C after assigning it

I have strange program behavior while trying to read a value from a structure after assigning a value to it. I'm showing the related structure and function below:
/*Data struct for cor_entry */
struct cor_entry {
struct cor_entry * pre_entry;
struct cor_entry * next_entry;
long long unsigned int entry_data;
};
I've commented out most of my function to highlight the problem:
/* update correlation table */
void cor_table_update(long long unsigned int cor_table_data,
struct cor_entry **cor_table_head_ptr,
struct cor_entry **cor_table_tail_ptr,
int *entry_num,
const int MAX_NUM)
{
struct cor_entry *cor_table_entry;
int cor_hit=0;
//test code
//cor_table_head=cor_table_tail=(struct cor_entry*)calloc(1, sizeof(struct cor_entry));
//printf("original cor_entry_num=%d\n",*entry_num);
////////////////////////code for test///////////////////////////////
cor_table_entry=(struct cor_entry*)calloc(1, sizeof(struct cor_entry));
printf("The cor_table_entry=%x\n",cor_table_entry);
cor_table_entry->entry_data=cor_table_data;
if (cor_table_entry->entry_data==cor_table_data)
{
printf("The assignment is correct!\n");
printf("the cor_enrty_data=%x, stored data=%x,\n",
cor_table_data,
cor_table_entry->entry_data);
}
// ... rest of function
}
And I get this output while running the program:
The cor_table_entry=8c09a58
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09a70
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09a88
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09ae8
Could someone shed some light on this problem? I'm using the GCC-3.4.6 compiler.
Try to compile with -Wall. GCC should then tell you that the sizes of the % format specifiers and the printf() arguments don't match. Try %llx instead of %x. That should fix the issue.
Your problem is probably with the printf, %x is not designed for showing long long unsigned. Split the value before printing it and it shall be what you expect.
You could also use %llx format specifier if your compiler support it.

Resources