In similar questions, the scanf reading a char or string skips because it takes in a new line from the input buffer after the "Enter" key is pressed for the previous scanf, but I don't think that's the issue here. This program does not skip the 2nd scanf if input1 is an integer, but it skips it for other types of inputs (double, char, string, etc.).
#include <stdio.h>
#include <string.h>
int main(){
int input1;
char input2[6];
printf("Enter an integer. ");
scanf("%d", &input1);
printf("You chose %d\n", input1);
printf("Write the word 'hello' ");
scanf(" %s", input2);
if (strcmp(input2,"hello")==0){
printf("You wrote the word hello.\n");
} else {
printf("You did not write the word hello.\n");
}
return 0;
}
Why does this happen?
Comments in code:
int input1 = 0; // Always initialize the var, just in case user enter EOF
// (CTRL+D on unix) (CTRL + Z on Windows)
while (1) // Loop while invalid input
{
printf("Enter an integer. ");
int res = scanf("%d", &input1);
if ((res == 1) || (res == EOF))
{
break; // Correct input or aborted via EOF
}
int c;
// Flush stdin on invalid input
while ((c = getchar()) != '\n' && c != EOF);
}
printf("You chose %d\n", input1);
Also, take a look to How to avoid buffer overflow using scanf
Did you try to write "%*c" after your %c or %s or %d ?
Something like this : scanf("%s%*c", input1);
Related
So my code does the following:
Ask what's the option
If option is 1: Scan some numbers
If option is 2: Print those numbers
After each option, ask if user wanted to continue choosing (Y/N)
This is my main code
while(yesnocheck==1)
{
printf("What's your option?: ");
scanf("%d",&b);
switch(b){
case 1:
printf("How many numbers?: ");
scanf(" %d",&n);
a=(struct sv*)malloc(n*sizeof(struct sv));
for(int i=0;i<n;i++)
scanf("%d",&((a+i)->num));
break;
case 2:
for(int i=0;i<n;i++)
printf("%d\n",(a+i)->num);
break;
}
yesnocheck==yesnochecker();
}
And this is the yesnochecker function:
int yesnochecker()
{
char yesorno;
printf("Do you want to continue? (Y/N)");
while(scanf("%s",&yesorno))
{
if(yesorno=='Y')
return 1;
if(yesorno='N')
return 0;
printf("*Wrong input. Please reenter (Y/N): ");
}
}
So on dev C++, my code won't run correctly. After it's done option 1, when I enter "Y" then choose option 2, case 2 will display some weird numbers. However it works well on online C compilers.
And then, when I change the char yesorno in yesnochecker() function to char yesorno[2] and treat it as a string, the code does work.
Can someone shed some light?
It is a bad idea to read a char c with scanf("%s", &c);. "%s" requires a buffer to store a string. The only string which fits into a char is an empty string (consisting only of a terminator '\0' – not very useful). Every string with 1 character requires 2 chars of storage – 1 for the character, 1 for the terminator ('\0'). Providing a char for storage is Undefined Behavior.
So, the first hint was to use the proper formatter instead – "%c".
This is better as it removes the Undefined Behavior. However, it doesn't solve another problem as the following sample shows:
#include <stdio.h>
int cont()
{
char c; do {
printf("Continue (y/n): ");
scanf("%c", &c);
printf("Input %c\n", c);
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Output:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n):
Input '
'
Continue (y/n): n↵
Input 'n'
Live Demo on ideone
WTH?
The scanf("%c") consumes one character from input. The other character (inserted for the ENTER key) stays in input buffer until next call of any input function.
Too bad, without ENTER it is hard to confirm input on console.
A possible solution is to read characters until the ENTER key is received (or input fails for any reasons). (And, btw., getc() or fgetc() can be used as well to read a single character.):
#include <stdio.h>
int cont()
{
int c;
do {
int d;
printf("Continue (y/n): ");
if ((c = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
printf("Input '%c'\n", c);
for (d = c; d != '\n';) {
if ((d = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
}
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Output:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n): Hello↵
Input 'H'
Continue (y/n): n↵
Input 'n'
Live Demo on ideone
Please, note, that I changed the type for the read character to int. This is because getc()/fgetc() return an int which is capable to store any of the 256 possible char values as well as -1 which is returned in case of failing.
However, it isn't any problem to compare an int with a character constant (e.g. 'y'). In C, the type of character constants is just int (SO: Type of character constant).
I have never programmed in C and today I have to write small code. Program is very easy - I want to add two integers.
But when I'm trying to check if given input is a number and first scanf returns 0, the second one returns 0 too without waiting for input.
Code:
int main()
{
int a = 0;
int b = 0;
printf("Number a:\n");
if (scanf("%d", &a) != 1)
{
printf("Not a number. a=0!\n");
a = 0;
}
printf("Number b:\n");
if (scanf("%d", &b) != 1)
{
printf("Not a number. b=0!\n");
b = 0;
}
printf("%d\n", a+b);
return 0;
}
The input that failed to convert to a number for the first fscanf() is still pending in standard input's buffer and causes the second fscanf() to fail as well. Try discarding offending input and re-prompting the user:
#include <stdio.h>
int main(void) {
int a = 0;
int b = 0;
int c;
printf("Number a:\n");
while (scanf("%d", &a) != 1) {
printf("Not a number, try again:\n");
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
exit(1);
}
printf("Number b:\n");
while (scanf("%d", &b) != 1) {
printf("Not a number, try again:\n");
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
exit(1);
}
printf("%d\n", a + b);
return 0;
}
Factorizing the code with a utility function makes it much clearer:
#include <stdio.h>
int get_number(const char *prompt, int *valp) {
printf("%s:\n", prompt);
while (scanf("%d", valp) != 1) {
printf("Not a number, try again:\n");
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
return 0;
}
return 1;
}
int main(void) {
int a, b;
if (!get_number("Number a", &a) || !get_number("Number b", &b)) {
return 1;
}
printf("%d\n", a + b);
return 0;
}
That is because, once the first scanf() failed, it is probably because of matching failure, and the input which caused the matching failure, remains inside the input buffer, waiting to be consumed by next call.
Thus, the next call to scanf() also try to consume the same invalid input residing in the input buffer immediately, without waiting for the explicit external user input as the input buffer is not empty.
Solution: After the first input fails for scanf(), you have to clean up the input buffer, for a trivial example, something like while (getchar() != '\n'); should do the job.
This happens if there is any input from the previous entry, can take that, and skip input from the user. In the next scanf also It takes the new line which is left from the last scanf statement and automatically consumes it. That's what happening in your code.
You can clear previous input in stdin stream by using fflush(stdin); before starting your program.
This can also be solved by leaving a space before % i.e scanf(" %d",&n);,Here leaving whitespace ensures that the previous new line is ignored.
Or we can use getc(stdin) before calling any scanf statement, Sometimes it helps very much.
int main()
{
int a = 0;
int b = 0;
printf("Number a:");
//getc(stdin);
if (scanf(" %d", &a) != 1)
{
printf("Not a number. a=0!\n");
a = 0;
}
printf("Number b:\n");
//getc(stdin);
if (scanf(" %d", &b) != 1)
{
printf("Not a number. b=0!\n");
b = 0;
}
printf("%d\n", a+b);
return 0;
}
It's because of input and output aren't synchronized in C. The program can output some lines after user's input while the input hasn't been read. Try to run this code:
char token;
scanf("%c", &token);
printf("%c\n", token);
printf("line 1\n");
scanf("%c", &token);
printf("%c\n", token);
printf("line 2\n");
scanf("%c", &token);
printf("%c\n", token);
printf("line 3\n");
And input abc in one line.
You can imagine this like there are two separated consoles, one for input and another for output.
For example you want to input asd for a and 3 for b. In this case, the first scanf won't find any number and will return 0. But it also won't read anything from the input. Because of this, the second scanf will see asd too.
To clear the input if a isn't a number, you should input all remaining chars in the line until '\n' (look at the #Sourav's solution)
You could do the same thing using strings without problems with scanf. Just take the user input as string and convert it to integer. Then convert the string back to integer to check whether they are the same. If they are the same, treat a and b as integers, if not, do what you do (You will need to include string.h). Here is the working code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int a;
int b;
char str1[100];
char str2[100];
printf("Number a:\n");
scanf("%s", &str1); //take input as a string
a = atoi(str1); //convert string to integer
snprintf(str2, 100, "%d", a); //convert integer back to string
//if the integer converted to string is not the same as the string converted to integer
if (strcmp(str1, str2)!= 0)
{
printf("Not a number. a=0!\n");
a = 0;
}
printf("Number b:\n");
scanf("%s", &str1);
b = atoi(str1);
snprintf(str2, 100, "%d", b);
if (strcmp(str1, str2)!= 0)
{
printf("Not a number. b=0!\n");
b = 0;
}
printf("%d\n", a+b);
return(0);
}
I have never programmed in C and today I have to write small code. Program is very easy - I want to add two integers.
But when I'm trying to check if given input is a number and first scanf returns 0, the second one returns 0 too without waiting for input.
Code:
int main()
{
int a = 0;
int b = 0;
printf("Number a:\n");
if (scanf("%d", &a) != 1)
{
printf("Not a number. a=0!\n");
a = 0;
}
printf("Number b:\n");
if (scanf("%d", &b) != 1)
{
printf("Not a number. b=0!\n");
b = 0;
}
printf("%d\n", a+b);
return 0;
}
The input that failed to convert to a number for the first fscanf() is still pending in standard input's buffer and causes the second fscanf() to fail as well. Try discarding offending input and re-prompting the user:
#include <stdio.h>
int main(void) {
int a = 0;
int b = 0;
int c;
printf("Number a:\n");
while (scanf("%d", &a) != 1) {
printf("Not a number, try again:\n");
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
exit(1);
}
printf("Number b:\n");
while (scanf("%d", &b) != 1) {
printf("Not a number, try again:\n");
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
exit(1);
}
printf("%d\n", a + b);
return 0;
}
Factorizing the code with a utility function makes it much clearer:
#include <stdio.h>
int get_number(const char *prompt, int *valp) {
printf("%s:\n", prompt);
while (scanf("%d", valp) != 1) {
printf("Not a number, try again:\n");
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
return 0;
}
return 1;
}
int main(void) {
int a, b;
if (!get_number("Number a", &a) || !get_number("Number b", &b)) {
return 1;
}
printf("%d\n", a + b);
return 0;
}
That is because, once the first scanf() failed, it is probably because of matching failure, and the input which caused the matching failure, remains inside the input buffer, waiting to be consumed by next call.
Thus, the next call to scanf() also try to consume the same invalid input residing in the input buffer immediately, without waiting for the explicit external user input as the input buffer is not empty.
Solution: After the first input fails for scanf(), you have to clean up the input buffer, for a trivial example, something like while (getchar() != '\n'); should do the job.
This happens if there is any input from the previous entry, can take that, and skip input from the user. In the next scanf also It takes the new line which is left from the last scanf statement and automatically consumes it. That's what happening in your code.
You can clear previous input in stdin stream by using fflush(stdin); before starting your program.
This can also be solved by leaving a space before % i.e scanf(" %d",&n);,Here leaving whitespace ensures that the previous new line is ignored.
Or we can use getc(stdin) before calling any scanf statement, Sometimes it helps very much.
int main()
{
int a = 0;
int b = 0;
printf("Number a:");
//getc(stdin);
if (scanf(" %d", &a) != 1)
{
printf("Not a number. a=0!\n");
a = 0;
}
printf("Number b:\n");
//getc(stdin);
if (scanf(" %d", &b) != 1)
{
printf("Not a number. b=0!\n");
b = 0;
}
printf("%d\n", a+b);
return 0;
}
It's because of input and output aren't synchronized in C. The program can output some lines after user's input while the input hasn't been read. Try to run this code:
char token;
scanf("%c", &token);
printf("%c\n", token);
printf("line 1\n");
scanf("%c", &token);
printf("%c\n", token);
printf("line 2\n");
scanf("%c", &token);
printf("%c\n", token);
printf("line 3\n");
And input abc in one line.
You can imagine this like there are two separated consoles, one for input and another for output.
For example you want to input asd for a and 3 for b. In this case, the first scanf won't find any number and will return 0. But it also won't read anything from the input. Because of this, the second scanf will see asd too.
To clear the input if a isn't a number, you should input all remaining chars in the line until '\n' (look at the #Sourav's solution)
You could do the same thing using strings without problems with scanf. Just take the user input as string and convert it to integer. Then convert the string back to integer to check whether they are the same. If they are the same, treat a and b as integers, if not, do what you do (You will need to include string.h). Here is the working code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int a;
int b;
char str1[100];
char str2[100];
printf("Number a:\n");
scanf("%s", &str1); //take input as a string
a = atoi(str1); //convert string to integer
snprintf(str2, 100, "%d", a); //convert integer back to string
//if the integer converted to string is not the same as the string converted to integer
if (strcmp(str1, str2)!= 0)
{
printf("Not a number. a=0!\n");
a = 0;
}
printf("Number b:\n");
scanf("%s", &str1);
b = atoi(str1);
snprintf(str2, 100, "%d", b);
if (strcmp(str1, str2)!= 0)
{
printf("Not a number. b=0!\n");
b = 0;
}
printf("%d\n", a+b);
return(0);
}
This question already has answers here:
Why is scanf() causing infinite loop in this code?
(16 answers)
Closed 7 years ago.
I am trying to see if user enters 3 correct input. If not the loop ask for input again and again until they correct it correctly.
#include <stdio.h>
int main(void) {
int num1,num2;
char str;
int check;
printf("Enter : ");
check = scanf("%d,%d, %c", &num1, &num2, &str);
while (check != 3) {
printf("Enter : ");
check = scanf("%d,%d, %c", &num1, &num2, &str);
}
}
Let's say if I entera, 5.4, c we get an infinite loop. Why is it giving an infinite loop?
There are far more ways to incorrectly use scanf in a loop that proper ones. The primary issue (aside from input or matching failures that are explained in the man page), is failing to empty the input buffer (stdin when reading from a terminal) after a failed conversion. (There is also the issue that the user must enter something.) When a user enters text and presses [Enter] a newline ('\n') is generated and placed in the input buffer to mark the end of line. When you enter a, 5.4, c, 'a' is fine, but 5.4 is not an int and the processing fails:
If processing of a directive fails, no further input is read, and
scanf() returns.
When scanf returns, it leaves the remaining characters in stdin and you loop and attempt to read again. scanf attempts to read what is left in stdin, processing again fails, and the loop continues endlessly.
In this situation the only way to prevent the indefinite loop is to manually empty the input buffer after you call to scanf. Something simple will do:
int c;
...
while (...) {
scanf (...)
while ((c = getchar()) != '\n' && c != EOF) {}
}
This will insure you start with an empty buffer on the next iteration. For example:
#include <stdio.h>
int main (void) {
int num1 ,num2, c;
char str;
while (printf ("\nEnter : ") &&
scanf (" %d, %d, %c%*c", &num1, &num2, &str) != 3) {
printf ("error: invalid input, required: 'int, int, char'\n");
/* empty remaining chars from input buffer */
while ((c = getchar()) != '\n' && c != EOF) {}
}
printf ("\n num1 : %d\n num2 : %d\n str : %c\n\n", num1, num2, str);
return 0;
}
Example Use
$./bin/scanf3
Enter : a
error: invalid input, required: 'int, int, char'
Enter : a, 5.4, c
error: invalid input, required: 'int, int, char'
Enter : 10, 25
error: invalid input, required: 'int, int, char'
Enter : 10, 25, a
num1 : 10
num2 : 25
str : a
note: this does not protect against the user entering nothing (just pressing [Enter]) and the cursor just sitting there blinking as it waits for input. That is an inherent behavior of scanf, part of which is the reason that line-oriented input methods (fgets or getline) are preferable when taking input.
First time scanf() reads the character then it reads the newline (enter/whitespace character ).This character is present in the input buffer and is read by the scanf() function.
So clear the buffer before reading the new user input using fflush(stdin).
EDIT : Tested in windows VS2013.Sorry i dont have Linux. Windows and Linux define the behaviour of fflush() in different way.If you are using in Windows platform :
int main(void) {
int num1, num2;
char str;
int check;
printf("Enter : ");
check = scanf("%d,%d, %c", &num1, &num2, &str);
while (check != 3) {
////Flush the input buffer ////
fflush(stdin);
printf("Enter : ");
check = scanf("%d,%d, %c", &num1, &num2, &str);
}
}
EDIT : this will work in all platforms.
Another simple way is to consume the remaining read line by
while ((c = getchar()) != '\n' && c != EOF);
so now
int main(void) {
int num1, num2;
char str,c;
int check;
printf("Enter : ");
check = scanf("%d,%d, %c", &num1, &num2, &str);
while (check != 3) {
////read the remaining char ////
while ((c = getchar()) != '\n' && c != EOF);
printf("Enter : ");
check = scanf("%d,%d, %c", &num1, &num2, &str);
}
}
the output should be something like this:
Enter Character : a
Echo : a
I wrote
int c;
while (c != EOF)
{
printf("\n Enter input: ");
c = getchar();
putchar(c);
}
But I get two Enter Input after the echos.
Two characters are retrieved during input. You need to throw away the carriage return.
int c = 0;
int cr;
while (c != EOF)
{
printf("\n Enter input: ");
c = getchar();
cr = getchar(); /* Read and discard the carriage return */
putchar(c);
}
Homework?
If so, I won't give a complete answer/ You've probably got buffered input - the user needs to enter return before anything is handed back to your program. You need to find out how to turn this off.
(this is dependent on the environment of your program - if you could give more details of platform and how you are running the program, we could give better answers)
take fgets eg:
char c[2];
if( fgets( c, 2, stdin ) )
putchar( *c );
else
puts("EOF");
and you dont have any problems with getchar/scanf(%c)/'\n' and so on.
Why don't you use scanf instead?
Example:
char str[50];
printf("\n Enter input: ");
scanf("%[^\n]+", str);
printf(" Echo : %s", str);
return 0;
Outputs
Enter input: xx
Echo : xx
scanf reference
#include <stdio.h>
#include <conio.h>
main(){
int number;
char delimiter;
printf("enter a line of positive integers\n");
scanf("%d%c", &number, &delimiter);
while(delimiter!='\n'){
printf("%d", number);
scanf("%d%c", &number, &delimiter);
}
printf("\n");
getch();
}