Scanf() does not recognize space before %c - c

Observe this chunk of code:
#include <stdio.h>
int main(void)
{
char choice;
printf("\n\nDo you want to play again (Y/N)? ");
scanf(" %c", &choice);
if (choice != 'Y' || choice != 'y' || choice != 'N' || choice != 'n')
{
printf("\n\nYou didn\'t enter a decision.");
}
return 0;
}
I want the printf() to prompt the user to input either Y or N. The scanf() will fill the user's input in the variable choice. If choice is not equal to Y, y, N, or n, it will tell the user that he/she didn't enter a decision. Then, the program will end.
However, when I inputted Y or N, it printed "You didn't enter a decision." This should only happen if I don't enter Y or N (lowercase or uppercase).
I even put a space before the conversion character so the scanf() wouldn't read the newline character (\n).
Any help would be greatly appreciated!

Change
if (choice != 'Y' || choice != 'y' || choice != 'N' || choice != 'n')
to
if (choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n')
otherwise whether you enter any of Y, y, N, n or any other character (as pointed by Jonathan Leffler in the comment), the expression in if will be evaluated to true.

You Have to Just Include Else Like Following
#include <stdio.h>
int main(void)
{
char choice;
printf("\n\nDo you want to play again (Y/N)? ");
scanf(" %c", &choice);
if (choice != 'Y' || choice != 'y' || choice != 'N' || choice != 'n')
{
printf("\n\nYou didn\'t enter a decision.");
}
return 0;
}

Related

User input with scanf using while loop

I'm having a problem with multiple characters while using a while loop. I'm writing a code that would direct the user to a new function based on the input of either "y" or "n". When I scanf for one character it works fine; however, when the user types in multiple characters the while loop repeats.
#include <stdio.h>
int main()
{
char x;
printf("type in letter n or y\n");
scanf("%c", &x);
while (x!= 'Y' && x!='N' && x!= 'n' && x!='y')
{
printf("Invalid, please type Y/N to continue: \n");
scanf(" %c", &x);
}
if (x== 'Y' || x == 'y')
{
printf("y works");
}
if (x =='N' || x =='n')
{
printf("n works");
}
}
For example, if I type in hoyp, it would say "Invalid, ..." 2 times and then the "y works" would be written on the third line. How can the code be changed so that the invalid would only be said once, and the user must input again to allow the program to continue?
This is how scanf behaves. It keeps reading in all the characters you've entered. You can accept a string as input first using fgets and extract and check only its first character. fgets allows you to specify the exact number of characters to be read. I have first declared a char array of size 4096. This will work when the input is up to 4095 characters. You can adjust the size as per your needs.
#include <stdio.h>
int main()
{
char x, buffer[4096];
printf("type in letter n or y\n");
fgets(buffer, 4096, stdin);
x = buffer[0];
while (x!= 'Y' && x!='N' && x!= 'n' && x!='y')
{
printf("Invalid, please type Y/N to continue: \n");
fgets(buffer, 4096, stdin);
x = buffer[0];
}
if (x== 'Y' || x == 'y')
{
printf("y works");
}
if (x =='N' || x =='n')
{
printf("n works");
}
}
Here is my approach to the problem:
I have used fgets() instead of scanf(). See why
here.
I have used the suggestion by users jamesdlin and M.M in this question to solve the repeated printing issue when the input is more than one character or if the input is empty. I encourage you to read the whole thread to know more about this issue.
(Optional) Used some extra headers for better code readability in the loop conditions. I think the fgets() could be used in the condition of the while() but I got used to the pattern I have written below.
Edit: added a condition to reject inputs with length > 1. Previously, inputs that starts with 'y' or 'n' will be accepted (and are interpreted as 'y' or 'n' respectively) regardless of their length.
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
void clearInput();
int main()
{
// allocate space for 'Y' or 'N' + '\n' + the terminator '\0'
// only single inputs will be accepted
char _inputbuff[3];
char choice;
bool isValidInput = false;
while(!isValidInput) {
printf("Please enter your input[y/n]: ");
// use fgets() instead of scanf
// this only stores the first 2 characters of the input
fgets(_inputbuff, sizeof(_inputbuff), stdin);
// don't accept empty input to prevent hanging input
if(_inputbuff[0] == '\n') {
printf("Empty input\n");
// go back to the top of the loop
continue;
}
// input is non-empty
// if the allocated space for the newline does not
// contain '\n', reject the input
if(_inputbuff[1] != '\n') {
printf("Input is more than one char.\n");
clearInput();
continue;
}
choice = _inputbuff[0];
// printf("The input is %c\n", choice);
// convert the input to uppercase for a 'cleaner' code
// during input validation
choice = toupper(choice);
// the input is not 'Y' or 'N'
if(choice != 'Y' && choice != 'N') {
printf("Please choose from Y or N only.\n");
// go back to the top of the loop
continue;
}
// the input is 'Y' or 'N', terminate the loop
isValidInput = true;
}
// conditions for 'Y' or 'N'
if(choice == 'Y') {
printf("The input is Yes.\n");
return 0;
}
if(choice == 'N') {
printf("The input is No.\n");
return 0;
}
}
void clearInput() {
int _clear;
// clear input stream to prevent repeated printing of invalid inputs
while ((_clear = getchar()) != '\n' && _clear != EOF ) { }
}
(This is my first time answering a question and it has been a while since I have used C so feel free to give suggestions/corrections regarding my answer. Thanks!)

C Programming yes no loop with error catcher

I am trying to get this yes no programme to work in a loop. I've checked the other users messages and there's only one which is poorly written and doesn't work properly.
So if the user types y or Y it installs and if they type n or N it exits out of the program. Also if they type w, m or any other letter that isn't y or n it goes back to the start and asks them again.
Not sure if its a while loop or a do while loop. The programme below works but doesn't have any loops.
#include <stdio.h>
int main() {
char yn;
printf("Do you want to install this programme? y/n: ");
scanf("%c", &yn);
if(yn == 'y' || yn == 'Y') {
printf("Installing...\n");
}
else if(yn == 'n' || yn == 'N') {
printf("Exiting programme!\n");
}
else {
// Go back to the start/top of the programme!
}
return 0;
}
You can wrap your code into a while-loop.
Something like:
while(1)
{
printf("Do you want to install this programme? y/n: ");
scanf("%c", &yn);
if(yn == 'y' || yn == 'Y') {
printf("Installing...\n");
break; // Stop the while-loop to end the program
}
else if(yn == 'n' || yn == 'N') {
printf("Exiting programme!\n");
break; // Stop the while-loop to end the program
}
}
The type of loop that makes most sense in this scenario is a do/while loop since getting a response from a user is something that should happen at least once and be tested for until a desired response is obtained from the user.
Also, using tolower or toupper on yn when checking for equality can eliminate the need to check both upper and lowercase.
do
{
printf("Do you want to install this program? y/n: ");
scanf(" %c", &yn);
}
while(tolower(yn) != 'n' && tolower(yn) != 'y');
if(tolower(yn) == 'n')
{
printf("Exiting program\n");
}
else
{
printf("Installing ...\n");
}
fgets can be used to capture the input. It has an advantage of being able to clear the input stream in case of too many characters or incorrect characters.
#include <stdio.h>
#include <string.h>
int main ( void) {
char input[3] = "";//can hold one char a newline and a '\0'
printf("Do you want to install this programme? y/n: ");
do {
printf ( "\nenter y or n\n:");
if ( fgets ( input, sizeof input, stdin)) {
if ( !strchr ( input, '\n')) {//is there a newline?
while ( !strchr ( input, '\n')) {//call until newline is found to clear input
if ( !fgets ( input, sizeof input, stdin)) {
fprintf ( stderr, "\nEOF problem\n");
return 1;
}
}
input[0] = 0;
printf ( "\ntoo many characters. try again.");
}
}
else {
fprintf ( stderr, "\nEOF problem\n");
return 1;
}
if ( input[0] == 'y' || input[0] == 'Y') {
printf("Installing...\n");
}
if ( input[0] == 'n' || input[0] == 'N') {
printf("Exiting programme!\n");
}
} while ( input[0] != 'y' && input[0] != 'n' && input[0] != 'Y' && input[0] != 'N');
return 0;
}
Solved!
This is the code that works. Thanks to #govindparmar.
#include <stdio.h>
int main() {
char yn;
do {
printf("Do you want to install this programme? y/n: ");
scanf(" %c", &yn);
}
while(yn != 'n' && yn != 'N' && yn != 'y' && yn != 'Y');
if(yn == 'n' || yn == 'N') {
printf("Exiting programe!\n");
}
else {
printf("Installing...\n");
}
printf("It works!\n");
return 0;
}

Infinite looping,c logical thinking

I'm facing a problem with what I enter with any unknown during the first time to the program. it will show me an infinite loop problem program closing. The program won't read the else statement.
char cont;
printf("Do u want continue\n");
scanf("%c", &cont);
getchar();
do
{
if (cont == 'y' || cont == 'Y')
{
selection();
}
else if (cont != 'n' || cont != 'N')
{
printf("Program Closing \n");
}
else
{
printf("Invalid Please Re-enter");
getchar();
scanf("%c", &cont);
}
} while (cont != 'n'&& cont != 'N');
let's dissect your code line by line starting with
scanf("%c", &cont);
This line would get a char value from stdin and put it into cont, which is a char so that's fine
getchar();
All I have to say for this is, why? it doesn't do anything useful, remove it.
Entering the loop now we have this statement
if (cont == 'y' || cont == 'Y')
this line is correct, it checks if the character is equal to y or Y
else if (cont != 'n' || cont != 'N')
this line is the main issue, your statement checks if cont is a value NOT equal to n or N, i.e. as a comment mentioned above, if the user put in the value a this line would return true, and then end the program. To correctly check if the user wants to exist you can use the same if statement used for y
if (cont == 'n' || cont == 'N')
if you replace the original if statement with this your program should work as expected. Just remember in the future that the != means not equal to, i.e. if the value is anything besides n or N return true. The == operator checks for equality as you saw above, so the line cont == 'n' means return true if cont is the same value as 'n'
printf("Invalid Please Re-enter");
getchar();
scanf("%c", &cont);
also as an extra note, please explain why you keep throwing in useless getchar()'s, those lines literally do nothing and you should remove them.

How to use loops in terms of input (in C language)?

I've been trying to get this code to work but the loop does not seem to work? I am very new to C and I sort of get confused with the syntax of this language. However my loop is not functioning like how I want it to be. I want the if and else statement to work but no matter what input (right or wrong) it always outputs "thank you".
#include <stdio.h>
#include <stdlib.h>
int confirm()
{
char c;
printf("Confirm (y/n): ");
scanf("%c", &c);
while (scanf("%c", &c))
{
if (c = 'Y' && 'y' && 'N' && 'n')
{
printf("\nthank you");
break;
}
else
{
printf("\nInput not recognised, try again. \n");
printf("\nConfirm (y/n): ");
scanf("%c", &c);
}
}
}
int main(int argc, char* agrv[])
{
confirm();
return 0;
}
it won't ask to enter another output when the output is incorrect. It just keeps ending from the if statement, thus the loop is not running?
Please help.
There's nothing wrong with your loop - it's the if statement that's wrong.
This code compiles, but it does not do what you want it to do:
if (c = 'Y' && 'y' && 'N' && 'n')
= is an assignment; you need == to do a comparison
&& means "AND"; you need ||, which means an "OR"
You combine logical expressions, not constants with && or ||
The condition should be
if (c == 'Y' || c == 'y' || c == 'N' || c == 'n')
Also note that when you read single characters with %c, your program "sees" all characters, including whitespace. This is a problem, because the '\n' left over in the buffer will be passed to your program before Y or N. To fix this, add a space before %c to your format string:
scanf(" %c", &c)
// ^
// |
// Here
Your code also ignores the first character that it reads. I think this is not intentional, so remove the call of scanf before the loop. You should also remove the second scanf from the loop, leaving the only call to scanf in the loop header.
int confirm()
{
char c;
printf("Confirm (y/n): ");
//scanf("%c", &c);// <---------- needless
while (scanf("%c", &c)) //<----while loop will do `scanf("%c",&c)`, so previous line should be remove.
{
if (c == 'Y' || c == 'y' || c == 'N' || c == 'n')// <- &&(AND); ||(OR). Also, be careful that don't be lazy, [c == 'Y' || 'y' || 'N' || 'n'] can't to communicate with computer
{
printf("\nthank you");
break;
}
else
{
printf("\nInput not recognised, try again. \n");
printf("\nConfirm (y/n): ");
scanf("%c", &c);
}
}
}

My while loop with char doesnt work. Some help please

So i have this peace of code:
int choice_dig;
char choice_dup;
printf("Welcome to the mystery number game.\n");
printf("How many digits do you want to use (3 to 5)?");
scanf("%d", &choice_dig);
while (choice_dig<3 || choice_dig>5)
{
printf("\nPlease choose a number between 3 and 5.\t");
scanf("%d",&choice_dig);
}
printf("\nDo you want to allow duplicate digits (y or n)?");
scanf(" %c", &choice_dup);
while (choice_dup != 'y' || choice_dup != 'n')
{
printf("\nInvalid entry. Please choose y for yes and n for no.\t");
choice_dup = getchar();
getchar();
}
The choice_dup is already assinged as a char var at the start of the main. So when i run this its all good. But even when i press y or n it cant recognize it and the loop never ends. No matter what i type. Can someone help me and expain to me what wrong?
The loop will run forever because while (choice_dup != 'y' || choice_dup != 'n') will always evaluate to true.
You probably wanted: while (choice_dup != 'y' && choice_dup != 'n')
should be this:
printf("\nDo you want to allow duplicate digits (y or n)?");
scanf(" %c", &choice_dup);
while (choice_dup != 'y' && choice_dup != 'n')
{
printf("\nInvalid entry. Please choose y for yes and n for no.\t");
choice_dup = getchar();
getchar();
}
Just use
while (choice_dup != 'y' && choice_dup != 'n') instead
In the last while loop,i.e the one for choice_dup,change it to:
while(!(choice_dup=='y'| choice_dup=='n'))

Resources