Why am i losing the value of variable n2? - c

I am doing school work and I came across a problem. Why do I loose the value of the variable n2?
#include <stdio.h>
#include <stdlib.h>
int opt;
double n1;
double n2;
int main()
{
printf("Hello and welcome \n");
printf("Lets do Some math! \n");
printf("Menu!\n");
printf("1- \t Areas \n");
printf("2- \t Perimetros \n");
scanf("%d",&opt);
switch (opt){
case 1:
Areas();
break;
case 2:
break;
}
return 0;
}
void Areas(){
printf("Area de:\n");
printf("1- \t Quadrado\n");
printf("2- \t Retangulo\n");
printf("3- \t Losangulo\n");
printf("1- \t Circulo\n");
scanf("%d", &opt);
switch (opt){
case 1:
Medidas("dos lados.");
printf("%d %d\n", n1,n2 );
break;
case 2:
break;
}
}
void Medidas(char string[]){
printf("Introduzir as Medidas %s \n", string);
scanf("%d", &n1);
printf("Next\n");
scanf("%d", &n2);
}
I tried many things and nothing works. The
printf("%d %d\n", n1,n2 );
is just for debugging purposes.

The problem is in
scanf("%d", &n1);
scanf("%d", &n2);
n1 and n2 are of type double, so using %d format specifier invokes undefined behavior.
Quoting C11, chapter §7.21.6.2, for fscanf(), (emphasis mine)
d Matches an optionally signed decimal integer, whose format is the same as
expected for the subject sequence of the strtol function with the value 10
for the base argument. The corresponding argument shall be a pointer to
signed integer.
and
[...] Unless assignment suppression was indicated by a *, the
result of the conversion is placed in the object pointed to by the first argument following
the format argument that has not already received a conversion result. If this object
does not have an appropriate type, or if the result of the conversion cannot be represented
in the object, the behavior is undefined.
solution: For printing doubles, you need to use %f and for scanning the values, you need to use %lf.

The variables n1 and n2 are of type double. However, you're using the %d format specifier in printf and scanf, which expect an int and a pointer to int.
For reading / writing a double, use the %f format specifier for printf and %lf for scanf.

You are using double data type for n1 and n2.
The printing format specifier for double is %f; the scanning format is %lf.
Instead of %d, use %f every time for n1 and n2.

Related

Scanf_s reading wrong input

