I can't seem to get my keyboard to accept input and I'm not sure why. I have flushed the buffer (or so I think I did) and all I'm getting is BCS.
This is my menu function
//Menu
int menu() {
int choice;
do {
printf("1)Move\n2)Display Maze\n3)Peek ahead\n");
scanf("%i", &choice);
while(getchar() != '\n');
} while(choice<=0 && choice>3);
return choice;
}//end menu
This is in my main. I print the maze out first and then display the menu
printMaze(maze);
do
{
choice = menu();
if(choice == 1)
{
//direction = readDirection();
//move(maze, direction);
printf("Hi\n");
}// end choice
else if(choice ==2)
//displayMaze(maze);
printf("Hello\n");
else
//peek(maze);
printf("Goodbye\n");
} while(choice!=4);//hag doesn't kill me or i find the exit)
What operating system are you using.., if you are windows version of try reinstalling turbo c++ compiler and re-configuring the "TC" directories.
I'm not very up on C but....
Shouldn't you be scanning for INPUT "INSIDE" the While Loop??
while(getchar() != '\n');
scanf("%i", &choice);
}while(choice<=0 && choice>3);
choice<=0 && choice>3 -> choice<=0 || choice>3
and
choice!=4 // 1 <= choice <= 3, never choice == 4
Related
int login_user()
{
wrong:
printf("-------------Login-------------\n");
int loop,dev;
char usernmcmpr[30],pswdcmpr[4],loginchoice,test[30];
printf("Username:");
scanf(" %s",&usernmcmpr);
printf("Password:");
scanf(" %s", &pswdcmpr);
printf("1. %s\n",username);
printf("2. %s",usernmcmpr);
if(strcmp(password,pswdcmpr) == 0 && strcmp(username,usernmcmpr) == 0)
{
system("cls");
printf("-------------Main Menu-------------\n");
printf("a.Calculate Cost\nb.Payment\nc.Recepit\nd.Exit\n");
scanf(" %c", &loginchoice);
if (loginchoice == 'a')
{
system("cls");
calculate_cost();
}
else if (loginchoice == 'b')
{
system("cls");
payment();
}
else if (loginchoice == 'c')
{
system("cls");
receipt();
}
else if (loginchoice == 'd')
{
keep_Looping = 1;
system("cls");
}
else
{
system("cls");
printf("-------------Error-------------\n");
printf("Invalid input please try again\n");
goto wrong;
clear();
}
}
else
{
goto wrong;
}
return 0;
}
It used to work and then all of a sudden it stopped, don't know why i didn't even change the code in this function nor did i change anything related to it. Really can't tell what is wrong.
usernmcmpr is a char array which is basically a char* under the hood. Since usernmcmpr is already a pointer you want scanf(" %s", usernmcmpr); instead of scanf(" %s",&usernmcmpr);. Same for your other char arrays.
Furthermore, you should be more cautious about buffer overflow problems as currently the user can enter more than your arrays can hold. See How to prevent scanf causing a buffer overflow in 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));
}
I am new in this world of programming. I am learning programming at my school. My teacher recently ask the class to create a menu with limited selection that will end with a sentinel value.
So here's my coding:
#include <stdio.h>
void menu(void);
void choice1();
void choice2();
void choice3();
char choice;
int main() {
do {
menu();
if (choice =='1')
choice1();
else if (choice =='2')
choice2();
else if (choice =='3')
choice3();
else if (choice =='4')
break;
else
printf("Invalid character.");
} while (choice != '4');
return 0;
}
void menu(void) {
printf("\nMenu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("3) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
scanf("%c", &choice);
}
void choice1() {
printf("\nChoice 1\n");
}
void choice2() {
printf("\nChoice 2\n");
}
void choice3() {
printf("\nChoice 3\n");
}
When I try to run it, by putting the number 1, 2, 3, the output came out but after that the function menu() and also the line "Invalid character." came out. As for as the other character, the menu() and the "Invalid character" came out twice. Number 4 does end the program. Is there any improvement that I can make to make sure the menu() and the line "Invalid character." does not come out unnecessarily?
In line-buffered input, the newline character lingers in the buffer after you read a single character for 'choice' and hence you get Invalid character. unintentionally.
You are required clear the buffer after reading the choice
scanf("%c", &choice);
while(getchar()!='\n')
/* Wasting the buffer
* Hence ensuring that the character you enter
* is indeed considered for 'choice'
*/
;; // Do nothing in particular
As a side note, your program looks like a typical use-case for the switch-case command and maybe your teacher expects you to use it.
Considering the scenario mentioned by #chqrlie in [ this ] comment, the workaround is to add after
scanf("%c", &choice);
the below lines
int c;
while ((c = getchar()) != EOF && c != '\n')
;; //Wasting the buffer
The problem is simple: the terminal is line buffered: you must press enter for the input to become available to your program, the first scanf("%c", &choice) retrieves the character typed and the second call retrieves the linefeed ('\n') that was generated by the enter key.
There are multiple ways to avoid this problem. You can add a space in the scanf format before the %c: scanf(" %c", &choice); or you can read characters after the first until you get a '\n'.
Note that you must check the return value of scanf to avoid undefined behavior if the user enters an end of file. It is also advisable to avoid global variables: the function menu() should return the choice specified. Using a switch statement is also more idiomatic for this.
Here is a corrected version:
#include <stdio.h>
int menu(void);
void choice1(void);
void choice2(void);
void choice3(void);
int main(void) {
int ch;
for (;;) {
switch (ch = menu()) {
case '1': choice1(); continue;
case '2': choice2(); continue;
case '3': choice3(); continue;
case '4':
case EOF: break;
default: printf("Invalid character %c\n", ch); continue;
}
break;
}
return 0;
}
int menu(void) {
char choice;
printf("\nMenu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("3) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
if (scanf(" %c", &choice) == 1)
return choice;
else
return EOF;
}
void choice1(void) {
printf("\nChoice 1\n");
}
void choice2(void) {
printf("\nChoice 2\n");
}
void choice3(void) {
printf("\nChoice 3\n");
}
As already mentioned in other answers the problem is the newline character.
When you press 1 followed by enter, you'll get two chars, i.e. 1 and \n. So your loop runs twice and prints Invalid character when \n is processed.
Here is an alternative solution for your problem. Just add a space before %c.
scanf(" %c", &choice);
This works because the space will match any number of white-space characters and thereby match the \n and remove it.
From the man page:
A sequence of white-space characters (space, tab, newline,
etc.......). This directive matches any amount of
white space, including none, in the input.
Additional comments
You should always check the value returned by scanf to make sure you read the correct number of values.
if (scanf(" %c", &choice) != 1)
{
// Add error handling ....
// For instance you could terminate the program like
exit(1);
}
In your program choice is a global variable. In general global variables should be avoid if possible. In your case you could make choice a local variable in main and let menu return a char. Like:
// char choice; Remove global variable
int main() {
char choice; // Add local variable
do {
choice = menu(); // Assign to local variable
.....
}
char menu(void) { // Make the function return a char
char choice; // Add local variable
printf("\nMenu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("3) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
if (scanf("%c", &choice) != 1) exit(1); // Assign to local variable
// On failure -> exit
return choice; // Return value of local variable
}
You can write scanf(" %c",&choice); (with whitespace) instead of scanf("%c",&choice);
When I try to run it, by putting the number 1, 2, 3, the output came
out but after that the function menu() and also the line "Invalid
character." came out.
It's happening because of the new line character you press after each number. It's itself a character and loop is iterated one more time for this. As it is an invalid character, that's why "Invalid character." is showing.
Try using getchar() after scanf().
Edit: fixed my previous while loop which may exit incorrectedly:
#include <stdio.h>
int main() {
int choice;
printf("Menu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("2) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
while (1) {
char c = scanf("%d",&choice);
if (c == EOF || choice == 4) break;
if (choice == 1 || choice == 2 || choice == 3) {
printf("Choice %d.\n", choice);
} else {
printf("Invalid character.\n");
}
}
return 0;
}
You can use function if you want, but not necessary in this case. You need to understand how many times your loop actually runs and compare it to that you expect.
My previous code:
#include <stdio.h>
int main() {
int choice;
printf("Menu:\n\n");
printf("1) Choice 1.\n");
printf("2) Choice 2.\n");
printf("2) Choice 3.\n");
printf("Choose any of the above, or enter 4 to quit.\n\n");
while (scanf("%d", &choice) && choice != 4) {
if (choice == 1 || choice == 2 || choice == 3) {
printf("Choice %d.\n", choice);
} else {
printf("Invalid character.\n");
}
}
return 0;
}
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().
I'm working on a console application which is supposed to have a little menu to choose from different options. I came up with two ideas, in one of which I used int to be a choice variable and it gets me into an infinite loop whenever I enter a character other than numeric. Another one though seems clearer to me but I can't understand why I get "Choose an option Not a digitChoose an option" message even if I choose a valid theoretically option Please let me know what's the problem with my code. I enclose the second example I mentioned.
#include <stdio.h>
#include <ctype.h>
void F1()
{
printf("Function 1\n");
}
void F2()
{
printf("Function 2\n");
}
void F3()
{
printf("Function 3\n");
}
int main()
{
char c;
printf("MAIN MENU\n"
"1. Function 1\n"
"2. Function 2\n"
"3. Function 3\n"
"4. Exit\n");
while(1)
{
printf("Choose an option ");
scanf("%c", &c);
if(isdigit(c) == 0) printf("Not a digit");
else
{
if(c == '1') F1();
else if(c == '2') F2();
else if(c == '3') F3();
else if(c == '4') break;
else printf("Wrong option");
}
}
return 0;
}
You need to flush your input buffer to clear the \n character leftr behind by previous call of scanf. Place a space before %c in scanf
scanf(" %c", &c);
or in general you flush input buffer by placing this snippet after each call of scanf:
int c
while((c = getchar()) != '\n' && c != EOF);
The first call to scanf() will real your typed character, and the second one will read a newline character.
You need to finish reading the line after your call to scanf():
int c2;
while((c2=getchar()) != '\n' && c2 !=EOF) {}