web-dev-qa-db-ja.com

whileループでscanf関数を使用する

プログラミング割り当てのために、スペースで区切られたユーザー入力をフォーマットしようとしています。

基本的に、入力は任意の数の式で構成されます

L integer integer integer integerおよびC integer integer integer

例えば: L 1 1 5 7 C 4 5 3

これまでのところ、最初の文字に応じて整数を抽出することができ、scanf関数を使用して文字列を反復処理できます。

char a;
while(scanf("%c", &a) == 1){
    if(a == 'C'){
        int inputX, inputY, inputR;
        scanf("%d %d %d", &inputX, &inputY, &inputR);
        printf("%d %d %d\n", inputX, inputY, inputR);
    }
    else if(a == 'L'){
        int x1, y1, x2, y2;
        scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
        printf("%d %d %d %d\n", x1, y1, x2, y2);
    }
}

残念ながら、これは目的の整数を出力しますが、ループ(およびユーザー入力プロンプト)は終了しません。

誰かがなぜこれが起こっているのかについて私に教えてもらえますか?

4
Julian Laval

これは、scanf("%c", &a) == 1を常に真にするために\nが常に存在するためです。
変更する

while(scanf("%c", &a) == 1) 

while(scanf(" %c", &a) == 1)  
     //      ^space before format specifier.  

%cの前のスペースは、scanfによって残されたこの\nを使い果たします(を押すと Enter)。

15
haccks

その理由は、scanfが標準入力から直接読み取り、行を処理した後にユーザー入力をブロックして待機するためです。あなたがする必要があるのは、その行を読んで、whileループでその行を処理することです。以下のコードを変更しました。

char a;
char line[1024];

fgets(line, 1023, stdin);   // leave 1 character for null terminator
while(sscanf(line, "%c", &a) == 1){
    if(a == 'C'){
        int inputX, inputY, inputR;
        sscanf(line, "%d %d %d", &inputX, &inputY, &inputR);
        printf("%d %d %d\n", inputX, inputY, inputR);
    }
    else if(a == 'L'){
        int x1, y1, x2, y2;
        sscanf(line, "%d %d %d %d", &x1, &y1, &x2, &y2);
        printf("%d %d %d %d\n", x1, y1, x2, y2);
    }
}
3
T.V.

他の投稿のいくつかの機能といくつかの追加を組み合わせます。
fgets()内でsscanf()および_%n_を使用します。必ずsscanf()の結果を確認してください。

_char line[1024];
while (fgets(line, sizeof line, stdin) != NULL)) {
  char *s = line; 
  char Type;
  int n;
  while(sscanf(s, " %c%n", &Type, &n) == 1) {
    s += n;
    if(Type == 'C') {
      int inputX, inputY, inputR;
      if (3 != sscanf(s, "%d %d %d%n", &inputX, &inputY, &inputR, &n)) {
        Handle_Syntax_Error();
      }
      s += n;
      printf("%d %d %d\n", inputX, inputY, inputR);
    }
    else if(Type == 'L') {
      int x1, y1, x2, y2;
      if (4 != sscanf(s, "%d %d %d %d%n", &x1, &y1, &x2, &y2, &n)) {
        Handle_Syntax_Error();
      }
      s += n;
      printf("%d %d %d %d\n", x1, y1, x2, y2);
    }
    else {
      Handle_Syntax_Error();
    }
  }
} 
_