While loop causing many issues with program - c

void answerme();
int main() {
char *answer = malloc (MAX_NAME_SZ);
....
printf ("\nWould you like to begin? [Y/N]");
fgets (answer, MAX_NAME_SZ, stdin);
answerme();
if(*answer == 'y' || *answer == 'Y'){
getinfo();
printf("\nprogram starting now...");
}
else if(*answer == 'n' || *answer == 'N'){
printf("\nThank you, program will close now....");
return 0;
}
...
} //end of main
void answerme(){
char *answer = malloc (MAX_NAME_SZ);
while(*answer !='n' && *answer != 'N' && *answer != 'y' && *answer != 'Y'){
printf("\nPlease enter [Y], or [N]");
fgets (answer, MAX_NAME_SZ, stdin);
}
};
What the point of this while loop or the whole function is that for it to check if the user has answered the question with a y/n rather than another random key. I want this while loop to continue asking the user for a Y/N input until the user inputs it. However for some reason when this program is run, the first step asks you if you would like to begin the program, and if you do answer Y, it will for some reason tell you "please enter Y or N" even though you did enter the right answer, and then when you do enter for example "n" or even any other random letter it will still let you through. So it seems like it registers the input but for some reason it still asks runs the while loop instead of skipping to the if(answer == Y) or the if(answer ==N).
Does anyone know what could be the reason this is happening?
Also once the user says "Y" and begins the program there will be a message asking the user to input certain information and this information gets stored into a structure which I created (not shown in the code), however with this while loop, this somehow gets skipped. If I take off this while loop, the whole program works fine, but of course the user will be able to skip through steps of the program without strictly inputing what I've asked of him.
If there's any better alternative way of restricting the user into only inputing what I've asked, please do enlighten me on that as this has been causing me issues and headaches for the past 3 days. Thank you !

The problem is that you set a variable *answer in the function and there is another one in the main program. However, it looks like they are expected to be the same variable.
To fix this, declare only one and share it between the two functions. Do that by declaring it outside any function, or pass it from main to the subfunction. Note that it should be malloc() only once.
Example of the parameter passing technique is:
void answerme (char *answer)
{
while (*answer !='n' && *answer != 'N' &&
*answer != 'y' && *answer != 'Y')
{
printf ("\nPlease enter [Y], or [N]");
fgets (answer, MAX_NAME_SZ, stdin);
}
}
int main()
{
char *answer = malloc (MAX_NAME_SZ);
....
printf ("\nWould you like to begin? [Y/N]");
fgets (answer, MAX_NAME_SZ, stdin);
answerme(answer);
if (*answer == 'y' || *answer == 'Y')
{
getinfo();
printf("program starting now...\n");
}
else
if (*answer == 'n' || *answer == 'N')
{
printf("Thank you, program will close now.\n");
return 0;
}
...
} //end of main

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10
void answerme();
int main() {
char answer[SIZE]="0";
printf ("\nWould you like to begin? [Y/N]");
scanf(" %s",answer);
if((strcmp(answer,"y")==0) || (strcmp(answer,"Y")==0))
{
printf("Answer is y\n");
printf("\nprogram starting now...");
answerme();
}
else
{
printf("Wrong input..exiting\n");
exit(1);
}
return 0;
}
void answerme()
{
char answer[SIZE]="0";
do
{
printf("\nPlease enter [Y], or [N]");
scanf(" %s",answer);
printf("You entered %s\n",answer);
}while((strncmp(answer,"y",1)!=0) && (strncmp(answer,"Y",1)!=0) && (strncmp(answer,"n",1)!=0) && (strncmp(answer,"N",1)!=0));
}

Related

How to properly get a y/n input in C

