Segmentation fault in structure in C - c

Hello I'm trying to make simple program that will check if student assessment is greater than 5.50. When I try to enter the var "number in class" I get SEGFAULThere is my code:
#include <stdio.h>
typedef struct student{
char name[100];
int number_in_class;
double assessment;
}student;
int main(void){
student corrective[25];
int i;
for(i = 0; i < 25; i++){
printf("Ime na uchenika:\n");
scanf("%s", corrective[i].name);
printf("Nomer v klas:\n");
scanf("%i", corrective[i].number_in_class);
printf("ocenka:\n");
scanf("%f", corrective[i].assessment);
}
for(i = 0; i < 25; i++){
if(corrective[i].assessment >= 5.50){
printf("Ime: %s\nNomer v klas: %i\nOcenka: %i\n",corrective[i].name, corrective[i].number_in_class ,corrective[i].assessment);
}
}
return 0;
}
Any idea why?

You need to pass the address of the objects to scanf(), not their values
for(i = 0; i < 25; i++){
printf("Ime na uchenika:\n");
scanf("%s", corrective[i].name); // array converted to pointer to 1st element (an address)
printf("Nomer v klas:\n");
scanf("%i", &corrective[i].number_in_class); // use & to pass the address
printf("ocenka:\n");
scanf("%lf", &popravitelni[i].assessment); // same as before
}
As other posters have noted, you need "%lf" for addresses of objects of type double.

Use %lf to read a double object and not %i or%f. For printf, use %f to print a double. Also you need to pass pointers for scanf arguments. Enable all your compiler warnings and fix them.

The parameters to scanf() are incorrect. You have to pass them as pointers.
scanf("%s", corrective[i].name); is correct, because corrective[i].name is an array therefore a pointer by definition, but you cannot do the same with the other primitive data types. Head then with & to get its pointer.
...
scanf("%i", &corrective[i].number_in_class);
...
scanf("%f", &corrective[i].assessment);
In addition you should check the types you are reading as mentioned in ouah's answer.

You are using %i in this statement:
scanf("%i", corrective[i].number_in_class);
while the number_in_class is a double. Use %lf, thats used for double. Also correct %f to %lf in this statement too:
scanf("%f", popravitelni[i].assessment);
Also use &-the address-of operator to pass the address instead of value in the scanf() function.
Corrected Code:
scanf("%lf", &corrective[i].number_in_class);
.
.
scanf("%lf", &popravitelni[i].assessment);

Related

New to C; using arrays. Undesirable output

I'm new to C (programming in general). I was working on this for a while, my school assignment. I'm getting an output of many random numbers (e.g. 1xxxxxxxxx) instead of printed displays of input entered.
Here's the code in question:
#include<stdio.h>
int main()
{
char item[5][20];
double ppu[5], total, price[5], quantity[5];
int i;
for(i = 0; i < 5; i++)
{
printf("Enter item, price and quantity: ");
scanf("%s %f %f", &item[i], &ppu[i], &quantity[i]);
price[i] = ppu[i]*quantity[i];
total += price[i];
}
printf("ITEM\t\tPRICE PER UNIT\t\tQUANTITY\t\tPRICE\n");
for(i=0; i < 5; i++)
{
printf("%s\t\t%.2f\t\t%.0f\t\t%.2f\n", item[i], ppu[i], quantity[i], price[i]);
}
}
Change the format specifier to %lf. Don't forget to assign total with an initial value.
total hasn't been assigned (or initialized with) a relevant value.
Also, item[i] (a pointer to 20 chars) is converted to a pointer to char (what scanf expects) in the context of scanf. The & is wrong
scanf("%s %f %f", &item[i], &ppu[i], &quantity[i]);
// wrong ^^ ^^ ^
scanf("%s %lf %lf", item[i], &ppu[i], &quantity[i]); // thanks to Bpaul
Even better is making sure scanf did the right thing:
if (scanf("%s%lf%lf", item[i], &ppu[i], &quantity[i]) != 3) /* error */;
None of these variables and array members are initialized.
char item[5][20];
double ppu[5], total, price[5], quantity[5];
int i;
That means that they will contain random garbage values.
Now, the ones that you assign to with either scanf or the assignment operator will contain (possibly) useful data, but you are also missing out checking the return value of scanf, which will tell you how many values could be successfully read.
Also look at the way you use the 2-D array item. There is something wrong there.

