I wrote a test program, in this progtam there is a menu function, which allows user to choose a thing he wants to do. And there is a thing, if he chooses a task, where function gets_s
is located and when, for example, user wants a task 2, he writes 2 and then presses "enter" and then the function gets_s
thinks that this "enter" is for it and then my program finishes.
#include <stdio.h>
void test()
{
char str[25];
gets_s(str, 24);
printf("%s\n", str);
}
int menu()
{
int choice;
printf("Choose a task\n1 - task 1\n else...\n");
scanf_s("%d", &choice);
return choice;
}
int main(void)
{
int x;
x = menu();
if (x == 1)
test();
}
You can try this program and see that after your input 1, the program will finish. I don't understand why this happens, how can i do it without finishing the program?
User input is significantly more difficult than people generally to think it is (or ought to be).
I personally find that a little helper function works, such as one to get an integer from the user. Here is one such way:
int ask_integer( const char * prompt )
{
// Prompt the user for input
if (prompt)
printf( "%s", prompt );
// Get user’s answer as a string ending with ENTER key press
char s[100];
if (!fgets( s, sizeof(s), stdin ))
complain_and_quit();
char * first = skipws( s ); // (skip over any leading whitespace)
if (!*first) complain_and_quit(); // (nothing but whitespace == error)
char * last = strchr( first, '\n' ); // (find the newline/ENTER)
if (!last) complain_and_quit(); // (not found == line too long == error)
*last = '\0'; // (strip the newline)
// Convert user’s input to an integer, if possible
errno = 0;
long n = strtol( first, &last, 10 );
if (errno or (n < INT_MIN) or (n > INT_MAX))
complain_and_quit(); // (out of range == error)
last = skipws( last ); // (skip over any trailing whitespace)
if (*last) complain_and_quit(); // (fail if input not JUST an integer)
return n;
}
With
char * skipws( char * s )
{
while (isspace( (unsigned char)(*s) )) ++s;
return s;
}
Notice that there are a lot of things to check just to get an integer. Yes, it is obnoxious.
The method you use to handle errors is up to you. For most schoolwork assignments, any variation of a simple “complain and quit” is sufficient.
Notice the pattern:
The using code is now much simpler:
int menu(void)
{
return ask_integer(
"Menu:\n"
" 1 - Quux\n"
" 2 - Frob\n"
" ...\n"
"? " );
}
int main(void)
{
switch (menu())
{
case 1: test(); break;
...
}
return 0;
}
Or, using if
:
int main(void)
{
int choice = menu();
if (choice == 1)
test();
else if (...)
...;
else
...;
return 0;
}