4

コード:

#include <stdio.h>
int main(void) {
    char i[50];
    while(scanf("%s ", i)){
        printf("You've written: %s \n", i);
    }
    printf("you have finished writing\n");

    return 0;
}

1 つの問題は、コードが期待どおりに動作しないことです。入力した場合:

abc def ghi.

次のように出力されます。

You've written: abc
You've written: def

どうすれば修正できますか?目標は、「ENTER」または「.」に到達するまで、標準入力からすべての単語を読み取ることです。(ドット)。

4

4 に答える 4

5

@cnicutarはかなり近いですが、空白以外の場所から読み始めたいだけで、空白になったら1つの単語の読み取りを停止したいので、スキャンセットの場合は、おそらく次のようなものが必要です。

while(scanf(" %49[^ \t.\n]%*c", i)) {

この場合、最初のスペースは先頭の空白をスキップします。次に、スキャンセットは、スペース、タブ、改行、またはピリオドに到達するまで読み取ります。次に、%* cは次の文字(通常はスキャンを停止した文字)を読み取ります(ただし、破棄します)。

ただし、これにより、バッファの最後に到達したときに文字が破棄される可能性があるため、%cを使用して、代わりに読み込む文字を指定することをお勧めします。これにより、指定したバッファよりも長い1ワードから回復できます。

于 2012-04-13T21:02:27.237 に答える
4

どうですか:

scanf("%49[ ^\n.]", str)

またはそのようなもの。

于 2012-04-13T20:57:51.340 に答える
2

scanf完全に捨てて、次のようにしますfgets

while (fgets(i, sizeof i, stdin))
{
  printf("you've written: %s\n", i);
}

次の注意事項があります。

  1. ターゲット バッファに余裕がある場合はfgets、末尾の改行を入力の一部として格納します。

  2. を見つけたときに読み取りを停止したい場合は.、次のように、入力文字列でそれを探すロジックを追加する必要があります。


    int foundDot = 0;
    while (fgets(i, sizeof i, stdin) && !foundDot)
    { 
      char *dot = strchr(i, '.');
      char *newline = strchr(i, '\n');

      if (dot != NULL)
      {
        foundDot = 1;
        *dot = 0; // overwrite the '.' character with the 0 terminator
      }

      if (newline != NULL)
      {
        *newline = 0; // overwrite newline character with 0 terminator
      }

      /**
       * Assuming you don't want to print a blank line if you find a dot
       * all by itself. 
       */
      if (strlen(i) > 0) 
        printf("you've written: %s\n", i);
    }
于 2012-04-13T22:20:35.300 に答える
-1

これを行う最も簡単な方法は、flexを使用することです。そうしないと、困難で複雑な作業を繰り返すことになり、間違いを犯す可能性が高くなります。

また、 lex と yacc、第 2 版もお読みください。

于 2012-04-13T20:56:39.317 に答える