So, I'm a C and programming newcomer and I'm trying to write a function to abstract y/n choices in a program that uses a lot of them, as of now I have it like this:
void chooser (char *choice)
{
while (1)
{
*choice='\0';
*choice=getchar();
while(getchar()!='\n');
if(*choice == 'y' || *choice == 'n')
break;
}
}
The second getchar consumes input in excess in the stdin so that it shouldn't be susceptible to the user typing gibberish.
The only problem is that if I type "ywhatever" or "nwhatever" the first getchar still captures "y" and "n" and passes it to the main.
I would like to have it so that the user has to type "y" or "n" and nothing else.
I could try ditching getchar and switching to fgets for capturing and sscanf for parsing, which is how I prefer to get strings, but, dunno, it's just a single character, I would prefer not to overcomplicate things.
Is there a way to scan stdin after user input to see if it contains more than one alphabetic character?
EDIT:
In the end, I went for this:
int chooser ()
{
char buffer[MAXIN];
while (1)
{
printf("y/n: ");
if (fgets(buffer, sizeof(buffer), stdin)!=NULL)
{
if (buffer[0] == 'y' || buffer[0] == 'n')
{
if (buffer[1]=='\n')
{
break;
}
else
{
while(getchar()!='\n');
}
}
}
}
if (buffer[0]=='y')
{
return 1;
}
if (buffer[0]=='n')
{
return 0;
}
}
It seems to be doing exactly what I need it to do, is there something else I should adjust? Does a fgets from the standard input need a if(fgets(...)!=NULL) check?
What's wrong with this solution:
#include <stdio.h>
void chooser(char *choice)
{
char buffer[200];
while (1)
{
fgets(buffer, sizeof(buffer), stdin);
if (buffer[0] == 'y' || buffer[0] == 'n')
break;
}
*choice = buffer[0];
}
int main(int argc, char **argv)
{
while (1)
{
char yn;
chooser(&yn);
if (yn == 'y' || yn == 'n')
printf("User choice: %c\n", yn);
}
}
That's not exactly "overcomplicated"
There is still room for improvement, e.g the EOF condition is not handled at all here.
Example of execution:
abc
def
y
User choice: y
n
User choice: n
yes
User choice: y
no
User choice: n
noooo
User choice: n

Can't clear the stdin using fflush(stdin), after using getchar(), in an infinite for loop C prog

I have just started off with C programming and while I was trying to write a programme to accept only y or n characters I came across that
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ch;
printf("Do you want to continue\n");
for (;;)
{
ch=getchar();
if (ch=='Y' || ch=='y')
{
printf("Sure!\n");
break;
}
else if (ch=='N'||ch=='n')
{
printf("Alright! All the best!\n");
break;
}
else
{
printf("You need to say either Yes/No\n");
fflush(stdin);
}
}
return(0);
}
When I run this code, and type in any other character other than Y/y or N/n, I receive the last printf statement (You need to say either Yes/No) as output twice.
I understand that this is happening because it considers enter, i.e, '\n' as another character.
Using fflush doesn't help as it's an infinite loop.
How else can I modify it so that the last statement is displayed only once?
You can use a loop to read any characters left using getchar():
ch=getchar();
int t;
while ( (t=getchar())!='\n' && t!=EOF );
The type of ch should int as getchar() returns an int. You should also check if ch is EOF.
fflush(stdin) is undefined behaviour per C standard. Though, it's defined for certain platforms/compilers such as Linux and MSVC, you should avoid it in any portable code.
Another option - use scanf ignoring white spaces.
Instead of ch=getchar();, just need scanf( " %c", &ch );
With this you can also get rid of fflush(stdin);
Like is said in my comment you should use int ch instead of char ch because the return type of getchar which is int.
To clean stdin you could do something like the following:
#include <stdio.h>
#include <stdlib.h>
int main(void){
int ch,cleanSTDIN;
printf("Do you want to continue\n");
for (;;)
{
ch = getchar();
while((cleanSTDIN = getchar()) != EOF && cleanSTDIN != '\n');
if (ch=='Y' || ch=='y')
{
printf("Sure!\n");
break;
}
else if (ch=='N'||ch=='n')
{
printf("Alright! All the best!\n");
break;
}
else
{
printf("You need to say either Yes/No\n");
}
}
return(0);
}
Any way a do while will probably do the job for you:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char ch;
int check;
do {
printf("Do you want to continue: ");
if ((scanf("%c",&ch)) == 1){
while((check=getchar()) != EOF && check != '\n');
if ((ch == 'y') || (ch == 'Y')){
printf("Alright! All the best!\n");
break;
} else if((ch == 'n') || (ch == 'N')){
printf("You choosed %c\n",ch);
break;
}else{
printf("You need to say either Yes/No\n");
}
}else{
printf("Error");
exit(1);
}
}while (1);
return 0;
}
Output1:
Do you want to continue: g
You need to say either Yes/No
Do you want to continue: y
Alright! All the best!
Output2:
Do you want to continue: n
You choosed n
Or we can simply use another break; statement after the last printf().

