is stdin buffer empty C [duplicate] - c

This question already has answers here:
Is there any way to peek at the stdin buffer?
(3 answers)
Closed 9 years ago.
I want to write a function that would tell me if stdin buffer is empty.
So, here's the code:
int buff_empty()
{
char buffer[3];
fgets(buffer, 3, stdin);
if(strlen(buffer) > 1) return 0;
return 1;
}
but the problem is - I don't want fgets() to wait for my input. I'm using my own function to read, for example, an integer, and then check with this func is buffer empty (was more than one number put) or not.
Function works well, but when I read a number (read function reads just to white space, just like scanf()), it waits for one breakline(Enter?) more. Is there any way to solve it?
Thanks in advance!

Part of the problem is that you are kind of asking the program to read your mind. When it reads (or tries to read) from the input, and there's nothing there, how does it tell the difference between there being no more input and the input just hasn't been entered yet?
The normal solution is to put the input into a separate file, and look for the end-of-file to tell when there is no more input. So when the program tries to read the next number, it hits the end of file and knows that there isn't any more input.
Try reading up on the feof() function, or the possible return values of fgets().

Related

Can somebody explain why the line of this code containing fgets isn't getting executed? [duplicate]

This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 1 year ago.
#include <stdio.h>
#include <string.h>
int main()
{
int num;
char answer[10];
char affirmation[10]="yes";
do
{
printf("Enter a number : \n");
scanf("%d",&num);
if (num % 97 == 0)
{
printf("No. is divisible by 97!\n");
}
else
{
printf("No. is not divisible by 97!\n");
}
printf("Once More ? [yes/no] \n");
fgets(answer,sizeof(answer),stdin);
}
while(strcmp(affirmation,answer) == 0);
return 0;
}
I expected from this program to check the divisibility of a provided number by 97 and then to ask if I again want it to check for another number if I input "yes". But it isn't prompting for my input .
If anybody can explain the reason behind this problem and suggest some ways to get through, it will be appreciated.The output is given below:
This output is for num = 194.
It is being executed but what it's reading is the newline character in the input stream that wasn't read when you did the scanf.
What your scanf does is to first skip any white space, then read an integer up to but not including the first non-digit character, which is probably the \n generated by the ENTER key.
Then, because fgets reads a line up to the next newline, you get an empty line.
In both the preceding two paragraphs, I'm assuming for simplicity ideal conditions such as ensuring it's a valid integer and that the line is not longer than the size you provided. Obviously, deviating from that could cause unruly behaviour.
It's generally not a good idea to mix the two input types unless you know in great detail what will be in the input stream. It's often better to just use line-based input and then sscanf that into more appropriate variables.
That way, you can be more sure about where your input stream is at any given point.
A quick fix in this particular case is simply to augment your scanf so that it skips to the start of the next line:
scanf("%d",&num);
while (getchar() != '\n') {}
The other problem you'll have after that is the fact that your fgets input will actually be "yes\n" rather than "yes", so that string comparison won't work.
If you're after a fairly robust line input function that takes care of that (and many other things), see here.

question about reading an input using fgets and scanf in c [duplicate]

