What is rewind(stdin) for and why does C need it? - c

From my understanding, I need to write rewind(stdin) after inputting integers if I want to input char or string. Why do I need to do this and why can't C let me input a char after inputting int
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996)
#include<math.h>
void main()
{
char c;
int x, y,square;
double root;
do {
printf("Enter integers = ");
scanf("%d%d", &x, &y);
square = pow(x, y);
root = double(sqrt(square));
printf("Squared = %d\n", square);
printf("Square root = %.2lf\n", root);
rewind(stdin); // If this isnt here it goes straight into the beginning instead of letting me input a char.
printf("Continue ? (Y/N)");
scanf("%c", &c);
} while (c != 'N' );
}

As comments already pointed out, there's a remain new-line character at scanf("%c", &c).
What I want to mention why rewind(stdin) make your code works is that rewind(stdin) moves input buffer position and, for some streams, it truncates its internal buffer. That's why your code works correctly with rewind(stdin) since it empties remaining characters in the buffer.
You can have the same effect with the following code which also moves its its input buffer position.
printf("Enter integers = ");
scanf("%d %d", &x, &y);
fseek(stdin, 0, SEEK_SET);
but, I found the following code has no effect with undefined behavior on Windows.
printf("Enter integers = ");
scanf("%d %d", &x, &y);
fflush(stdin)

Related

Taking a string input using gets() function in C [duplicate]

I'm pretty new to C, and I have a problem with inputing data to the program.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int a;
char b[20];
printf("Input your ID: ");
scanf("%d", &a);
printf("Input your name: ");
gets(b);
printf("---------");
printf("Name: %s", b);
system("pause");
return 0;
}
It allows to input ID, but it just skips the rest of the input. If I change the order like this:
printf("Input your name: ");
gets(b);
printf("Input your ID: ");
scanf("%d", &a);
It will work. Although, I CANNOT change order and I need it just as-is. Can someone help me ? Maybe I need to use some other functions. Thanks!
Try:
scanf("%d\n", &a);
gets only reads the '\n' that scanf leaves in. Also, you should use fgets not gets: http://www.cplusplus.com/reference/clibrary/cstdio/fgets/ to avoid possible buffer overflows.
Edit:
if the above doesn't work, try:
...
scanf("%d", &a);
getc(stdin);
...
scanf doesn't consume the newline and is thus a natural enemy of fgets. Don't put them together without a good hack. Both of these options will work:
// Option 1 - eat the newline
scanf("%d", &a);
getchar(); // reads the newline character
// Option 2 - use fgets, then scan what was read
char tmp[50];
fgets(tmp, 50, stdin);
sscanf(tmp, "%d", &a);
// note that you might have read too many characters at this point and
// must interprete them, too
scanf will not consume \n so it will be taken by the gets which follows the scanf. flush the input stream after scanf like this.
#include <stdlib.h>
#include <string.h>
int main(void) {
int a;
char b[20];
printf("Input your ID: ");
scanf("%d", &a);
fflush(stdin);
printf("Input your name: ");
gets(b);
printf("---------");
printf("Name: %s", b);
system("pause");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int a;
char b[20];
printf("Input your ID: ");
scanf("%d", &a);
getchar();
printf("Input your name: ");
gets(b);
printf("---------");
printf("Name: %s", b);
return 0;
}
Note:
If you use the scanf first and the fgets second, it will give problem only. It will not read the second character for the gets function.
If you press enter, after give the input for scanf, that enter character will be consider as a input f or fgets.
you should do this way.
fgetc(stdin);
scanf("%c",&c);
if(c!='y')
{
break;
}
fgetc(stdin);
to read input from scanf after reading through gets.
scanf("%d", &a); can't read the return, because %d accepts only decimal integer. So you add a \n at the beginning of the next scanf to ignore the last \n inside the buffer.
Then, scanf("\n%s", b); now can reads the string without problem, but scanf stops to read when find a white space. So, change the %s to %[^\n]. It means: "read everthing but \n"
scanf("\n%[^\n]", b);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int a;
char b[20];
printf("Input your ID: ");
scanf("%d", &a);
printf("Input your name: ");
scanf("\n%[^\n]", b);
//first \n says to ignore last 'return'
//%[^\n] read until find a 'return'
printf("---------\n");
printf("Name: %s\n\n", b);
system("pause");
return 0;
}
The scanf function removes whitespace automatically before trying to parse things other than characters. %c, %n, %[] are exceptions that do not remove leading whitespace.gets is reading the newline left by previous scanf. Catch the newline usinggetchar();
scanf("%d", &a);
getchar(); // catches the newline character omitted by scanf("%d")
gets(b);
https://wpollock.com/CPlus/PrintfRef.htm
Just use 2 gets() functions
When you want to use gets() after a scanf(), you make sure that you use 2 of the gets() functions and for the above case write your code like:
int main(void) {
int a;
char b[20];
printf("Input your ID: ");
scanf("%d", &a);
//the change is here*********************
printf("Input your name: ");
gets(b);
gets(b);
//the change is here*********************
printf("---------");
printf("Name: %s", b);
system("pause");
return 0;
}

