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

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);
}
}
}

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!)

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.

C: scanf input single character and validation

I've encountered a problem when validating a single-char scanf input in C and I cannot find an existing solution that works...
The scenario is: a method is taking a single letter 'char' type input and then validating this input, if the criteria is not met, then pops an error message and re-enter, otherwise return this character value.
my code is:
char GetStuff(void)
{
char c;
scanf("%c", &c);
while(c != 'A' || c != 'P')
{
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &dtChar);
}
return c;
}
however, i got the infinite loop of error message no matter what input I type in. I read some other posts and guess it's the problem that %c specifier does no automatically get rid of the newline when I hit enter, and so far I have tried:
putting a white space before/after %c like:
scanf(" %c", &c);
write a separate method or include in this GetStuff method to clean the newline like:
void cleanBuffer(){
int n;
while((n = getchar()) != EOF && n != '\n' );
}
Can anyone help me with this problem please? Thank you in advance.
Please consider the following snippet:
#include <stdio.h>
#include <ctype.h>
char GetStuff(void)
{
char c;
do {
printf("Please enter A for AM or P for PM: ");
scanf ("%c", &c);
// clean input buffer (till the end of line)
while(getchar()!='\n');
} while(toupper(c) != 'A' && toupper(c) != 'P');
return c;
}
int main(void)
{
printf("Your input is'%c'\n", GetStuff());
return 0;
}
Note the points:
condition while(c != 'A' || c != 'P') will be always true (just because one character cannot be 'A' and 'P' at the same time), so use while(c != 'A' && c != 'P') instead
No need for two scanf if you use do..while loop
After entering a char with scanf it is recommended to clean all characters from buffer, e.g. with while(getchar()!='\n'); (this will clean all input including incorrect and redundant characters)
use toupper to avoid making 4 comparison (actually single c=toupper(c) inside loop can minimize your while as while(c != 'A' && c != 'P') )
UPDATE:
To add message "Invalid input" and adding some other useful improvement subjected befor... new code is as:
#include <stdio.h>
#include <ctype.h>
void CleanBuffer(){
int n;
while((n = getchar()) != EOF && n != '\n' );
}
char GetStuff(void)
{
char c;
do {
printf("Please enter A for AM or P for PM: ");
scanf (" %c", &c);
c = toupper(c); // here letter become uppercase
CleanBuffer();
} while( (c != 'A' && c != 'P')?printf("Invalid input! "):0 );
return c;
}
int main(void)
{
printf("You have entered: %c\n", GetStuff());
return 0;
}
Note: function will return 'A' or 'P' in uppercase, so if this is not needed change the code as in example before update (use two toupper and do not change c after scanf). Also you can use tolower as an option (of course with comparing to 'a' and 'p').
#include <stdio.h>
char GetStuff(void) {
char c;
scanf("%c", &c);
getchar();
while ((c != 'A') && (c != 'a') && (c != 'P') && (c != 'p')) {
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &c);
getchar();
}
return c;
}
int main(void) {
printf("Calling GetStuff()...\n");
char x = GetStuff();
printf("User entered %c\n", x);
return 0;
}
You are using while (c != 'A' || c != 'P') as your loop conditional, but this will always return true. What you meant to use is the && "and" operator, instead of the || "or" operator.
Also, call getchar() after your scanf statements, to capture the newline. This should work the way you want it to.
Inside loop you are taking input in dtChar but your loop condition checks variable c which is not updated in the loop, that is causing infinite loop
Also you would change your condition
while(c != 'A' || c != 'P')
to
while(c != 'A' && c != 'P')
If you want user to enter either 'A' or 'P'
Another possible solution. As others mentioned the condition was to be done with &&. Anyway the big problem is how to remove what's left on the console input line. Since the console works by lines, we remove everything up to the next '\n'. If the user already left something on the input line before calling GetStuff(), it would be useful to add a call to SkipRestOfTheLine() before the while loop.
In general I suggest to start with a while(1) loop, before making it nicer (such as in the cleanBuffer() you posted).
#include <stdlib.h>
#include <stdio.h>
void SkipRestOfTheLine(void)
{
while (1) {
int c = fgetc(stdin);
if (c == EOF || c == '\n')
break;
}
}
char GetStuff(void)
{
while (1) {
int c = fgetc(stdin);
if (c == EOF)
exit(EXIT_FAILURE); // Deal with this case in an appropriate way
if (c == 'A' || c == 'P')
return c;
printf("invalid input, enter again (A for AM or P for PM): ");
SkipRestOfTheLine();
}
}
int main(void)
{
char c = GetStuff();
return 0;
}
try this,
char GetStuff(void)
{
char c;
scanf("%c", &c);
while (((c != 'A') || (c != 'a')) && ((c != 'P') || (c != 'p'))==1)
{
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &dtChar);
}
return c;
}
I hope this works, some time because of not given proper bracket it is stuck in the loop.
#include <stdio.h>
int main(){
char c;
do{
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%s", &c);
}while ((c != 'A') && (c != 'P'));
return 0;
}

Error Checking In C

I'm not as advance in C as yet so I'd need help with few problems. 1. Let's say I want to enter character (y or n) and I don't want anything else other than that character, so I'll use a while loop to until its entered. I can't get it working, here's my code. It compiles and run but it won't carry out what I want, if I enter y it continues to loop likewise n
printf("Enter code(y/n): \n");
scanf(" %c", &code);
while (code != 'y' || 'n' ){
printf("Try Again: \n");
scanf(" %c", &code);
}
REPLACE
while (code != 'y' || 'n' ){ <-- condition evaluates always to TRUE
WITH
while ((code != 'y' )&&(code != 'n')){
The line you have
while (code != 'y' || 'n' ){
is equivalent to:
while ((code != 'y') || 'n' ){
which evaluates to true all the time.
The logic you need is:
while (code != 'y' && code != 'n' ){

Scanf() does not recognize space before %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;
}

Resources