I've had this problem with a couple of programs now, and I can not figure out why this keeps happening. This is my code:
#include <stdio.h>
#include <math.h>
int main(void){
double x = 0;
while(x <= 0){
printf("Enter a digit greater than 0.\n");
scanf("%lf", &x);
}
printf("%lf", &x);
}
and the output is:
Enter a digit greater than 0.
4
0.000000
please help
Use the following code
#include <stdio.h>
#include <math.h>
int main(void){
double x = 0;
while(x <= 0){
printf("Enter a digit greater than 0.\n");
scanf("%lf", &x);
}
printf("%lf", x);
}
You are using
printf("%lf", &x);
But the correct syntax to print value of x is:
printf("%lf", x);
Check the working code https://ideone.com/lpdlmX
First off,
printf ("%lf", &x);
will try to print the address of x rather than its value, and this is clearly into undefined behaviour territory(a). A half-decent compiler should warn you about this such as, with gcc:
program.c: In function 'main':
program.c:13: warning: format '%lf' expects argument of type
'double', but argument 2 has type 'double *' [-Wformat=]
printf ("%lf\n", &x);
^
Secondly, the normal printf specifier for double is %f rather than %lf. You can use the latter since the standard states it has no effect on certain data types but it's a bit of a waste doing so.
So what you need is actually:
printf ("%f", x);
The general rule is that you pass addresses to scanf because it needs to populate the objects at those addresses. For printf, you just pass the object itself (yes, even if the data is a pointer that you want printed as a pointer rather than pointing the object being pointed to).
And, finally, to make your code more robust, you would be wise to detect a problem with scanf since, it there's a problem with the input that leaves x set to zero, the program will continuously try to read that input, resulting in an infinite loop.
So a good starting point, taking all those comments into consideration, would be:
#include <stdio.h>
#include <math.h>
int main (void) {
double x = 0;
while (x <= 0) {
printf ("Enter a digit greater than 0.\n");
if (scanf ("%lf", &x) != 1) {
printf ("Invalid input\n");
return 1;
}
}
printf ("%f\n", x);
return 0;
}
(a) Specifically, from ISO C11 7.21.6.1 /9:
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
Always always check the return of scanf, that being said, you printf ("%f", x); -- there is no &x and no need for %lf, printf %f format specifiers prints doubles. (however it is required when using scanf -- man scanf and man printf are your friends)
Putting it altogether, you could safely take input as follows:
#include <stdio.h>
int main (void) {
double x = 0;
while(x <= 0){
printf ("Enter a digit greater than 0.\n");
if (scanf ("%lf", &x) != 1) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
}
printf ("%f", x);
}
note: you must exit the loop on conversion failure (or empty stdin before attempting to take input again -- or your input will fail) Reason: on a failed conversion - no additional characters are read leaving the characters causing the failure just waiting to bite you again on the next go-round...
Related
I am trying to run the following code in C:
#include <stdio.h>
#include <stdint.h>
void main(){
int firstNum = 5;
int16_t secondNum;
printf("Please enter the first number: ");
scanf("%d", &firstNum);
printf("Please enter the second number: ");
scanf("%d", &secondNum);
printf("%d %d\n", firstNum, secondNum);
}
And the output I am getting is as follows:
Please enter the first number: 13
Please enter the second number: 4
0 4
--------------------------------
Process exited after 1.877 seconds with return value 4
Press any key to continue . . .
Why is that so?
My IDE is Dev-C++. Compiler is TDM-GCC 4.9.2 64-bit Release. Program name is TestBit.c (if that is relevant?).
Note: When I change the line int16_t secondNum; to int secondNum;, the program works as intended.
The proper specifier for int16_t secondNum is from <inttypes.h>
// scanf("%d", &secondNum);
scanf("%" SCNd16, &secondNum);
Better code would check the return value.
if (scanf("%" SCNd16, &secondNum) == 1) {
Success();
}
An int16_t is not the same thing as an int; so passing a pointer to one via scanf and pretending it is an int pointer can yield unexpected behaviour; thus your question.
Replace int16_t with int and your program works. For followup read the C Programming Language specification of types and what they mean.
Try changing to: scanf("%hd", &secondNum);
%d is a 4-byte data specifier, int16_t is actually only 2 bytes.
More references: https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=vs-2019
Only my first line of input request user to key in the value. Input B not request user to key in and shows wrong total.
#include <stdio.h>
#include <stdlib.h>
//BASIC CALCULATION INPUT 2 INTEGER ONE BY ONE
int main(int argc, char *argv[])
{
int a,b,c;
//REQUEST ONE INPUT
printf("Integer A: \n");
scanf("%a",&a);
//REQUEST ONE INPUT
printf("Integer B: \n");
scanf("%b",&b);
c=a+b;
//DISPLAY AMOUNT INTEGER
printf("Total: &c",c);
system("PAUSE");
return 0;
}
Your both scanf statements are wrong!
It should be
scanf ("%d",&a);
scanf ("%d",&b);
For taking user input a and b of type integer use %d.
&a is the reference (address) of identifer a which holds the value of a.
And also user output printf statement for integer c should be
printf("%d",c);
Add a space in the scanf to discard all whitespace before matching an integer. Such as a
scanf(" %b",&b);
^^^
space in the scanf
There is no format specifier like %b that's why Input B doesn't request user to key in.I think this this will help you.
#include <stdio.h>
#include <stdlib.h>
//BASIC CALCULATION INPUT 2 INTEGER ONE BY ONE
int main(int argc, char *argv[])
{
int a,b,c;
//REQUEST ONE INPUT
printf("Integer A: \n");
scanf("%d",&a);
//REQUEST ONE INPUT
printf("Integer B: \n");
scanf("%d",&b);
c=a+b;
//DISPLAY AMOUNT INTEGER
printf("Total: &c",c);
system("PAUSE");
return 0;
}
Both of your scanf statements use wrong format specifiers. Thus undefined behaviour.
scanf("%a",&a);
and
scanf("%b",&b);
a expects a float*as its argument, but you are passingint*. There's no format specifierb` in standard C either.
Use %d to scan int's.
Better yet, avoid scanf altogether and use fgets and parse the line instead.
Another problem is your printf statement:
printf("Total: &c",c);
is wrong too. It should be:
printf("Total: %c",c);
to print the value of c.
#include <stdio.h>
int main(void) {
float base, height, hyp;
printf("input base of triangle:\n");
scanf("%f", base);
printf("input height of triangle:\n");
scanf("%f", height);
printf("input hypotenuse of triangle:\n");
scanf("%f", hyp);
float perimeter = base + height + hyp;
printf("the perimeter of your triangle is: %f\n", perimeter);
return 0;
}
I'm running this through ideone.com and it shows success, then standard input is empty, then in stdout it prints all my print statements with no numbers
This is because ideone is not interactive. Unlike running your program from the command line, ideone requires you to provide all the input upfront in the "input" tab:
You need to enter all your data before running your program.
P.S. Once you do, notice how you have undefined behavior because you pass values, rather than pointers, to scanf. The best way to address this on ideone is to pick "C99 strict" option when compiling your C code. This would break your compile with the following warning:
prog.c:7:11: error: format '%f' expects argument of type 'float *', but argument 2 has type 'double' [-Werror=format=]
scanf("%f", base);
scanf requires a pointer to your data type, you should pass the address of your variables using &:
scanf("%f", &base);
scanf("%f", &height);
scanf("%f", &hyp);
To add, some error checking might be useful, something like:
if(scanf("%f", &base) != 1) //number of items scanned is expected to be 1
//process error..
//etc
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 *
I've made extremely easy program:
#include <stdio.h>
int main()
{
double x;
printf("Write your number \n");
scanf ("%f", &x);
printf("You've written %f \n", x);
return 0;
}
And as a result strange number appears (no matter what x I give):
"You've written 83096261053132580000000000000000000000000000000000000000000"
What's wrong with this? This program works fine when I change all numbers into an 'int' type.
See what happens when you compile it with warnings enabled:
amb#nimrod-ubuntu:~/so$ gcc -Wall x.c -o x
x.c: In function ‘main’:
x.c:6:9: warning: format ‘%f’ expects argument of type ‘float *’, but argument 2 has type ‘double *’ [-Wformat]
Change %f to %lf and the scanf and printf functions will correctly take a double.
Wrong specifier for scanf().
With scanf(), "%f" matches a float *, yet coded passed a double *. Use "%lf" instead. Code's printf() is fine. See Correct format specifier for double in printf
double x;
printf("Write your number \n");
// scanf ("%f", &x);
scanf ("%lf", &x);
printf("You've written %f \n", x);
A good compiler should have warned of your incorrect code as suggested by #abligh. Either enable all warnings or consider a new compiler.
When scanning, the &x must match the proper scanf() print specifier.
"%f" matches a float *
"%lf" matches a double *
The using printf() things are easier. If a float or double is passed, being a variadic function, float is promoted to double.
"%f" and "%lf" match a double
%f is used for float type. You should use %lf for double (Long Float).
You need to use %lf for scanf and printf.
In other words, this:
#include <stdio.h>
int main()
{
double x;
printf("Write your number \n");
scanf ("%lf", &x);
printf("You've written %lf \n", x);
return 0;
}