Why the below code is giving different output when variable type is different?

//o/p when i/p is 16 and 2 is 4 and if variable is int then o/p will be 20;
#define SETBIT(A,B) A|1<<B
int main(){
char n,pos;
printf("Enter a value");
scanf("%d",&n);
printf("Enter position");
scanf("%d",&pos);
printf("Value after setting %d",SETBIT(n,pos));
}
For the *scanf functions, the d conversion specifier expects its corresponding parameter to have type int *; if that's not the case, then the behavior is undefined, and pretty much any result is possible.
If you want to use char for pos and n, then you must use %hhd instead of %d in the scanf call.

Float seen as a double

When running this little C script using Xcode, I get this message:
Format specifies type 'float *' but the argument has type 'double" at scanf("%f", v) and scanf("%f", i).
I don't get it, since I have not declared any double type variables.
int main(int argc, const char * argv[]) {
char choice[10];
float v;
float i;
float r;
printf("What would you like to calculate?: ");
scanf("%s", choice);
printf("\nYou chose: \n""%s", choice);
if (strcmp(choice, "r") == 0)
{
printf("\nPlease enter voltage (V): \n");
scanf("%f", v);
printf("\nPlease enter current (I): \n");
scanf("%f", i);
r = v/i;
printf("%f", r);
}
}
Any ideas?
You're getting that warning because you failed to pass a pointer to a float (float*) to the function scanf. The compiler tells you that it's a double because scanf is a variadic function. Variadic parameters are subject to default argument promotion, where arguments of certain data types are converted to larger data types. In this case, float is promoted to double.
The only way for a function in C to modify variables v, i, and choice is to pass them as pointers, so you need to pass pointers to scanf, using the & "address of" operator.
Your code should look like this:
int main(int argc, const char * argv[]) {
char choice[10];
float v;
float i;
float r;
printf("What would you like to calculate?: ");
scanf("%9s", &choice); /* this specifier prevents overruns */
printf("\nYou chose: \n""%s", choice);
if (strcmp(choice, "r") == 0)
{
printf("\nPlease enter voltage (V): \n");
scanf("%f", &v); /* use a pointer to the original memory */
printf("\nPlease enter current (I): \n");
scanf("%f", &i); /* use a pointer to the original memory */
r = v/i;
printf("%f", r);
}
}
Note also that I used the format specifier %9s. That way, if the user inputs more than 9 characters, adjacent memory won't be overwritten. You have to reserve the last element of the array for the null character \0 because strings in C end with \0.
I don't get it since I have not declared any double type variables.
When there is no visible prototype to indicate what type a function expects for a given argument, or when that argument is among a set of variadic arguments, then default argument promotion is performed on that argument. This provides for compatibility with pre-ANSI C code that assumed such promotions were performed on all arguments.
In this case, scanf() is variadic, with this prototype:
int scanf(const char *fmt, ...);
so everything but the format is subject to default argument promotion. For arguments of type float, that is a promotion to double, and that's where your double comes from.
Of course, as other answers describe, you shouldn't be passing the float at all, but rather a pointer to it.
You have to use the & operator. For example replace scanf("%f", v); with scanf("%f", &v);. This will pass the address of the variable (instead of the value) to scanf().
You have to write scanf("%f", &i); e.t.c, as you want the variable to be passed as a pointer as C has no reference type like C++

Format specifies type "int*" but argument has type "int"

