Code:
#include <stdio.h>
main()
{
   int n;
   
      puts("Input an Integer");
      while(scanf("%d",&n)==0)
         fflush(stdin);
      printf("Integer Value: %d\n",n);
}


1. What does the ==0 do after the scanf function?

This program is supposed to ask for user input and return the input if it is an integer. Otherwise, it keeps asking for input.

Does scanf return NULL if input is invalid? Is that why the cmd crashes when you use scanf and insert an invalid input and then try to use printf with it as a parameter?


2.Also, why do you write scanf's parameters like ("%d",&n) and not just ("%d",n) ?

3. If I write the code like this:


Code:
#include <stdio.h>
main()
{
   int n;
   
      puts("Input an Integer: ");
      scanf("%d",&n)==0;
         fflush(stdin);
      printf("Integer Value: %d\n",n);
}


and give it an invalid input, what are those numbers it returns?
My guess is those are random numbers from when the variable is declared, am I right? I initialized n with the value 2 and the result on the printf was always 2, so I guess i'm right.

4. Which brings us to the last question... if in the last code n stays with the value it was initialized in the declaration because scanf was used only in a condition, then why does n receive the value of the input in the first code, when it is used in the same way, only inside of a loop?

EDIT: I think I figured it out, it's because of fflush, isn't it?

I wrote it like this:

Code:
{
   int n;
   
      puts("Input an Integer: ");
    while(  scanf("%d",&n)==0)
    ;

      printf("Integer Value: %d\n",n);
}


And the keyboard freezes (only inside the program) after I insert an invalid input. Why?

5.Is there a way to look at the code of the built-in functions? The ones that come with the compiler?

I know it's a lot of questions, sry guys
1)
As per http://www.cplusplus.com/reference/cstdio/scanf/,
Quote:
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.

If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof or ferror). And, if either happens before any data could be successfully read, EOF is returned.

If an encoding error happens interpreting wide characters, the function sets errno to EILSEQ.


In your code, you loop and flush stdin (in a non-portable way) so long that you don't successfully read in an integer. Officially, fflush does not work on input streams. Linux here, fflush(stdin); does nothing (3.16.3-200). Using
Quote:
while(getchar() != '\n');
is a much better idea (should also check for EOF, but meh).

2)
In order for scanf to store values back, it needs to know where to store them. It requires a pointer to the variable's location (the &n in this case). Otherwise, you simply pass the value of n.

3)
Yes, because n was not defined, you print an undefined value (whatever happens to be in memory where the variable is located).

4)
See #1, again, you are using fflush in an undefined behavior (ignoring platform exceptions, they aren't reliable). The exception to fflush that linux added states that
Quote:
For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.
.

5)
If you are on Linux, of course! Although I would stay away from them as a learning source, they are very complex. glibc is at https://www.gnu.org/software/libc/, gcc source has some functionality, Linux kernel has very low-level source. Again, these are very complex.
AHelper wrote:
1)
As per http://www.cplusplus.com/reference/cstdio/scanf/,
Quote:
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.

If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof or ferror). And, if either happens before any data could be successfully read, EOF is returned.

If an encoding error happens interpreting wide characters, the function sets errno to EILSEQ.


In your code, you loop and flush stdin (in a non-portable way) so long that you don't successfully read in an integer. Officially, fflush does not work on input streams. Linux here, fflush(stdin); does nothing (3.16.3-200). Using
Quote:
while(getchar() != '\n');
is a much better idea (should also check for EOF, but meh).

2)
In order for scanf to store values back, it needs to know where to store them. It requires a pointer to the variable's location (the &n in this case). Otherwise, you simply pass the value of n.

3)
Yes, because n was not defined, you print an undefined value (whatever happens to be in memory where the variable is located).

4)
See #1, again, you are using fflush in an undefined behavior (ignoring platform exceptions, they aren't reliable). The exception to fflush that linux added states that
Quote:
For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.
.

5)
If you are on Linux, of course! Although I would stay away from them as a learning source, they are very complex. glibc is at https://www.gnu.org/software/libc/, gcc source has some functionality, Linux kernel has very low-level source. Again, these are very complex.


1. So, when the input is invalid, it returns 0, alright, I get it.

2. ...because if it stored the input in n and did not use a pointer, it would be the same of doing nothing, because functions are executed in a separated environment and in order for the variable values at the end of the function's execution don't get lost, you have to use a pointer, am I right?

Aand I also assume scanf is void type, because if you were to "scan" more than one variable and of different types, then which type to use? So, instead, scanf just changes the value of the variable, and so those values don't get lost, because functions are executed on a separated environment, it has to use pointers, therefore you need &n.

So what scanf does, basically, would be something like this:

Code:
void scanf( "%d", &n)
{
       int *ptr = &n;
}



