1

次のように、コンマを購入して区切られた標準入力のアイテムのリストを期待しているとしましょう。

 item1, item2, item3,...,itemn

また、ユーザーがアイテムとコンマの間に空白を入れることを許可したいので、この種の入力は私のプログラムでは合法です。

item1,item2,item3,...,itemn

私がこのように使用する場合scanf

scanf("%s,%s,%s,%s,...,%s", s1, s2, s3, s4,...,sn);

入力全体を1つの文字列として参照するため、空白がない場合(テスト済み)は失敗します。では、C標準ライブラリ関数だけでこの問題を解決するにはどうすればよいでしょうか。

4

3 に答える 3

8

簡単な答えは、ユーザー入力を読み取るためにscanfを使用することは決してありません。これは、ファイルから厳密にフォーマットされた入力を読み取ることを目的としており、それでもあまり良くありません。少なくとも、行全体を読み取ってから、sscanf()を使用してそれらを解析する必要があります。これにより、エラーを修正する機会が得られます。せいぜい、独自の解析関数を作成する必要があります

実際にC++を使用している場合は、はるかに強力で安全なc++文字列クラスとストリームクラスの使用を調べてください。

于 2009-07-12T20:02:21.987 に答える
7

あなたはを見ることができますstrtok。最初に行をバッファに読み込み、次にトークン化します。

const int BUFFERSIZE = 32768;
char buffer[BUFFERSIZE];
fgets(buffer, sizeof(buffer), stdin);

const char* delimiters = " ,\n";
char* p = strtok(buffer, delimiters);
while (p != NULL)
{
  printf("%s\n", pch);
  p = strtok(NULL, delimiters);
}

ただし、再入可能性に関連する潜在的な問題strtokに注意する必要があります。

于 2009-07-12T19:59:12.710 に答える
2

これについては、独自の解析関数を作成する方がよいと思います。ただし、落とし穴があっても scanf を好む場合は、%s を %[^, \t\r\n] に置き換えるだけで回避策を実行できます。

%s が非空白文字のシーケンスに一致するため、コンマも飲み込むという問題。したがって、%s を %[^, \t\r\n] に置き換えても、ほとんど同じように機能します (違いは、%s が isspace(3) を使用してスペース文字に一致することですが、この場合、どのスペース文字を使用するかを明示的に指定します一致し、このリストはおそらく isspace の場合と同じではありません)。

コンマの前後にスペースを許可する場合は、フォーマット文字列に空白を追加する必要があることに注意してください。フォーマット文字列 "%[^, \t\r\n] , %[^, \t\r\n]" は、"hello,world"、"hello, world"、"hello , world" などの文字列に一致します。

于 2009-07-12T20:35:00.047 に答える