1

空白を処理するときの scanf の動作について混乱しています。

私が使用しているコードは次のとおりです。

int main()
{
  int val;
  int c;

  scanf("%d\t", &val);

  c = getchar();

  if(c == EOF)
    printf("eof");
  else if(c == '\t')
    printf("tab");
  else if(c == '\n')
    printf("newline");
}

そして、ここに私が渡している入力があります:

1234<tab><newline>

scanf はタブのみを探しており、おそらく scanf はデフォルトでバッファに空白を残すため、これは「改行」を出力することを期待しています。代わりに、「eof」を出力します。は%d\t改行を飲み込んでいるようです。

scanf の仕組みについて何か不足していますか?

次のように変更すると、「改行」が正しく出力されることに注意してください。

int main()
{
  int val;
  int c;

  scanf("%d", &val);

  getchar(); /* note this extra getchar */

  c = getchar();

  if(c == EOF)
    printf("eof");
  else if(c == '\t')
    printf("tab");
  else if(c == '\n')
    printf("newline");
}
4

3 に答える 3

3

パターン内の任意の量の空白 ( )は、入力内の任意の\t量の空白と一致します ( )。\t\n

マニュアルページから:

White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input.
于 2013-02-27T20:43:58.557 に答える
1

*scanf使用してはならない、より悪名高い理由の1つである、紛らわしい空白の処理に遭遇しました。単一'\t'のタブに一致するだけでなく、改行を含むあらゆる種類の空白に一致します。

あなたが持っていると仮定して、この種のことをするための最良の方法はgetline次のようになります:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char *line = 0;
    char *p;
    long val;

    (void) getline(&line, 0, stdin);

    val = strtol(line, &p, 10);
    if (*p == '\0')
        puts("eof (no tab)");
    else {
        if (*p != '\t')
            printf("no tab, %c instead\n", *p);
        p++;
        if (*p == '\0')
            puts("eof");
        else if (*p == '\t')
            puts("tab");
        else if (*p == '\n')
            puts("newline");
    }

    free(line);
    return 0;
}

持っていない場合はgetlinefgets多くの場合十分です。fgets(警告:。と混同しないでくださいgetsgets危険であり、決して使用しないでください。ただしfgets、入力行が非常に長い場合にプログラムを堅牢にしたい場合にのみ不便です。)

于 2013-02-27T20:48:33.493 に答える
0

「空白を処理するときの scanf の動作について混乱しています。」普遍的な主張です!

フォーマット文字列に空白がある場合、すべての空白が消費されるため、「\t」は空白の任意の文字列に一致します。

于 2013-02-27T20:45:21.673 に答える