I'm trying to do this loop in C, where you would press enter and be in it and you either press 0 to exit or 3 to continue in it. But somehow the Switch commands are no being activated. Note that there is a different messages on each of them that is supposed to differentiate them from the other outcomes. Can someone help me understand the problem with this code?`Note: the code is obviously within int main().
int I = 1;
printf("Press enter to start the loop...");
getchar();
do
{
printf("\nYou are in a LOOP. Would you like to stay in it, or leave it? \nPress 0 to leave the loop or press 3 to stay in it: ");
scanf_s("%d", &I);
getchar();
switch (I)
{
case'3':
printf("\nYou are STILL inside the LOOP. Press 0 to leave it or press 3 to stay in it: ");
getchar();
break;
case'0':
printf("\nExiting the LOOP...");
break;
default:
printf("\nPlease, enter a valid command...: ");
if (scanf_s("%d", &I) != 3 || scanf_s("%d", &I) != 0);
{
fflush(stdin);
}
break;
}
while (I != 0);
printf("\nCongratulations! You are OUT of the LOOP!");
As others have pointed out, you are reading in an integer with scanf_s(), but comparing against a character literal inside the switch statement.
switch'3': should be written as switch 3: (using an integer literal instead). Same goes for the 0 case.
Also, your example is missing a curly brace } before while(I != 0);.
It is also worth mentioning that scanf_s() "returns the number of fields successfully converted and assigned" (from https://msdn.microsoft.com/en-us/library/w40768et.aspx). That is, your scanf_s() call in the default switch case will only ever return 0 or 1 when reading in a single integer (or EOF on error).
Related
I tried to calculate the tot(total fee) in the do-while loop, but all I get is tot=0.00?! Why is this happening? And after that I get a message: it said the variable fee is not being initialised?
#include<stdio.h>
int main(void)
{
int cofno;
float tot=0.0;
float fee;
char option;
do{
printf("Enter cofno: ");
scanf("%d",&cofno);
if(cofno>0)
{
printf("Key in (h/c): ");
scanf("%c",&option);
getchar();
switch(option)
{case 'h':fee=cofno*1.80;
break;
case 'c': fee=cofno*2.50;
break;
}
tot=tot+fee;
//the program will repeat until the user key in negative value or zero
}
}while(cofno>0);
printf("\ntot=RM%.2f \n\n",tot);
return 0;
}
scanf(" %c",&option); This will solve the problem for you. The reason the ' ' is provided in the scanf so that it can consume the white space characters.
What happened earlier was that your character input got the \n from previous input.
To check the thing that it inputted \n try outputting the option like this
printf("[%c]",option); you will see output
[
]
Also the break statement you provide is breaking for the case staement. Not the while loop. You have infinite loop now. You can solve this with a added condition.
...
tot=tot+fee;
if(option == 'c' || option =='h')
break;
...
Even more simply, you could have changed the while condition overall and make it like this
while(cofno<=0);
this conforms to your idea the program will repeat until the user key in negative value or zero more suitably.
Maybe there is no problem in running the first code
However,it will always default after I enter comment's data
char answer;
do{
printf("Do you want to add new comment?Y/N: ");
scanf("%c",&answer);
fflush(stdin);
switch(tolower(answer))
{
case 'y':
comment();
break;
case 'n':
main();
break;
default:
printf("Wrong choice !\n\n");
break;
}
}while(tolower(answer)!=='y'||'n');
there is the code of comment(),I guess the problem at here.
FILE*fp=fopen("comment.txt","a+");
if(fp == NULL)
{
printf("FIle not Found");
exit(1);
}
else
{
printf("Please enter your name: ");
gets(c.name);
printf("Pleas enter the date: ");
gets(c.date);
printf("Please enter the movie name: ");
gets(c.movie);
printf("Please enter your comment in 100 words:\n");
printf("Please press [Tab]and[Enter] to submit your comment\n");
scanf("%[^\t]",c.comment);
fprintf(fp,"%s %s\n%s\n%s\n\n",c.name,c.date,c.movie,c.comment);
}
fclose(fp);
Can someone help me?Thx!!
try using strlwr() instead of tolower()
Compiler gives you no error for while condition?
Maybe you want to write:
while(tolower(answer)!='y'||tolower(answer)!='n');
Inside do{}while you are reading input buffer which has a character you entered and a enter key. You need to clear that. Try scanf("%c%*c",&answer); .which will read that extra character from the buffer
A couple of problems in your code.
scanf("%c",&answer);
When you enter a character for the first time and if the character if either y or n then in next iteration this scanf() will read the stray \n (newline) character from the input buffer. To overcome this problem, add a space character before %, like this:
scanf(" %c",&answer);
Another problem is this statement:
while(tolower(answer)!=='y'||'n');
^^ ^
The compiler must be giving you both error and warning in this statement.
Change this to:
while(tolower(answer)=='y'||tolower(answer)=='n');
With this the loop to be run till user give input either y or n and for any other character, the loop will exit.
If you don't want loop to exit for any input character other then y or n but just print the message Wrong choice ! message then you can do:
}while(tolower(answer)!='y'||tolower(answer)!='n');
I'm completing an assignment and after completing it, I have 1 bug, and 1 bug fix I made that I don't fully understand. Currently, as long as the user does what is asked, everything works fine. But I know that doesn't happen often, so I'd love to know how to stop these issues.
Would love any advice - I am a complete beginner with C.
I found many different pieces of advice here: C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf
I added a space to my scanf() statements which solved some of the bugs - and I understand that \n is added onto the end of the entered strings / chars, I'm just not sure how to check for it / handle it, and I tried using getchar() in place of the scanf() but I still get double print / loop problems.
Bug Issue
When the user is running through the game loop, if they enter more than 1 character (for example: 'oo', when prompted with the scanf() to enter 'y' or 'n') my printf statements run 1x per character entered, and connect to each other:
Example would be:
Welcome to Two doors.
Would you like to play? (y/n):Welcome to Two doors.
Would you like to play? (y/n):
This issue also shows up if the user enters 'y' to play the game but then enters a character other than 1,2 or 3 in the second section.
How can I limit the length of their response? Or is the best way to monitor the length of the play and choice variables prior to entering the if statements? Maybe checking to see if they are longer than 1 character and if so, only taking the first character?
Second issue - bug fix that I don't understand
In the scanf() functions I ran into a very similar problem to what I described above, but it happened when the user entered any character. The solution I found was to add a space before the character ->
scanf(" %c", &play);
vs
scanf("%c", &play);
Is this issue only a problem when using loops? Since I never found these bugs prior to looping back through the code.
Updated Code with 'while (getchar() != '\n');' suggestion from Sourav Ghosh
#include <stdio.h>
int main(void) {
char play;
int choice;
char answer[] = "No matter which one you choose the guards both tell you which door leads to death, and therefore you can pick the other door.\n";
int gameLoop = 1;
int timesPlayed = 0;
while (gameLoop == 1){
if (timesPlayed == 0) {
printf("Welcome to Two doors.\n");
printf("Would you like to play? (y/n):");
} else {
printf("Would you like to play again? (y/n):");
}
scanf(" %c", &play);
while (getchar() != '\n');
if (play == 'y') {
// == instead of =
printf("\nYou are a prisoner in a room with 2 doors and 2 guards.\n");
printf("One of the doors will guide you to freedom and behind the other is a hangman --you don't know which is which.\n");
printf("One of the guards always tells the truth and the other always lies. You don't know which one is the truth-teller or the liar either.\n");
printf("You have to choose and open one of these doors, but you can only ask a single question to one of the guards.\n");
printf("What do you ask so you can pick the door to freedom?\n\n");
printf("\t1.Ask the truth-guard to point to the door of doom.\n");
printf("\t2.Ask the liar-guard to point to the door of doom.\n");
printf("\t3.Doesn't matter which one you pick.\n");
scanf(" %d", &choice);
while (getchar() != '\n');
switch (choice) {
case 1:
printf("%s", answer);
timesPlayed++;
break;
case 2:
printf("%s", answer);
timesPlayed++;
break;
case 3:
printf("%s", answer);
timesPlayed++;
break;
default:
printf("The Troll Smasher comes out from the shadows and squeezes the stupid out of you until you pop. GAME OVER!\n");
break;
}
} else if(play == 'n') {
printf("Sorry to hear that, we at Two Doors hope you have a super duper day!\n");
gameLoop = 0;
break;
} else {
printf("That is not a valid input, please try again by entering either 'y' to start the game or 'n' to quit the game.\n");
}
}
return 0;
}
The problem with %c format specifier is that, it will read only one byte from the input buffer and if the input buffer has more in store and the call in encountered next time, it will not ask for user input, it will simply read the next byte from the available input stream.
So, to answer
How can I limit the length of their response?
well, there's no straightway approach that you can stop the user from entering only X characters/ digits, instead, swipe off the excess, (if any) and for the next call, start with an empty buffer is an easy approach.
So, the quick way out of this would be, to clean off the standard input of remaining inputs. You can do something like
int retval = scanf(" %c", &play);
//some code
while (getchar() != '\n'); //eat up the input buffer
//next call to scanf(), input buffer is empty now....
to stop scanf() from reading already existing unwanted inputs and force it to ask the input from user.
Also, don't forget to check the return value of scanf() to ensure the success of the call.
For the first issue the problem is caused because the execution of the program enters the loop again for example if the user types oo that means that after reading with scanf it is going all the way to the last else.
Inside that else none of the variables is modified so when it reenters the loop gameLoop is still 1 and timesPlayed is still 0 so it will print the statements in the first if, then scanf will read the second o and repeat the process. The problem is that scanf reads one character at the time.
Actually for entering one character you can use getchar() but in any case after char input you should clean standard input stream. Consider the following example, that forces the user to the correct input:
char name[11];
char answer = 0;
printf("Would you like to play again? (y/n): ");
while ((answer = getchar()) != 'y' && answer != 'n')
{
printf("You should answer 'y' or 'n'\n");
// clean the buffer from mess
while (getchar() != '\n');
}
// clean the buffer from mess
while (getchar() != '\n');
// next input
printf("Enter your name: ");
scanf("%10s", name);
// clean the buffer from mess
while (getchar() != '\n');
UPDATE:
Just for clarification, the code
while ((answer = getchar()) != 'y' && answer != 'n')
{
printf("You should answer 'y' or 'n'\n");
// clean the buffer from mess
while (getchar() != '\n');
}
can be be easier to understand while rewritten as
char name[11];
char answer = 0;
printf("Would you like to play again? (y/n): ");
while (1) // infinit loop
{
answer = getchar();
// clean the buffer from mess (immideatly after reading)
while (getchar() != '\n');
if (answer == 'y' || answer == 'n') // check the input
break; // stop the loop if condition is true
// or ask again
printf("You should answer 'y' or 'n'\n");
}
// next input
printf("Enter your name: ");
scanf("%10s", name);
// clean the buffer from mess
while (getchar() != '\n');
in my first example I just optimize the code combining reading and checking the data in parentheses after while: (answer = getchar()) != 'y' is like two actions - answer = getchar() and then answer != 'y'
In the last snippet condition answer != 'y' && answer != 'n' was intentionally replaced with answer == 'y' || answer == 'n' to show difference between "do while data is incorrect" and "stop when correct data get"
This question already has answers here:
Skipping over Scanf statement in C
(4 answers)
Closed 8 years ago.
I am writing an objective c program for hangman. I need to replicate another program which has been given to me. I have done most of it, but am having an issue. It has to replicate the other program exactly, so I went into the other one and entered a character into the wordlength. It came up with the "number must be between 3 and 14 (inclusive)" statement, and asked me to enter a number again, but it started to loop infinitely. It works when i enter a number lower than 3 and larger than 14 (comes up with the error and asks for another input) but with a letter it infinitely loops. Also, the loop is meant to loop infinitely until the word length is larger than 3 and less than 14. That is why the while loop will loop infinitelyAny ideas??? Thanks
while (i == 0) {
printf("\n\n > Please enter a word length: ");
scanf("%i", &wordLength);
printf("\n\n");
if (wordLength > 3 && wordLength < 14) {
continue;
}
else printf("number must be between 3 and 14 (inclusive)");
}
The main problem (that you seem to be asking about) here is that you don't check for errors from the scanf call. It will return with the number of successfully scanned items, or zero if none were scanned, or EOF on error.
If scanf fails to extract data from the input, like when you ask for an integer but the user write a letter, then that letter will continue to be in the input buffer, so the next call to scanf will see that letter again. And again and again...
The best way to fix this is to read the whole line, as text, into a buffer, and then try to parse the integer from this buffer (using e.g. sscanf):
char input[16];
if (fgets(input, sizeof(input), stdin) == NULL)
{
printf("Error reading your input\n");
exit(0); /* Do whatever error handling you want */
}
if (sscanf(input, "%d", &wordLength) != 1)
{
printf("Error: Input was not a valid integer\nPlease try again: ");
fflush(stdout);
continue;
}
Problem is with while (i == 0){ you never change i in the loop. You may want to update it to
while (wordLength == 0){
But make sure you do wordLength=0 before the loop.
change the value of i for the loop to terminate. you dint change the value of i anywhere inside loop.
continue;
will not exit the loop, it will just skip the statement after continue statement and start the loop again. To exit the loop use
break;
so use break or change the value of i to some value other than i=0 to exit the loop.
I think you meant break instead of continue:
if (wordLength > 3 && wordLength < 14)
break;
break will take you out of the loop, whereas continue skips to the next iteration of the loop (which , as others have mentioned, never terminates because i is never changed)
Do not forget to break your loop when the condition is met.
while ( 1 ){
printf("\n\n > Please enter a word length: ");
scanf("%i", &wordLength);
printf("\n\n");
if (wordLength > 3 && wordLength < 14) {
break;
}
else printf("number must be between 3 and 14 (inclusive)");
}
I want to create a simple menu in C program that accepts single character. The menu will be like this:
[S]how
[E]xit
If the user enter '1','s' or 'S' the program will print "Hello" and prompt again for the input
else if the user enters '2',E or 'E' the program ends.
else it should print "invalid input" and prompt again.
I am able to create the program but the problem is that when user enters 12, 13, 14, 15, 16.....so on starting with 1, it shows Hello and same for other options.
My code is:
#include <stdio.h>
void clearBuffer();
int main() {
int i = 0;
char selection;
do
{
printf("\t1. [S]how\n");
printf("\t2. [E]xit\n");
printf("Enter your selection from the number or character noted above: ");
scanf("%s", &selection);
clearBuffer();
if (selection == '1' || selection == 's' || selection == 'S')
printf("Hello");
else if (selection == '2' || selection == 'E' || selection == 'x')
i = 0;
} while(i != 0);
}
void clearBuffer()
{
while(getchar() != '\n');
}
If you are going to receive only one character consider replacing the scanf() function for getchar() function:
printf("Enter your selection from the number or character noted above: ");
selection = getchar();
You could use strlen, which is part of the standard C library, to check the length of the string returned by scanf and reject entries longer than one character:
if (strlen(selection) > 1)
{
printf("Invalid selection.");
}
Alternatively, I think you could use getchar() to accept just a single character from the user, which means they wouldn't have to press enter.
As already mentioned, you should use getchar() if you only want one character. If you still want to use scanf() for whatever reason you may have, the correct format is "%c", not "%s".
I would also suggest that if you are looking for a single character, the if block looks a little "busy" (read, awkward) ... a switch would be a cleaner, more elegant way to do it (IMHO).
/* something like this ... */
switch ( selection ) {
case '1':
case 's':
case 'S':
printf ( "Hello\n" );
break;
case '2':
case 'e':
case 'E':
i = 0;
break;
}
Other couple of things ... if you don't care about the case of the character being read (that is, 's' and 'S' will do the same thing), you can convert selection to uppercase before your if-block or switch-block using toupper(). Also, and this is just a style suggestion, don't use i for your exit flag. General practice is to use things like i and j for counters or indexes - you could use something like quit_now or user_done which would convey more precisely what the variable means.