Why is scanf skipping the input here? [duplicate]

This question already has answers here:
Using fflush(stdin)
(7 answers)
Parsing input with scanf in C
(5 answers)
scanf() leaves the newline character in the buffer
(7 answers)
Closed 5 years ago.
#include <stdio.h>
int main()
{
char another;
int num;
do
{
printf("enter the number");
scanf("%d", &num);
printf("square of%d is %d\n", num, num * num);
printf("want to check another number y/n");
fflush(stdin);
scanf("%c", &another);
} while (another == 'y');
return 0;
}
In the above code, the second scanf() is not getting executed and hence the console is not accepting input.
According to the standard, flushing stdin is undefined behaviour. See Using fflush(stdin) for more information.
When you enter a number for the first scanf, its always followed by a newline. %d only takes the integer value and the newline is still left in the input buffer. So the subsequent scanf ends up consuming that character and your loop terminates due to another=='y' being false. (another has '\n').
Following is one of the ways to solve the problem. Use a %c along with %d to capture newline and ignore it.
#include<stdio.h>
int main()
{
char another, nl;
int num;
do
{
printf("enter the number");
scanf("%d%c",&num,&nl);
printf("square of%d is %d\n",num,num*num);
printf("want to check another number y/n: ");
//fflush(stdin);
scanf("%c",&another);
printf("%c", another);
}while (another=='y');
return 0;
}
if you add the statement
fseek(stdin, 0, SEEK_END);
it will move the stdin pointer to the end of the file so any extra character will be omitted. then write the second scanf. I mean:
#include<stdio.h>
int main()
{
char another, nl;
int num;
do
{
printf("enter the number");
scanf("%d%c",&num,&nl);
fseek(stdin, 0, SEEK_END);
printf("square of%d is %d\n",num,num*num);
printf("want to check another number y/n: ");
//fflush(stdin);
scanf("%c",&another);
fseek(stdin, 0, SEEK_END);
printf("%c", another);
}while (another=='y');
return 0;
}
Cause of the char input before scanf dont work
remove the fflush and add a space to <<"%c">>
like this: scanf(" %c",&another);
#include<stdio.h>
int main(){
char another;
int num;
do
{
printf("enter the number ");
scanf("%d",&num);
printf("square of %d is %d\n",num,num*num);
printf("want to check another number y/n ");
scanf(" %c",&another);
}while (another=='y');
return 0;
}
This works great
First of all fflush; flushes the output buffer of a stream, so you should not be using it here. The reason why the second scanf is not working is because you are trying to read a 1-bit character which in this case always getting the value of \0 after the second printf statement. Hope this helped.

Why does this scanf in a while loop work?

I can't understand why this does exactly what I want. The part where I used two scanf's in the loop confuses me. I compiled it using devcpp.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int dend, dsor, q, r;
char c;
while(c!='n')
{
printf("enter dividend: ");
scanf("%d", &dend);
printf("enter divisor: ");
scanf("%d", &dsor);
q=dend/dsor;
r=dend%dsor;
printf("quotient is %d\n", q);
printf("remainder is %d\n", r);
scanf("%c", &c);
printf("continue? (y/n)\n");
scanf("%c", &c);
}
system("PAUSE");
return 0;
}
FWIW, your code invokes undefined behavior. In the part
char c;
while(c!='n')
c is an uninitialized local variable with automatic storage and you're trying to use the value of c while it is indeterminate.
That said, first scanf("%c", &c); is used to eat up the newline present in the input buffer due to the press of enter key after previous input. You can read about it in details in another post.

