Вы как бы ответили на свой вопрос; вам нужно как-то справиться с символом новой строки.
Есть несколько вариантов. Если пункты меню пронумерованы, вы можете использовать scanf()
для считывания целочисленного значения и переключения на основе этого:
printf("Pick an option: ");
fflush(stdout);
scanf("%d", &option);
switch(option)
{
case 0 : do_something(); break;
case 1 : do_something_else(); break;
...
default: bad_option(); break;
}
Преимущество этой опции заключается в том, что спецификатор преобразования %d
пропускает все начальные пробелы, включая символы новой строки, поэтому вам не нужно беспокоиться о том, что какой-либо непрочитанный \n
засорит входной поток (фактически, большинство спецификаторов преобразования пропускают начальные пробелы). ; %c
нет, что делает его поведение очень похожим на getchar()
).
Недостаток этого варианта в том, что если кто-то введет нецифровой символ во входные данные, он не будет прочитан со спецификатором преобразования %d
и останется во входном потоке до вызова getchar()
или scanf()
со спецификатором преобразования. %s
или %c
спецификатор преобразования.
Лучшим вариантом является чтение всех входных данных в виде строк символов с использованием fgets()
, а затем их синтаксический анализ и проверка при необходимости.
/**
* Prints a prompt to stdout and reads an input response, writing
* the input value to option.
*
* @param prompt [in] - prompt written to stdout
* @param option [out] - option entered by user
*
* @return - 1 on success, 0 on failure. If return value is 0, then option
* is not changed.
*/
int getOption(const char *prompt, char *option)
{
char input[3]; // option char + newline + 0 terminator
int result = 0;
printf("%s: ", prompt);
fflush(stdout);
if (fgets(input, sizeof input, stdin))
{
/**
* Search for a newline character in the input buffer; if it's not
* present, then the user entered more characters than the input buffer
* can store. Reject the input, and continue to read from stdin until
* we see a newline character; that way we don't leave junk in the
* input stream to mess up a future read.
*/
char *newline = strchr(input, '\n');
if (!newline)
{
printf("Input string is too long and will be rejected\n");
/**
* Continue reading from stdin until we find the newline
* character
*/
while (!newline && fgets(input, sizeof input, stdin))
newline = strchr(input, '\n');
}
else
{
*option = input[0];
result = 1;
}
}
else
printf("Received error or EOF on read\n");
return result;
}
Да, это много работы, чтобы прочитать в одном глупом пункте меню, и это простая версия. Добро пожаловать в удивительный мир интерактивной обработки ввода на C.
person
John Bode
schedule
19.10.2010