C getchar() doesn't wait for input/ conditional loop doesn't int

I am trying to add a feature to my C console application calculator that prompts the user to decide whether they want to perform another calculation using: y or n, but in testing, getchar() refuses to wait for input and the program proceeds as though it has received valid input. The following is a minimal example of the feature:
main()
{
char newCalculation;
do{
lengthFormula(); /* main calculation formula */
printf("Would you like to do another calculation? (Y/N)");
newCalculation = getchar();
}while(tolower( newCalculation ) == 'y');
if(tolower(newCalculation) == 'n'){
exitProgram(); /* exit the program */
}
while(tolower(newCalculation) != 'n' && tolower(newCalculation) != 'y'){
printf("This is not a valid response.\n Please enter \"Y\"
if you want to do another calculation,
or enter \"N\" to exit.\n");
newCalculation = getchar();
}
return 0;
}
When I run this, the program does not wait for input after:
Would you like to do another calculation? (Y/N)
, but instead proceeds as though it has received invalid input. The result is that it spits out the prompt and the invalid input notice one after the other without a space:
Would you like to do another calculation? (Y/N)
This is not a valid response.
Please enter \"Y\" if you want to do another calculation, or enter \"N\" to exit.
If I enter a "y" after this, main() returns 0 and the program terminates.
Is someone able to see where I went wrong here?
Why won't the console wait for input at getchar()?
Why does valid input terminate the program after the first invalid response?
P.S.: Please don't tell me to "read a book" or shoo me away to Dennis Ritchie or one of the previous SO discussions on input. I've been poring over Richie's discussion of I/O, as well as similar texts from Lynda.com and Wiley, and none of the previous "it won't wait for input" posts addresses my issue as far as I can tell.
#simplicisveritatis Here is the modification of your code that I tried. Still have the same getchar issues.
int main(void)
{
/* local variable declaration */
char newCalculation = 'y';
/* main function */
/*if(tolower( newCalculation ) == 'y')
{
lengthFormula(newCalculation);
}*/
do
{
lengthFormula();
printf("Would you like to do another calculation? (Y/N)");
newCalculation = getchar();
if( tolower( newCalculation ) == 'n' )
{
exitProgram();
}
while( tolower( newCalculation ) != 'n' && tolower( newCalculation ) != 'y' )
{
printf("This is not a valid response.\n Please enter \"Y\" if you want to do another calculation, or enter \"N\" to exit.\n");
newCalculation = getchar();
}
}while( tolower( newCalculation ) == 'y' );
return 0;
}
Your code has a lot of problems:
main should be:
int main(void){return 0;}
You need to cast getchar (read about getchar) and should be:
newCalculation = (char)getchar();
Your approach on do{}while; + while{} is also wrong used.
Try the following:
#include<stdio.h>
#include<stdlib.h>
int main(void){
int validate;
char menu_choice;
validate = 0;
do{
printf("Would you like another go?(y/n):\t" );
if(scanf(" %c", &menu_choice ) == 1){
if((menu_choice=='y') || (menu_choice=='Y')){
printf("You choosed Yes\n\n\n");
validate = 1;
}else if((menu_choice=='n') || (menu_choice=='N')){
printf("You choosed No\n\n\n");
validate = 2;
}else{
printf("Wrong Input.\n\n\n");
validate = 0;
}
}
}while( validate == 0 || validate == 1);
printf("Goodbye\n");
return 0;
}
Include your three cases: exit condition, wrong input and calculate within the while loop:
main(){
do{
printf("Would you like to do another calculation? (Y/N)");
// get input
char newCalculation;
newCalculation = getchar();
// exit condition
if(tolower(newCalculation) == 'n'){
exitProgram(); /* exit the program */
}
// wrong input condition
else if(tolower(newCalculation) != 'n' && tolower(newCalculation) != 'y'){
printf("This is not a valid response.\n Please enter \"Y\"
if you want to do another calculation,
or enter \"N\" to exit.\n");
// you should clear the input stream from the wrong input
}
else{
// calculate
lengthFormula();
}
}while(tolower(newCalculation) == 'y');
return 0;
}
Why won't the console wait for input at getchar()?
Most probably, your function lengthFormula() reads input (e. g. by using scanf() or whatever), but doesn't read the line ending character \n from the input buffer. Then after returning from lengthFormula(), the getchar() has to read remaining content from the input buffer rather than requesting fresh input.
Why does valid input terminate the program after the first invalid
response?
That's because your
while(tolower(newCalculation) != 'n' && tolower(newCalculation) != 'y')
does the same after a response of y as after a response of n - it leaves the loop and gets to the following
return 0;

