10

ユーザーにループ内のメニューから選択するように求める簡単なプログラムを作成しようとしています。getchar() を使用して入力を取得しますが、文字を入力して「Enter」を押すと、プログラムが 2 つのループを作成することに気付きました (2 回押したかのように)。入力として。

これを修正するにはどうすればよいですか?

4

5 に答える 5

4

getchar()入力バッファの最初の文字を返し、入力バッファから削除します。ただし、他の文字はまだ入力バッファー\nにあります(例では)。getchar()再度呼び出す前に、入力バッファーをクリアする必要があります。

void clearInputBuffer() // works only if the input buffer is not empty
{
    do 
    {
        c = getchar();
    } while (c != '\n' && c != EOF);
}
于 2010-10-19T15:31:05.230 に答える
3

最も簡単な方法は、Enter キーを戻り値として除外することです。getchar

char c = (char)getchar();
if ( c != '\n' ) {
  ...
}
于 2010-10-19T15:17:05.233 に答える
2

:Pのgetchar()後に a を追加しますgetchar()

于 2010-10-19T15:16:50.210 に答える
1

あなたはあなた自身の質問に答えました。なんとかして改行文字を処理する必要があります。

いくつかのオプションがあります。メニューオプションに番号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を心配する必要がないことです(実際、ほとんどの変換指定子は先頭の空白をスキップします。 't、それを)のように動作させる。 \n%cgetchar()

このオプションの欠点は、誰かが入力で数字以外の文字を太くした場合、変換指定子で読み取られず、または変換指定子を%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;
}

はい、それは1つのばかげたメニューオプションで読むのは大変な作業であり、それは単純なバージョンです。Cでのインタラクティブな入力処理の素晴らしい世界へようこそ。

于 2010-10-19T15:58:08.793 に答える
1

どうですか

#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;
}

ソース

于 2010-10-19T15:16:28.987 に答える