I wrote an easy code and I got a question , here is my code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int first = 0;
int second = 0;
printf("please enter two integers to determine their relation: \n");
scanf("%d %d",&first , &second);
if ( first == second)
{
printf("%d and %d are equal\n", first ,second);
}
else if (first > second)
{
printf("%d is bigger than %d \n" ,first ,second);
}
else if (first < second)
{
printf("%d is smaller than %d \n" ,first ,second);
}
else
{
printf("something is wrong \n");`
}
system("pause");``
return 0;
}
now when I entered a character I thought I will get some error but instead after I put it in it returns 0 equal to 0,
why?
now when I entered a character I thought I will get some error but instead after I put it in it returns 0 equal to 0, why?
You did get an error, but you ignored it. The return value of scanf(), if non-negative, tells you how many input fields were successfully converted and assigned. In the event that the input cannot be matched to the pattern, you have a matching failure. Provided that that occurs at a point in the pattern preceding at least one input field directive, that will result in fewer fields being assigned than there are in the format. You could have detected that via scanf()'s return value if you had bothered to check it.
C was designed for system programming. It does not call for unsolicited runtime messages to to be emitted, and it does not make assumptions about what programs should do in the event of unexpected input or other errors. It gives you the information you need to direct the response of your choice, or, indeed, to direct no explicit response whatever.
In the program presented, your choice is to ignore the error. In the event of a matching failure such as you describe, any variables that were not assigned values by scanf() retain the values they had before the scanf() call, so ignoring the error produces the same behavior as the user entering "0 0".
Related
#include<stdio.h>
int main(void)
{
int h;
int m;
scanf_s("%d : %d", &h,&m);
printf("%d : %d", h,m);
return 0;
}
That is it,
I typed 12 13
It gave me 12 : -858993460
ironic.. would you give me an idea?
If you typed exactly "12 13" as you wrote in the question, then the issue is that your input does not match the format specified in your call to scanf. In particular, scanf is only looking for input in the form of <some integer> : <some integer>. Note that your input does NOT include the : character. As such, scanf only successfully reads a number into your first variable (h), but fails to read into the second variable (m).
You can confirm this is the case by checking the return value of scanf, which returns "the number of input items successfully matched" (see the man page).
The reason you're seeing a "random" number in the output is that your variable m is never initialized. If you instead initialize it to 0, then you will no longer see a "random" value. This is good practice anyway.
For example (with error check):
#include<stdio.h>
int main(void)
{
int h = 0;
int m = 0;
int rc = scanf_s("%d : %d", &h,&m);
if (rc != 2) { // expect to read 2 values
printf("scanf failed, read %d value(s)\n", rc);
} else {
printf("%d : %d", h,m);
}
return 0;
}
Keep the format in scanf_s("%d : %d", &h,&m);
scanf():
The C library function int scanf(const char *format, ...) reads formatted input from stdin.
In your case, type 12 : 13
Your call to the scanf_s function expects a colon in the input, but you didn't type one, so nothing got stored in m in the call. As a result, you got a garbage value for m (as you didn't initialize it either). If you type in 12 : 13, then you should get the expected result.
Also, make sure to check the return value of scanf_s to make sure that you've got all of the values you want.
#include<stdio.h>
int main(){
int n;
printf("%d\n",scanf("%d",&n));
return 0;
}
I wonder why the output of this program is always '1' ?!
What's actually happening here ?
I suspect you wanted to use
int n;
scanf("%d", &n);
printf("%d\n", n);
but what you wrote is equivalent to
int n;
int num = scanf("%d", &n); // num is the number of successful reads.
printf("%d\n", num);
The program is just about exactly equivalent to
#include <stdio.h>
int main() {
int n;
int r = scanf("%d", &n);
printf("%d\n", r);
return 0;
}
So if you run this program, and if you type (say) 45, then scanf will read the 45, and assign it to n, and return 1 to tell you it has done so. The program prints the value 1 returned by scanf (which is not the number read by scanf!).
Try running the program and typing "A", instead. In that case scanf should return, and your program should print, 0.
Finally, if you can, try running the program and giving it no input at all. If you're on Unix, Mac, or Linux, try typing control-D immediately after running your program (that is, without typing anything else), or run it with the input redirected:
myprog < /dev/null
On Windows, you might be able to type control-Z (perhaps followed by the Return key) to generate an end-of-file conditions. In any of these cases, scanf should return, and your program should print, -1.
#jishnu, good question and the output which you're getting is also correct as you are only reading one value from standard input (stdin).
scanf() reads the values supplied from standard input and return number of values successfully read from standard input (keyboard).
In C, printf() returns the number of characters successfully written on the output and scanf() returns number of items successfully read. Visit https://www.geeksforgeeks.org/g-fact-10/ and read more about it.
Have a look at the following 2 code samples.
Try the below code online at http://rextester.com/HNJE76121.
//clang 3.8.0
#include<stdio.h>
int main(){
int n, n2;
printf("%d\n",scanf("%d%d",&n, &n2)); //2
return 0;
}
In your code, scanf() is reading only 1 value from the keyboad (stdin), that is why output is 1.
//clang 3.8.0
#include<stdio.h>
int main(){
int n;
printf("%d\n",scanf("%d",&n)); //1
return 0;
}
In your program scanf returns 1 when successfully some value is taken by scanf into n and that is why you are always getting 1 from your printf("%d\n",scanf("%d",&n));.
You should modify your code like following
#include<stdio.h>
int main(){
int n;
scanf("%d",&n);
printf("%d\n",n);
return 0;
}
In man scanf,
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
In your program, it just match 1 input, so the function scanf will return 1, if you input an legal value that can match a %d, else it will return 0.
In your situation, you might always satisfy this requirements, so it always return 1.
scanf returns the number of successful conversion and assignments. In your case, you're only scanning for one argument, so scanf will either return a 1 on success, a 0 on a matching failure (where the first non-whitespace input character is not a decimal digit), or EOF on end-of-file or error.
When you call printf, each of its arguments is evaluated and the result is passed to the function. In this case, evaluation involves calling the scanf function. The value returned by scanf is then passed to printf.
It's essentially the same as writing
int count = scanf( "%d", &n );
printf( "%d\n", count );
For giggles, see what happens when you enter abc or type CtrlD (or CtrlZ on Windows).
Note that printf also returns a value (the number of bytes written to the stream), so you can write something ridiculous1 like
printf( "num bytes printed = %d\n", printf( "num items read = %d\n", scanf( "%d", &n ) ) );
Joke. Don't do that.
scanf returns number of successful conversions.
Try changing your scanf to as shown below....
you will notice printing 2 after inputting two valid integers.
int n1 =0;
int n2 =0;
int i = scanf("%d %d",&n1,&n2);
In C programming, scanf() takes the inputs from stdin() which is the keyboard and returns the number of successful inputs read
and printf() returns the number of characters written to stdout() which is the display monitor.
In your program scanf() is reading only one input which is getting returned and is printed by printf(). So, whatever may be the input the output is always 1 as it is reading only one input.
Here take a look at this C program:
#include<stdio.h>
int main(){
int n, n2;
printf("%d\n",scanf("%d %d",&n,&n2));
return 0;
}
It takes input or reads two integers from stdin() using scanf(), so the output will always be 2.
**Note: The output is 0 if your input is not integer, as it reads integer only.
The documentation of scanf() says the return value is:
Number of receiving arguments successfully assigned (which may be zero in case a matching failure occurred before the first receiving argument was assigned), or EOF if input failure occurs before the first receiving argument was assigned.
The code you would instead want is:
#include<stdio.h>
int main(){
int n;
scanf("%d",&n);
printf("%d\n",scanf("%d",&n));
return 0;
}
If you use this code as an example,
It shows : warning: implicit declaration of function 'printf' [-Wimplicit-function declaration]
int main()
{
char b[40];
printf(" %d", scanf("%s", b));
getchar();
}
Return value : -1
Outputs of the functions like printf and scanf can be use as a parameter to another function.
scanf() is a function which is integer return type function. It returns total number of conversion characters in it. For ex if a statement is written as :
int c;
c=scanf("%d %d %d");
printf("%d",c);
Then output of this program will be 3.
This is because scanf() is integer return type function and it returns total no of conversion characters, thus being 3 conversion characters it will return 3 to c.
So in your code scanf() returns 1 to printf() and thus output of program is 1.
This is because if more than one statement are used in printf() execution orders starts from right to left.
Thus scanf() is executed first followed by printf().
#include <stdio.h>
int main(void)
{
int i, j, k;
scanf("%d%d%d", &i, &j, &k);
printf("%d %d %d", i, j, k);
return 0;
}
If we input 1,2,3, what will happen? And why?
According to https://stackoverflow.com/a/18297691/2646069 , if scanf() reads an unexpected string, it will return early thus not modifying any value after the last successful value.
I tried clang (LLVM 6.1.0), on -O0, the explanation above is correct, but on -O2, the second variable is always a random number but not the same as before scanf(), and the third variable is always 0.
According to the manual, scanfs return value tells you whether it's safe to use those arguments or not.
Upon successful completion, these functions shall return the number of successfully matched and assigned input items; this number can be zero in the event of an early matching failure. If the input ends before the first matching failure or conversion, EOF shall be returned. If a read error occurs, the error indicator for the stream is set, EOF shall be returned
If you were to input 1,2,3 then scanf would return 1, indicating that the first argument is safe to use and that a match failure occured at the first , because it doesn't match the input expected according to the format string.
If you were to make use of j or k following this, then your code would be making use of an indeterminite value, which is undefined behaviour, obviously a source of erratic behaviour to be avoided... It's very important that you check the return value of scanf, as the link you used also encourages.
The explanation given there is correct. scanf will stop and return when it will find , in input. Therefore j and k will be uninitialized. Uninitialized variables have indeterminate values and this will invoke undefined behavior if it is a trap representation.
I am working on a code, and I tried to enter a char instead of integer, and the result was '2' regardless of the character I entered, is it undefined behaviour or some thing else ?
The code:
#include <stdio.h>
int f1(int n);
int f2(void);
int main(void)
{
int t;
printf("Enter a number: ");
scanf("%d", &t);
/* print proper message */
t ? f1(t) + f2() : printf("zero entered.\n");
return 0;
}
int f1(int n)
{
printf("%d ", n);
return 0;
}
int f2(void)
{
printf("entered.\n");
return 0;
}
when I entered a, the result was "2 entered", and when I entered g the result was "2 entered" and when I entered i,h,k,..... the result was the same. What is that?
If scanf() encounters something it cannot parse based on the specified format string, it simply stops and returns early. So it never writes anything to t (you're just seeing whatever indeterminate value t had before the call).
To handle this, you should always examine the return value of scanf.
It is because scanf failed to parse you input. It expects you to enter a decimal digits since you used %d.
You have to check the return value of scanf to avoid this kind of behavior :
On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.
So :
int items_matched;
// ...
items_matched = scanf("%d", &t); // Get the return value
if ( items_matched != 1 ) // Check it
{
printf("Matching failure with scanf.\n");
return 0;
}
else
{
if ( t == 0 )
printf("zero entered\n");
else
printf("%d entered\n", t);
}
You don't need your f1(t) + f2() who is quite confusing...
The problem is, as you say, that scanf using %d format is expecting you to enter one or more ascii digits. It stops scanning the input at a non-digit character, so it never reads what you type and t has whatever value it had before the scant was called.
You need to check the return code of scanf. Have a look at the manpage:
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.
In other words, scanf does not write anything into t, it's uninitialized the whole time.
So, instead of this:
scanf("%d", &t);
try this:
int items_matched = scanf("%d", &t);
if (items_matched != 1) {
printf("bad number entered\n");
exit(1);
}
From the Linux man page
The format string consists of a sequence of directives which describe
how to process the sequence of input characters. If processing of a
directive fails, no further input is read, and scanf() returns. A
"failure" can be either of the following: input failure, meaning that
input characters were unavailable, or matching failure, meaning that
the input was inappropriate.
In the C11 standard description of scanf (7.21.6.4 The scanf function) section 3:
The scanf function returns the value of the macro EOF if an input
failure occurs before the first conversion (if any) has completed.
Otherwise, the scanf function returns the number of input items
assigned, which can be fewer than provided for, or even zero, in the
event of an early matching failure.
Emphasis is mine . So as #oli charlesworth said you should check the return value of scanf when in doubt :)
I'm only a few days into C programming, so I am not quite sure what's wrong with this code:
#include <stdio.h>
int main(int argc, char * argv[]) {
int sides;
printf("Please enter length of three sides :\n");
scanf("%d", &sides);
return 0;
}
The error message I receive is as follows:
ignoring return value of scanf
What am I doing wrong here, and what can I do to fix it?
You might code
if (scanf("%d", &sides) >0) {
printf("you want %d sides.\n", sides);
}
else printf("You did not enter any number.\n");
The scanf function (please follow the link) has several roles
it is expecting some input and could modify the variables you passed by address to it
it is returning the number of successfully input items
It's a warning that stops your compiler from performing it's task (too strict settings). Check the return value of the scanf() function for errors and the warning should disappear.
Return Value
On success, the function returns the number of items
successfully read. This count can match the expected number of
readings or fewer, even zero, if a matching failure happens. In the
case of an input failure before any data could be successfully read,
EOF is returned.
scanf returns the number of "items", i.e. values passed both in the format string (a single item is e.g. %d, %c and so on), and in the subsequent arguments to scanf, for example, to read two integers separated by comma and space, you would use:
int x, y;
int items = scanf("%d, %d", &x, &y);
assert(items == 2);
I've already spoiled what my suggestion will be above - instead of adding unused variables, if you just want to read it, add an assertion:
#include <assert.h>
/* ... */
assert(scanf("%d", &sides) > 0);
/* ... */
Unfortunately, assert(scanf("%d", &sides)); is not enough, because of EOF (this will return -1). It would be really elegant.
I think this is the way to go, if you don't want to continue your program with an uninitialized variable (sides) in this case.
Alternatively, you can capture scanf's result to a variable, and handle it gracefully like in the other answers.
You don't capture the return value of scanf in a variable. It's a count (as an integer) of how many characters were read, so if that's important to you, then it may be good to capture it.