C program crashes after char input [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am new to the C programming language and I've been trying to make a little text-based game in it. The input is very simple, as the user needs to input S or s and N or n.
The problem is, when I run the program and feed input to choice, the program simply stops working.
Here's the code:
/*O jogo */
#include <stdio.h>
#include "story.h"
int main() {
char choice;
puts(intro);
scanf("%c", &choice);
if (choice == 's' || choice == 'S') {
puts(dialog0);
puts(dialog1);
puts(dialog2);
puts(dialog3);
puts(dialog4);
puts(dialog5);
scanf(" %c", &choice);
if (choice == 's' || choice == 'S')
puts(dialog6option1);
else if (choice == 'n' || choice == 'N') {
puts(dialog6option2);
puts(dialog6option2pt2);
}
puts(dialog6);
puts(dialog7);
puts(dialog8);
puts(dialog9);
puts(dialog10);
scanf(" %c", &choice);
if (choice == 's' || choice == 'S') {
puts(dialog10option1);
puts(dialog10option1pt2);
} else if (choice == 'n' || choice == 'N') {
puts(dialog10option2);
puts(dialog10option2pt2);
}
}
return 0;
}
The program I compiled does not "stop working" (I filled in the missing strings). It simply exits when I enter 'n' at the first response, because, to summarise, it is like this.
int main() {
char choice;
puts(intro);
scanf("%c", &choice);
if (choice == 's' || choice == 'S') {
// ...
}
return 0;
}
So 'n' simply exits the program, otherwise when I start with 's' and then continue with 'n' or 's' I get the printed dialogs. Although as I commented above, what is supposed to happen when neither 'n' or 's' are entered?
BTW you have no prompts to help the user know what they are supposed to enter, or why.
The behavior of scanf is interesting especially when you include whitespace in the format string. When I wrote more console-oriented applications and wasn't using something like curses, I used a function like the following to read input:
char
get_next_input(void)
{
int ch;
while ((ch=getchar()) != EOF) {
if (!isspace(ch)) {
return (char)ch;
}
}
return (char)'\0';
}
It returns the next non-whitespace character in the stream or '\0' on EOF. I found it more reliable than using scanf across various implementations.
The problem that you are probably experiencing is line buffering on stdin. The call to scanf might not return until you press enter (e.g., enter a newline character).
You're missing a space within your first scanf:
...
puts(intro);
scanf(" %c", &choice); /* missing the space in your code*/
...

How to fix the running of my program in terms of conditional statements and output in C?

I have a problem with my input for my program:
#include <stdio.h>
#include <stdlib.h>
int confirm()
{
char c;
printf("Confirm (y/n): ");
scanf("%c", &c);
while (scanf("%c", &c))
{
if (c == 'Y' || c == 'y' || c == 'N' || c == 'n')
{
printf("\nThank you. \n");
break;
}
else
{
printf("\nInput not recognised, ry again. \n");
printf("Confirm (y/n): ");
}
}
}
int main(int argc, char* argv[])
{
confirm();
return 0;
}
When it executes, it asks the first question and inputting the answer is fine. However after entering the character (either y or n) the program prints the second question and stops. The whole program is not running. I don't know what I'm doing wrong.
Loose the first scanf at line 9 and (for me) it then seem to work correctly: if ynYN is entered then the confirm function exits, otherwise it continues looping

Resources