C Programming yes no loop with error catcher - c

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

Related

Why isn't my while loop functioning properly?

My task is to exit the loop only if the user types "n" or "N".
Here is my code:
#include<stdio.h>
int main()
{
char alpha;
printf("This loop will repeat. Do you wnat to repeat? (Press n or N to exit). ");
scanf("%c", &alpha);
if(alpha != 'n' || alpha != 'N')
{
printf("Do you still want to repeat? (Press n or N to exit). ");
}
while(alpha != 'n' || alpha != 'N');
return 0;
}
The problem is my code is not looping at all.
Comments in code:
#include <stdio.h>
int main(void)
{
char alpha;
printf("This loop will repeat. Do you wnat to repeat? (Press n or N to exit). ");
// You need a "do" to start a block of code,
// otherwise the "while" loop runs forever
do
{
// Put a space before the format specifier to consume the trailing
// newline left by previous calls to scanf
scanf(" %c", &alpha);
// You want the "and" operator, not "or"
if(alpha != 'n' && alpha != 'N')
{
printf("Do you still want to repeat? (Press n or N to exit). ");
}
}
// Same here, you want the "and" operator, not "or"
while(alpha != 'n' && alpha != 'N');
return 0;
}
A better approach (test the condition only once and check the result of scanf):
#include <stdio.h>
int main(void)
{
char alpha;
printf("This loop will repeat. Do you wnat to repeat? (Press n or N to exit). ");
while (scanf(" %c", &alpha) == 1)
{
if(alpha != 'n' && alpha != 'N')
{
printf("Do you still want to repeat? (Press n or N to exit). ");
}
else break;
}
return 0;
}

Simple C program using If statement stops running in VS Code

I made a simple C program to understand the working of the If-Else statement but in VS Code the program stops at second input without any error prompt. Please tell me what's the problem with my program? I'm a beginner in programming.
#include <stdio.h>
int main(){
char math, sci;
printf("Have you passed Mathematics test (y/n)\n");
scanf("%c", &math);
printf("Have you passed Science test (y/n)\n");
scanf("%c", &sci);
if ((math == 'y') && (sci == 'y'))
{
printf("You get a gift of worth Rs. 45.");
}
else if ((math == 'n') && (sci == 'y'))
{
printf("You get a gift of worth Rs. 15.");
}
else if ((math == 'y') && (sci == 'n'))
{
printf("You get a gift of worth Rs. 15.");
}
else if ((math == 'n') && (sci == 'n'))
{
printf("You don't get any gift.");
}
return 0;
}
The second scanf() reads the newline that was left pending in stdin by the first scanf().
Use scanf(" %c", &sci); with an initial space in the conversion string to consume any newlines and initial white space in the input. Also test the return value of scanf() to detect premature end of file.
Here is modified version:
#include <stdio.h>
int main() {
char math, sci;
printf("Have you passed Mathematics test (y/n)\n");
if (scanf(" %c", &math) != 1) {
printf("Missing input\n");
return 1;
}
printf("Have you passed Science test (y/n)\n");
if (scanf(" %c", &sci) != 1) {
printf("Missing input\n");
return 1;
}
if ((math == 'y') && (sci == 'y')) {
printf("You get a gift of worth Rs. 45.\n");
} else
if ((math == 'n') && (sci == 'y')) {
printf("You get a gift of worth Rs. 15.\n");
} else
if ((math == 'y') && (sci == 'n')) {
printf("You get a gift of worth Rs. 15.\n");
} else
if ((math == 'n') && (sci == 'n')) {
printf("You don't get any gift.\n");
} else {
printf("Invalid input.\n");
}
return 0;
}
You just change
scanf("%c", &math) to scanf(" %c", &sci)
scanf("%c", &sci) to scanf(" %c", &math)
#include <stdio.h>
int main(){
char math, sci;
printf("Have you passed Mathematics test (y/n)\n");
scanf(" %c", &math);
printf("Have you passed Science test (y/n)\n");
scanf(" %c", &sci);
if ((math == 'y') && (sci == 'y'))
{
printf("You get a gift of worth Rs. 45.\n");
}
else if ((math == 'n') && (sci == 'y')||(math == 'y') && (sci == 'n'))
{
printf("You get a gift of worth Rs. 15.\n");
}
else if ((math == 'n') && (sci == 'n'))
{
printf("You don't get any gift.\n");
}
return 0;
}

How to restrict to a one letter input?

I realised that if the input is a word starting with 'y' or 'n', it will escape the loop. How can I restrict the loop such that it will continue looping unless the input is a single character?
do
{
printf("Do you want to try again? (Y/N): ");
fflush(stdin);
scanf("%c", &repeat);
repeat = toupper(repeat);
if (repeat != 'Y' && repeat != 'N')
printf("Invalid answer. Please enter 'Y' or 'N'.\n\n");
} while (repeat != 'N' && repeat != 'Y');
like this:
#include <stdio.h>
#include <ctype.h>
int main(void){
char repeat[3] = {0};//3 : one character + one character + NUL
do{
printf("Do you want to try again? (Y/N): ");fflush(stdout);
if(EOF==scanf("%2s", repeat)){ *repeat = 'N'; break; }
*repeat = toupper(*repeat);
if (repeat[1] || *repeat != 'Y' && *repeat != 'N'){//repeat[1] != '\0'..
printf("Invalid answer. Please enter 'Y' or 'N'.\n\n");
scanf("%*[^\n]");scanf("%*c");//clear upto newline
*repeat = 0;
}
} while (*repeat != 'N' && *repeat != 'Y');
puts("Bye!");//try agein or see ya, bye
return 0;
}
First fflush(stdin); does not make sense except in Microsoft's world.
Then, the scanf family function returns a value which is the number of input token successfully decoded and that return value should always be controlled. And %c should be used with caution because it can return a blank character (space or newline) remaining in buffer while %s only return printable characters. With those remarks you code could become:
repeat = '\0';
do
{
char dummy[2], inp[2];
printf("Do you want to try again? (Y/N): ");
// fflush(stdin);
if (1 == scanf("%1s%1s", inp,dummy) repeat = toupper(inp[0]);
if (repeat != 'Y' && repeat != 'N')
printf("Invalid answer. Please enter 'Y' or 'N'.\n\n");
} while (repeat != 'N' && repeat != 'Y');
Alternatively to using scanf() one can use fgets() to read a line and then do the parsing one self:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char repeat = '\0';
do
{
int input_valid = 0; /* Be pessimistic. */
char line[3] = {0};
puts("Do you want to try again? (Y/N):");
do /* On-time loop, to break out on parsing error. */
{
if (NULL == fgets(line, sizeof line, stdin))
{
break; /* Either fgets() failed or EOF was read. Start over ... */
}
if (line[1] != '\0' && line[1] != '\n')
{
break; /* There was more then one character read. Start over ... */
}
line[0] = toupper(line[0]);
if (line[0] != 'Y' && line[0] != 'N')
{
break; /* Something else but Y or N was read. Start over ... */
}
input_valid = 1;
} while (0);
if (input_valid == 0)
{
int c;
do /* Flush rest of input. if any. */
{
c = getc(stdin);
} while (EOF != c && '\n' != c);
fprintf(stderr, "Invalid answer. Please enter 'Y' or 'N'.\n\n");
}
else
{
repeat = line[0];
}
} while ('\0' == repeat);
printf("The user entered: '%c'\n", repeat); /* Will only print either Y or N. */
return EXIT_SUCCESS;
}

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

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