c - char variable proceeds without taking input

I have written a program to take input of two numbers and either add or subtract the numbers depending the operation specified.
Here is my code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
float i, j, k;
char a;
printf("This is a program to add or subs two number.\n");
printf("Enter the first number : ");
scanf("%f", &i);
printf("Enter the second number : ");
scanf("%f", &j);
printf("Give your choice(+ or -): ");
scanf("%c", &a);
switch(a){
case '+' :
k = i + j;
printf("Sum = %f\n", k);
break;
case '-' :
k = i - j;
printf("Difference = %f\n", k);
break;
default:
printf("Cannot do this operation\n");
}
return 0;
}
This program takes input for the two numbers but skips input for operation and runs the default case. Please help!
(I am using gcc compiler).
The %c conversion specifier won't automatically skip any leading whitespace, so if there's a stray newline in the input stream (from a previous entry, for example) the scanf call will consume it immediately.
One way around the problem is to put a blank space before the conversion specifier in the format string:
scanf(" %c", &a);
The blank in the format string tells scanf to skip leading whitespace, and the first non-whitespace character will be read with the %c conversion specifier.
-Aditya

i have to use getchar(); twice to end program [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why doesn't getchar() wait for me to press enter?
I continue to learn C, and at this stage I have something that is not clear to me.
When I write a program, that has several printf();, at the end, where I ask a user to press Enter key to finish the program, I have to write getchar(); twice, because when I write it once it does not work. I use getchar(); only at the end of the program, nowhere else.
I work on Ubuntu. I write in C.
here is my latest work:
#include<stdio.h>
main()
{
int m,n,r,k,q,l;
printf("This program will help you to find GCD & LCM of 2 non-negative integers\n");
printf("Now, you'll be asked to enter your integers, press Enter to continue");
getchar();
printf("Enter first integer:");
scanf("%i", &m);
printf("Enter second integer:");
scanf("%i", &n);
while(m<0 || n<0)
{
printf("The integers cannot be negative! You'll be asked to enter integers again.\n");
printf("Enter first integer:");
scanf("%i", &m);
printf("Enter second integer:");
scanf("%i", &n);
}
while(m==0 && n==0)
{
printf("Both of the integers cannot be zero at the same time! You'll be asked to enter integers again.\n");
printf("Enter first integer:");
scanf("%i", &m);
printf("Enter second integer:");
scanf("%i", &n);
}
if(n>m)
{
int b;
b=n;
n=m;
m=b;
}
r=m%n;
if(r==0)
{
printf("The GCD of these integers is %i\n", n);
printf("The LCM of these integers is %i\n", m);
printf("Press Enter to finish");
getchar();
getchar();
return 0;
}
k=n%r;
while(k>0)
{
r=k;
k=q;
}
l=(m*n)/r;
printf("The GCD of these integers is %i\n", r);
printf("The LCM of these integers is %i\n", l);
printf("Press Enter to finish");
getchar();
getchar();
return 0;
}
The reason you need 2 getchar() is because
the last scanf() call left the ENTER waiting in the buffer
the 1st getchar() "ate" that ENTER
the 2nd getchar() waits for input.
To properly deal with user input, use fgets() and sscanf() instaed of the simpler scanf(). Define a buffer for these functions, for example
char buffer[1000];
and then replace your scanf() calls with the pair
fgets(buffer, sizeof buffer, stdin);
sscanf(buffer, "%d", &n);
In the future you might want to also check the return value of sscanf() to detect invalid inputs, like foo42ENTER
if (sscanf(buffer, "%d", &n) != 1) /* invalid input */;
Edit (using strtol() rather than sscanf() is even better -- thanks to #Scooter)
char buffer[1000];
char *err;
/* ... */
fgets(buffer, sizeof buffer, stdin); /* error checking ommited */
n = strtol(buffer, &err, 10);
/* error checking ommited */
/* ... */

Resources