This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 3 years ago.
I have recently been trying to do an exercise in c.
I want to read the input which is something like: "SET 0" (note that the actual text will be parsed later).
I tried fgets as it is like that:
char in[20];
//ok, this reads the first line, the first input is meant to be a number
scanf("%s",in);
if(isdigit(in[0])){
char array[]={'?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?'};
auto counter = atoi(in);
while(counter !=0){
fgets(in, sizeof(in),stdin);
For some reason, when i type eg "SET 0" and i am using fgets the in variable is empty(will print nothing).
I tried scanf but it will not read the number.
Any ideas/suggestions of what i can do?
Thanks in advance!
Do not mix fgets() with scanf() until you know why scanf()` is evil.
fgets() read the left over '\n' of the first line of user input which scanf() did not read.

Why does getchar wait after one character is entered? [duplicate]

This question already has answers here:
How to avoid pressing Enter with getchar() for reading a single character only?
(14 answers)
Closed 4 years ago.
Here is my code:
#include <stdio.h>
int main()
{
char a = getchar();
printf("char: %c", a);
}
I'm compiling this with gcc.
When running, the program waits for input even after one character is entered on console. Shouldn't it immediately exit and print the character? I'm running this on Ubuntu for Windows, if that can make any difference.
stdin is your default input stream. The default buffering mode of stdin is line buffered. So it waits for the \n to be entered. Then only there is something to read from the input stream and then getchar gets the input and works with it.
The operating system often buffers console input until a new line is entered, such that your program will not even receive the single character before. Probably nothing you can do about that.

How is this buffer really working?

as a Linux system programming exercise I've written my own version of the tree command, which is to read from stdin and write to stdout using only the basic read() and write() C library functions. I've done it so that when an asterisk (*) is entered, the program is terminated. I have managed to get it to work properly, my problem is that I don't really understand why it works the way it does. What confuses me is the buffer. First of all, here is the code portion in question:
char buf[1];
...
do {
read(STDIN_FILENO, buf, 1);
if( buf[0] == '*') break;
write(STDOUT_FILENO, buf, 1);
} while( buf[0] != '*');
...
My idea was to read from stdin char by char, thereby storing the char in buf, check if it was an asterisk, then write the char from buf to stdout.
The behaviour is the following: I type a string of any number of chars, press ENTER, that string gets output to stdout, at which point I can type a new char string. If the string ends with an asterisk, the string is output up until the asterisk, then the program is terminated.
My problems are:
1) buf is sopposed to contain only one char. How is it possible that I enter any number of chars und upon pressing ENTER all of them are output to stdout? I would expect one char at a time to be output, or only the last one. How does a one-char buffer store all of those chars? Or do many one-char buffers get created? By whom?
2) What is so special about the newline character that prompts the string to be output? Why is it not just another char within the string? Is it just a matter of definition within the function read()?
Thank you for any help in understanding the working of the buffer!
This is based upon the way the IO calls - read and write will work on most OS's.
You are reading only 1 byte, so while you are typing, stuff will be held by an io buffer (not yours), until your loop reads it. Since you have no sleeps, it will be reading, or waiting to read faster than you can humanly type.
Also as R Sahu suggests - the input buffer may not be presented to your program until you press enter on the console you are typing at. This depends on the console and its config - but most will buffer lines and wait for enter too. This would be different if you were piping into stdin.
The last parameter to read, the '1', is what instructs it to read one byte here.
The second part is that your output is also buffered, and newline is commonly used by console output buffers to flush and show the line. Until that case, it is being written by your code to that output buffer. If you do not want this behaviour, then an fflush call after the write should output character by character instead.
When you type in your input at a console, the input characters are not immediately fed to stdin. After you press the Enter button, the entire line you typed, including the newline character, are is fed to stdin by the run time environment.

Why is my professor using two getchar();? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Why is my prof using two getchar(); at the end of our C program tutorials?
And what is the "better way" for this?
He is waiting for user input so that you can see the output to the program, otherwise it will just complete and the output will not be visible (depending on the OS). Take it out and give it a try.
He wants the console to stay open and wait for the user to press a key. I think to remember that depending on what happens in your professors program above the "getchar()". There might still be something in the buffer, so he added a second "getchar()". Not exactly the most elegant way to solve the problem.
Edit: Here is a little example. There is still a remaining "\n" in the buffer from the "scanf()" If you add a second "getchar()", you get the expected result. You have to flush the buffer before the "getchar()".
#include <stdio.h>
main()
{
int input;
scanf("%d", &input);
printf("The input is %d\n", input);
getchar();
return 0;
}
Edit 2: Here is a solution taken from here.
int c;
printf( "Press ENTER to continue... " );
fflush( stdout );
do c = getchar(); while ((c != '\n') && (c != EOF));
The best better way is not to add any code to try and keep the console window open: start your program right from the console window.
If you must start your program from the IDE and want the program to not terminate before the user presses Enter, one single getchar() should do it.
The second best better way to make the program terminate after the user presses a key, is to always make sure there are no inputs pending and use one single getchar().
The reason your teacher uses 2 getchar(), I guess, is that there is already a character in the input buffer from previous inputs. To consume all characters from the inputs, up to and including the ENTER, this is usual:
int ch;
/* ... */
printf("Press Enter"); fflush(stdout);
while ((ch = getchar()) != '\n' && ch != EOF) /* void */;
The reason a lot of beginners feel it necessary to put two getch calls in their code is that one single call often doesn’t work.
The reason for that is that getch fetches the next keyboard input from the input queue. Unfortunately, this queue gets filled whenever the user presses keys on the keyboard, even if the application isn’t waiting for input at that moment (of if it isn’t reading the whole input – see Lulu’s answer for an example). As a consequence, getch will fetch a character from the input queue without waiting for the next key press – which is really what the programmer wants.
Of course, this “solution” will still fail in a lot of cases, when there’s more than just one character in the keyboard queue. A better solution is to flush that queue and then request the next character. Unfortunately, there’s no platform-independent way to do this in C/C++ to my knowledge. The conventional way to do this in C++ (sorry, my C is limited) looks like this:
std::cin.ignore(std::cin.rdbuf()->in_avail());
This simply ignores all available input, effectively clearing the input queue. Unfortunately, this code doesn’t always work, either (for very arcane reasons).
Why is my prof using two getchar(); at the end of our C program tutorials?
Assuming you have something like
int main ( void )
{
int input;
scanf ( "%d", &input );
printf ( "The input is %d.\n", input );
getchar();
getchar();
return 0;
}
Two because scanf won't return until after an enter is pressed, but there will be the '\n' from the enter and any other characters you have entered in the input buffer.
So if you run the above and input 1234Enter, the program will pause after printing The input is 1234. until you then press Enter again. The first getchar reads the '\n' associated with the first Enter. If you input something else, such as 1234SpaceEnter, the program will not pause, as first getchar will read the space. Two getchars might not be enough, and you've interspersed the code for printing the response into the code for handling the input.
And what is the "better way" for this?
There are various standard ways of reading input in C. There are also platform specific ways of ignoring text in the input buffer, but you shouldn't need to do that if you use fgets to read a line of input instead of scanf to read some input from the last line entered.
fgets ( read input until '\n' or end of file ) followed by sscanf ( parse a string for input ) is safe from buffer overruns, and will absorb any extra input and line terminating '\n':
#include <stdio.h>
int main ( void )
{
int input;
char buf[16] = "";
fgets ( buf, sizeof buf, stdin );
sscanf ( buf, "%d", &input );
printf ( "The input is %d.\n", input );
fflush ( stdout );
getchar();
return 0;
}
Flushing stdout after the printf isn't normally needed for terminal IO, but can be if you're piping it to a disk ( typically when you're logging a crashing program it will lose the most interesting bit just before the crash if you don't flush ).
Because fgets reads up to and including the end of the line, there are no characters left in the buffer so you only need one getchar, and slightly awkward input such as 1234SpaceEnter doesn't cause the program to terminate without pausing.
However, most of the time you don't need to wait after running a console application - on Linux or other Unix systems you typically have a console open and run the program there, after which control returns to the shell. On Windows, IDEs such as Visual Studio typically run the program and pause it using something like:
"C:\WINDOWS\system32\cmd.exe" /c ""...\ConsoleApplication1.exe" & pause"
Or you can open cmd.exe and run it from there, or you can run it with a .pif shortcut and set the checkbox it not to close the console on exit, or you can create a batch file which runs it and pauses.
You really only need to make the program pause itself if you're on Windows and you're using a debugger to run it and you haven't set any breakpoints.
to pause the (probably) commandline program. he is using two, because using only one didn't work and he probably doesn't know why..
find him a better solution to do this (and not std::cin) and you'll be the hero of the day.
Probably to keep the output window open when you run the program from the IDE.
...why there are two there is beyond me though.
It is a naive solution to the unused buffered input problem. Your prof recognises the problem, but it seems does not know how to solve it properly.
If you use formatted input, only characters entered that match the format specifier are used. So if for example the last input requested a decimal integer using %d, you might enter at the console:
123<newline>
The formatted input will consume the "123", leaving the <newline> buffered. An unformatted input such as getchar() will consume that and return immediately. Since this is not what you want, your prof has used the "just add another getchar() kludge". This works only if the user enters the expected input. A hamfisted typist might type:
123w<newline>
Now the first getchar() gets the 'w', the second gets the <newline>, and your program terminates before you intended it to, and in a GUI environment, if the terminating process owns the window it is running in, then the OS closes it.
A more robust solution is to repeatedly call getchar() until the <newline> is found:
while( getchar() != '\n' ) { /*do nothing*/} ;
getchar() ; /* wait */
Of course if the previous input was a character, you need to check it was not already a <newline>:
while( ch != '\n' && getchar() != '\n' ) { /*do nothing*/} ;
getchar() ; /* wait */
Rather than putting the flush loop at the end just before the 'wait' input call, it is better to perform the buffer flush after every input that requires it. This is because that is where you know you need it, and how it should be coded. I tend to write wrapper functions for the input types I need.
getchar(); at the end of the program creates a "Press any key to continue" situation. I'm guessing that he likes hitting any key twice.
To fetch a remaining "\n" from the buffer so that the app closes.
Because one hit of the "enter" button generates two characters on Windows, see wikipedia. At least it used too, long time ago in a galaxy far far away ...

Resources