Creating a code that prints out Body Mass Index
printf("What is your height in inches?\n");
scanf("%d", height);
printf("What is your weight in pounds?\n");
scanf("%d", weight);
I have height and weight as initialized as int height, int weight, but the program is not letting me run it because it says the format is type int* on both scanf lines. What am I doing wrong to get this program to run?
scanf requires the format (your "%d") and also a memory address of the variable where it should put the value that was read. height and weight are int, not the memory address of an int (this is what int * type 'says': a pointer to a memory address of an int). You should use the operator & to pass the memory address to scanf.
Your code should be:
printf("What is your height in inches?\n");
scanf("%d", &height);
printf("What is your weight in pounds?\n");
scanf("%d", &weight);
Update: As The Paramagnetic Croissant pointed out, reference is not the correct term.So I changed it to memory address.
taking into account what the other users have said, try something like this;
int height; <---- declaring your variables
int weight;
float bmi; <---- bmi is a float because it has decimal values
printf("What is your height in inches?\n");
scanf("%d", &height); <----- don't forget to have '&' before variable you are storing the value in
printf("What is your weight in pounds?\n");
scanf("%d", &weight);
bmi = (weight / pow(height, 2)) * 703; <---- the math for calculating BMI
printf("The BMI is %f\n", bmi);
(for this you will need to include the math.h library.)
scanf reads characters from the standard input, interprets them according to the format specifiers here "%d" for integers and stores them in corresponding arguments.
To store them you must specify &variable_name, it will specify the address location where the input should be stored.
Your scanf statement should be:
//For storing value of height
scanf(" %d", &height);
//For storing value of weight
scanf(" %d", &weight);
Like others have said, it's because when you have a value that is a primitive (like an int) that is being read with scanf you have to pass the memory address to that primitive value. However, just to add something that has not been mentioned yet, the same is not true for strings.
Example 1. Using with a primitive value
#include <stdio.h>
int main()
{
int primitiveInteger; // integer (i.e. no decimals allowed)
scanf("%i", &primitiveInteger); // notice the address of operator getting the address of the primitiveInteger variable by prepending the variable name with the & (address of) operator.
printf("Your integer is %i", primitiveInteger); simply printing it out here to the stdout stream (most likely your terminal.)
}
Example 2. Not using a primitive value
#include <stdio.h>
int main()
{
char *nonPrimitiveString; // initialize a string variable which is NOT a primitive in C
scanf("%s", nonPrimitiveString); // notice there is no address of operator here
printf("%s\n", nonPrimitiveString); // prints string
}

Why is my C program printing 0.000000 here?

I just started to learn C programming.
In my book there is this piece of code:
/*Code Start*/
/*This code is use to find the simple interest*/
main ()
{
int p, n;
float r, si;
p = 1000;
n = 3;
r = 8.5;
si= p*n*r/100;
printf("%f", si);
}
/*Code end*/
The output i got was " 255.000000 "
I though i'll modify it with scanf function so i wrote this:
/*Code Start*/
main ()
{
int p, n;
float r, si;
printf("Enter value for p: \n");
scanf("%d", &p);
printf("Enter value for n: \n\n");
scanf("%d", &n);
printf("Enter valuse for r: \n\n");
scanf("%d", &r);
si= p*n*r/100;
printf("\nYour Simple Interest is %f\n\n", si);
}
/*Code End*/
No matter what values i give to p,n,r the answer i get is always 0.000000..
I also tried giving the values, p=1000, n=3, r=8.5 but still i get 0.000000..
Change the specifier in scanf. You're using %d instead of %f:
scanf("%f", &r);
^
First side note: the code looks kind of bad (no return type for main ?!). Are you sure it's a good book ?
Second side note: using floats today is kind of pointless. Maybe you
should use doubles ?
Firstly, your main problem: The %d specifier is only for integers, not floats or doubles. Use %f for floats.
In addition, the main should return an int, this will do:
int main() {
/* your code */
return 0;
}
Finally, I would recommend you make better use of white-space as it will vastly help with readability once you start making larger programs.
Use %f conversion specification to read a float:
scanf("%f", &r);
%d means it reads a decimal integer and not a float.
r is a float, but you're reading it in using %d as a scanf specifier, which expects an int.
The real culprit in your code is the line scanf("**%d**", &r).
%d is the format specifier for integer value, as you declared r as float then use %f instead of %d.
i.e. scanf("%f", &r)
Change Either
int p, n;
float r, si;
to
int p, n,r;
float si;
or change formate specifier in scanf("%d", &r); %d to %f.
when you declare r as an integer r=8 will be considered, in that case scanf("%d", &r); will be accepted. and your program get compiled and executed.
both declaration and formate specifier should be same.
my suggestion is to use %.2f when dealing with money. which will give like 10.00 which is the correct formate.

Resources