For this code below (in C)
int small_a, small_b;
printf("Please input two numbers\n");
scanf_s("%d %d", &small_a, &small_b);
printf("%d %d", &small_a, &small_b);
int test_2nd = small_a - small_b;
if (test_2nd < 0) {
printf("a is smaller %d", &small_a);
}
else {
printf("b is smaller %d", &small_b);
The values it prints when I write 4 and 2 is a huge six digit number (5504620 and 5504608 in this case) I don't understand where it goes wrong. stdio.h has been included as a header.
The problem here is in the print statement. In the code
printf("%d %d", &small_a, &small_b);
you don't need (want) to take (print) the address. Remove that &.
That said, this actually invokes undefined behavior. %d with printf() expects an argument of type int and you're essentially supplying an int *, causing the UB.
FWIW, to print an address (pointer), you need to use %p format specifier and cast the argument to void *

Addition not working in c

I was trying c code to add but my program doesn't execute, codeblocks unfortunately closes. What is the error?
void main()
{
float a,b;
printf("%30sAddition Of Numbers\n");
printf("\nEnter Number 1: ");
scanf("%f",&a);
printf("\nEnter Number 2: ");
scanf("%f",&b);
printf("\nThe addition of %0.3f and %0.3f is %0.3f",a,b,(a+b));
}
I want to put the result of addition directly in printf statement with float inputs but I am not getting it working.
I also tried putting the result in variable a but it didn't work either.
void main()
{
float a,b;
printf("%30sAddition Of Numbers\n");
printf("\nEnter Number 1: ");
scanf("%f",&a);
printf("\nEnter Number 2: ");
scanf("%f",&b);
a=a+b;
printf("\nThe addition of %0.3f and %0.3f is %0.3f",a,b,a);
}
where am I going wrong?
The problem is in the following statement
printf("%30sAddition Of Numbers\n");
here, the format string supplied to the printf() conatins %30s (or, %s, in general) which is a format specifier (conversion specifier), and you did not supply any argument to it. It invokes undefined behavior.
To quote C11 standard, chapter §7.21.6.1
[...] If there are insufficient arguments for the format, the behavior is
undefined. [...]
You can also check the man page to find out more about the format specifiers.
EDIT:
As discussed in the below comments, if you want some spaces to appear before the output, change
printf("\t\tAddition Of Numbers\n");
That said,
void main() should be int main (void), at least, to conform to the standards.
You should always check the return value of scanf() to ensure the successful scanning.
The "%30sAddition Of Numbers\n" issue in your post has been addressed by two good answers (at the time of this post). But you asked a question in comments that may not have been answered completely:
works with %30s when i use all integer numbers and not float! how do i make it work with floats.
A generic answer to that question:
The format specifier you use in scanf(): "%f",&a could result in undesirable results if scanning in unexpected newlines, spaces or other white space. This can be addressed by modifying the format specifier string to suppress these characters. Here is a suggestion:
char* fmt = "%[^\n]%*c";//This generic format specifier, can be used for both integer
//and floating point inputs when used in conjuction
//with strtod() or strtol() (see below)
scanf(fmt, input);
Explanation of "%[^\n]%*c".
When a user is asked to enter a generic number, it might be a float or an integer. You can accommodate that by creating methods for both, and being specific about what kind of value you would like to process:
float get_float(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter floating point number and hit return:\n");
scanf(fmt, input);
return strtod(input, dummy);
}
long get_int(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter integer number and hit return:\n");
scanf(fmt, input);
return strtol(input, dummy, 10);
}
Called like this:
int main(void)
{
long integer_var = get_int();
float float_var = get_float();
float sum = (float)integer_var + float_var;
return 0;
}
Try adding getch(); function at the bottom before closing curly brackets,
like this
void main()
{
float a,b;
printf("%30sAddition Of Numbers\n");
printf("\nEnter Number 1: ");
scanf("%f",&a);
printf("\nEnter Number 2: ");
scanf("%f",&b);
a=a+b;
printf("\nThe addition of %0.3f and %0.3f is %0.3f",a,b,a);
getch();//it will hold your output screen so you can see the output
}
In this line
printf("%30sAddition Of Numbers\n");
you did not supply a string argument for the %s format. This causes undefined behaviour.
If you want the output spaced, you could try a small modification
printf("%30s\n", "Addition Of Numbers");
in this case you are supplying a string literal to satisfy the %s format.
Additionally you must always check the return value from scanf to see that it did convert the number of arguments it was supposed to. It's a basic newbie error not to, and the root cause of hundreds of SO questions.

"static char" vs. "char" in C

To practice variable declaration, placeholders and I/O calls, I did a sample assignment in the book that I am using to study. However, I keep running into a particular problem, in that when I try to declare more than one character variable for the purpose of input, even if the compiler doesn't catch any syntax error, the program when executing will only return one character variable. This is the code in question:
#include <stdio.h>
int main()
{
double penny=0.01;
double nickel=0.05;
double dime=0.1;
double quarter=0.25;
double value_of_pennies;
double value_of_nickels;
double value_of_dimes;
double value_of_quarters;
double TOTAL;
int P;
int N;
int D;
int Q;
char a,b;
//used "static char" instead of "char", as only using the "char" type caused a formatting error where only the latter character entered in its input would appear
printf("Please enter initials> \n");
printf("First initial> \n");
scanf("%s", &a);
printf("Second initial> \n");
scanf("%s", &b);
//"%s" was used as the input placeholder for type "char"
printf("%c.%c., please enter the quantities of each type of the following coins.\n", a, b);
printf("Number of quarters> \n");
scanf("%d", &Q);
printf("Number of dimes> \n");
scanf("%d", &D);
printf("Number of nickels> \n");
scanf("%d", &N);
printf("Number of pennies> \n");
scanf("%d", &P);
printf("Okay, so you have: %d quarters, %d dimes, %d nickels, and %d pennies.\n", Q, D, N, P);
value_of_pennies=penny*P;
value_of_nickels=nickel*N;
value_of_dimes=dime*D;
value_of_quarters=quarter*Q;
TOTAL=value_of_quarters+value_of_dimes+value_of_nickels+value_of_pennies;
printf("The total value of the inserted coins is $%.2lf. Thank you.\n", TOTAL);
//total field width omitted as to not print out any leading spaces
return(0);
}
And this is the transcribed output ("a", "e", and the four "1"s are sample arbitrary input values:
Please enter initials>
First initial>
a
Second initial>
e
.e., please enter the quantities of each type of the following coins.
Number of quarters>
1
Number of dimes>
1
Number of nickels>
1
Number of pennies>
1
Okay, so you have: 1 quarters, 1 dimes, 1 nickels, and 1 pennies.
The total value of the inserted coins is $0.41. Thank you.
I entered the characters "a" and "e" as input values for the char variables "a" and "b", but only "e" had shown up. On the other hand, should I have put a "static" in the "char" variable declaration, both inputted char values will be displayed in the relevant print call.
For future reference, I would like to ask about why such a thing would occur the way that it did, and the value of the "static" word in the declaration.
(As an aside, I am aware that I could have simply made the "value_of_(insert coin here)" variables as constant macros.)
With a definition like
char a,b;
writing a statement like
scanf("%s", &a);
scanf("%s", &b);
invokes undefined behaviour. %s is not a format specifier for a char. Using wrong format specifier can and will lead to UB. You should use %c to scan a char.
To elaboreate,
%s format specifier expects a corresponding argument which is a pointer to char array. It scans multiple characters until it encounters a space (whitespace character, to be pedantic) or newline or EOF.
%c format specifier expects a corresponding argument which is a pointer to char variable. It reads only one char from the input buffer.
So, with %s, if you supply the adress of a char variable, it will try to access beyond the allocated memory region for writing the scanned data, which will invoke UB.
You may want to read some more on printf(), scanf() and format specifiers before moving forward.
You have used the wrong format specifier for char. char uses %c not %s. As far as static goes, I'm a bit confused about your question. You say in a comment that you are using static char, but I do not see any variables declared as static char.

decimal of numbers in c

I just asked a question but couldn't get what I want, and couldn't edited and reply as it is too long. My question is the same and it is the link to that question.how to keep decimals in c
#include<stdio.h>
int main()
{
float b,c,;
int a,kk;
printf("Welcome to the unit conversion program\n");
printf("This program can convert the measurements of;\n");
printf("1-Length\n");
printf("2-Mass\n");
printf("Please select the number that corresponds to the measurement you want to convert in:\n");
scanf("%d",&a);
if (a==1){
printf("Your number will be converted from inches to centimeters.\n");
printf("Please enter the length.\n");
scanf("%f",&b);
c=b*2.54;
printf("%f inch is %f cm.",b,c);
scanf("%d",kk); \. to avoid to shut the cmd windows .\
}
else if (a==2){
printf("Your number will be converted from pounds (lbs) to kilograms");
printf("Please enter the mass.\n");
scanf("%d",&b);
c=b*0.45359237;
printf("%d lbs is %d kgs.",b,c);
}
return 0;
}
The error is that %d in the format specifier of both scanf and printf represents decimal, so it expects an int (in the case of scanf, a pointer to int)
Since you are declaring b and c as float, %d in the lines
scanf("%d",&b);
printf("%d lbs is %d kgs.",b,c);
should be changed to %f respectively.
A little piece of advice: use double in stead of float. It provides more precision, its performance is better in many machines. The downside is that it occupies more space than float, but that's not a problem in most cases.
You should use %f in printf and %lf in scanf in case you are using double.
Change:
scanf("%d",&b);
printf("%d lbs is %d kgs.",b,c);
to:
scanf("%f",&b);
printf("%f lbs is %f kgs.",b,c);
You declared b as float and taking input as a decimal & later printing both float b,c as decimal? Please study a book Deital & Deital for C/C++ is an amazing book.

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