Reputation:
I'm building a long program requiring the typical "y/n" char function in an if/else statement, it works fine but if the user puts in something invalid, it will repeat my "Invalid answer" string equal to the number of characters they put in. I tried doing the "%1s" instead of %c but that doesn't stop runaway input.
#include<stdio.h>
int main()
{
printf("Welcome.I can predict the future\n"
"I learned this gift from someone in the future.\n"
"A bright creature with green eyes taught me how.\n"
"It appeared to me on a Sunday without enthusiam\n"
"and told me I would end up trapped in a computer,\n"
"and there was nothing I could do about it.\n"
"It was really cruel of it to do that.\n"
"I could have enjoyed the rest of my days\n"
"without being depressed having known that...\n"
"I also didn't need to know so many other things I\n"
"now have learned.\n\n"
"Having said this, would you like me to predict you\n"
"future?y/n\n");
char ansr;
scanf("%1s", &ansr);
while (ansr != 'y' && ansr != 'n'){
printf("Invalid answer, Please try again.");
scanf("%1s", &ansr);
}
if ( ansr == 'y') {
printf("You've been warned.\n\n");
}
else if ( ansr == 'n') {
printf("Goodbye Then.\n\n");
}
return 0;
}
Upvotes: 2
Views: 84
Reputation: 51
To handle strings in your input, you could try reading from stdin into your ansr
buffer as follows, and then do string comparisons. By throwing away the rest of the stuff in stdin
with %*[^\n]
the scan is not affected by whitespace or multiple characters, and you get the desired y/n
chars. Also don't forget your closing brace, and to return zero in main
.
#include <stdio.h>
#include <string.h>
#define buffLen 32
int main() {
char ansr[buffLen] = "";
printf("...would you like me to predict your future? (y/n) \n");
while (strcmp(ansr, "y") != 0 && strcmp(ansr, "n") != 0){
// Read the string, and throw away the rest up to the newline char.
scanf("%s%*[^\n]", &ansr);
if (strcmp(ansr, "y") == 0) {
printf("You've been warned.\n");
} else if (strcmp(ansr, "n") == 0) {
printf("Goodbye Then.\n");
} else {
printf("Invalid answer, Please try again.\n");
}
}
return 0;
}
EDIT: There was a good suggestion in the comments to use a do-while loop, to save us from initializing the buffer ansr
with dummy stuff, because the do
block initializes the buffer before the condition is evaluated. I like this because I rarely think to use these, but this is a great case of when to use one...
#include <stdio.h>
#include <string.h>
#define buffLen 32
int main() {
char ansr[strLen];
printf("...would you like me to predict your future? (y/n) \n");
do {
// Read the string, and throw away the rest up to the newline char.
scanf("%s%*[^\n]", &ansr);
if (strcmp(ansr, "y") == 0) {
printf("You've been warned.\n");
} else if (strcmp(ansr, "n") == 0) {
printf("Goodbye Then.\n");
} else {
printf("Invalid answer, Please try again.\n");
}
} while (strcmp(ansr, "y") != 0 && strcmp(ansr, "n") != 0);
return 0;
}
Upvotes: 0
Reputation: 223689
First, you don't want to use %1s
with a char
because this format specifier expects an array. After writing 1 character at the memory location of ansr
, it will write a null byte at the next memory location. This caused undefined behavior. Stick with using %c
.
To clear out the extra characters, you want to use getchar
in a loop to read characters until it finds a newline. That will flush the buffer out.
while (ansr != 'y' && ansr != 'n') {
printf("Invalid answer, Please try again.");
while ( getchar() != '\n');
scanf("%c", &ansr);
}
Output:
...
Having said this, would you like me to predict you
future?y/n
bogus
Invalid answer, Please try again.wrong
Invalid answer, Please try again.yep
You've been warned.
Upvotes: 1