ループ内のメニューから選択するようにユーザーに求める簡単なプログラムを作成しようとしています。 getchar()を使用して入力を取得しますが、charを入力して「Enter」を押すと、プログラムが2つのループを作成することに気付きました(2回押したかのように)。1つは入力としてのcharで、もう1つは「Enter」用です。入力として。
これを修正するにはどうすればよいですか?
正規入力と非正規入力について読む必要があります。次のStackOverflowの質問は、これに対処します。
getchar()
は、入力バッファーの最初の文字を返し、それを入力バッファーから削除します。ただし、他の文字はまだ入力バッファーにあります(この例では_\n
_)。 getchar()
を再度呼び出す前に、入力バッファをクリアする必要があります。
_void clearInputBuffer() // works only if the input buffer is not empty
{
do
{
c = getchar();
} while (c != '\n' && c != EOF);
}
_
getchar()
:Pの後にgetchar()
を追加します
最も簡単な方法は、getchar
からの戻り値としてEnterキーを除外することです。
char c = (char)getchar();
if ( c != '\n' ) {
...
}
どうですか
#include <stdio.h>
/*! getline() reads one line from standard input and copies it to line array
* (but no more than max chars).
* It does not place the terminating \n in line array.
* Returns line length, or 0 for empty line, or EOF for end-of-file.
*/
int getline(char line[], int max)
{
int nch = 0;
int c;
max = max - 1; /* leave room for '\0' */
while ((c = getchar()) != EOF) {
if (c == '\n')
break;
if (nch < max) {
line[nch] = c;
nch = nch + 1;
}
}
if (c == EOF && nch == 0)
return EOF;
line[nch] = '\0';
return nch;
}
あなたはあなた自身の質問に答えました。なんとかして改行文字を処理する必要があります。
いくつかのオプションがあります。メニューオプションがnumberedの場合、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()
を使用してすべての入力を文字stringsとして読み取り、必要に応じて解析および検証することです。
_/**
* 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;
}
_
はい、それは1つの愚かなメニューオプションで読むのは大変な作業であり、それは単純なバージョンです。 Cでのインタラクティブな入力処理の素晴らしい世界へようこそ。