Am I right?
How does the function know which type the pointer should be, or how many pointers it should use?

3. Sooo, that means that when invalid input occurs and the value 0 is returned, the variables the user inserted during scanf became part of the buffer, because those variables weren't used, right?

So, using fflush here:


Code:
#include <stdio.h>
main()
{
   int n;
   
      puts("Input an Integer");
      while(scanf("%d",&n)==0)
         fflush(stdin);
      printf("Integer Value: %d\n",n);
}


is just so the keyboard doesn't freeze, because of the buffer I assume.

But why doesn't it execute scanf again? I mean, if it is indeed because of the buffer, what does it do, exactly?


Thank you for answering my questions Very Happy

Also, I use Windows
Scanf() returns the number of arguments that was specified. If you ask for 3 arguments, it will return 3. You have it as one argument, so it will return 1. Scanf() returns -1 if there was an error. Hope this is correct in my thinking...
Quote:
Scanf() returns the number of arguments that was specified. If you ask for 3 arguments, it will return 3. You have it as one argument, so it will return 1. Scanf() returns -1 if there was an error. Hope this is correct in my thinking...


It will return the number of successful number of arguments. The first paragraph that I quoted is referring to matching failures. if you have "%d %c %d" and you supply "123 1 a", sscanf (string as input) would return 2. Supplying "asd" as input would return 0 as 0 it matched nothing. But this is different from a reading error or EOF. If that happens, it will return EOF (generally -1).

Quote:
2. ...because if it stored the input in n and did not use a pointer, it would be the same of doing nothing, because functions are executed in a separated environment and in order for the variable values at the end of the function's execution don't get lost, you have to use a pointer, am I right?

Aand I also assume scanf is void type, because if you were to "scan" more than one variable and of different types, then which type to use? So, instead, scanf just changes the value of the variable, and so those values don't get lost, because functions are executed on a separated environment, it has to use pointers, therefore you need &n.

So what scanf does, basically, would be something like this:

Code:
void scanf( "%d", &n)
{
       int *ptr = &n;
}


Am I right?
How does the function know which type the pointer should be, or how many pointers it should use?


scanf uses a variable arguments to allow you to pass in any amount of variables. scanf has no idea what the arguments you pass it are, it can only assume from the types you describe in the string. If you pass n, besides some compilers checking formatting strings and alerting you to it before you run anything, scanf will think that n of type int is really an int*. Whatever value n had in it will be treated as a memory address for an int.

For 3)

When invalid input is encountered, it stops parsing and leaves data in stdin. If it didn't clear out the failed characters, it will loop around to scanf, detect input waiting to be read, try to parse and fail, and keeps looping.
Ah, thanks for clearing that up! Haven't used C in a while, and IO for C++ is a little different. Smile
AHelper wrote:
Quote:
Scanf() returns the number of arguments that was specified. If you ask for 3 arguments, it will return 3. You have it as one argument, so it will return 1. Scanf() returns -1 if there was an error. Hope this is correct in my thinking...


It will return the number of successful number of arguments. The first paragraph that I quoted is referring to matching failures. if you have "%d %c %d" and you supply "123 1 a", sscanf (string as input) would return 2. Supplying "asd" as input would return 0 as 0 it matched nothing. But this is different from a reading error or EOF. If that happens, it will return EOF (generally -1).

Quote:
2. ...because if it stored the input in n and did not use a pointer, it would be the same of doing nothing, because functions are executed in a separated environment and in order for the variable values at the end of the function's execution don't get lost, you have to use a pointer, am I right?

Aand I also assume scanf is void type, because if you were to "scan" more than one variable and of different types, then which type to use? So, instead, scanf just changes the value of the variable, and so those values don't get lost, because functions are executed on a separated environment, it has to use pointers, therefore you need &n.

So what scanf does, basically, would be something like this:

Code:
void scanf( "%d", &n)
{
       int *ptr = &n;
}


Am I right?
How does the function know which type the pointer should be, or how many pointers it should use?


scanf uses a variable arguments to allow you to pass in any amount of variables. scanf has no idea what the arguments you pass it are, it can only assume from the types you describe in the string. If you pass n, besides some compilers checking formatting strings and alerting you to it before you run anything, scanf will think that n of type int is really an int*. Whatever value n had in it will be treated as a memory address for an int.

For 3)

When invalid input is encountered, it stops parsing and leaves data in stdin. If it didn't clear out the failed characters, it will loop around to scanf, detect input waiting to be read, try to parse and fail, and keeps looping.


So you give scanf a variable's address so it can turn it into a pointer, I get it.

scanf's header must declare a pointer somewhere in it's parameters i suppose


Also, the quote of the definition of fflush answered some questions I had.

Alright, my questions have been answered, thank you AHelper!
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement