質問

私はいくつかのコードに遭遇していると、元の開発者が最大だったと思いまして。以下は、このパターンを使用して単純化されたプログラムがあります:

      #include <stdio.h>

      int main()  {     

      char title[80] = "mytitle";      
      char title2[80] = "mayataiatale";      
      char mystring[80]; 

      /* hugh ? */
      sscanf(title,"%[^a]",mystring);
      printf("%s\n",mystring); /* Output is "mytitle" */


      /* hugh ? */
      sscanf(title2,"%[^a]",mystring); /* Output is "m" */
      printf("%s\n",mystring);


      return 0;  
  }

のscanf の manページには、関連する情報がありますが、私は問題を抱えていますそれを読んで。表記のこの種を使用する目的は何ですか?それは何を達成しようとしている?

役に立ちましたか?

解決

%sの表記を使用すると、フィールドの長さを指定した場合でも、最初の空白文字で停止し、あなたはかなり頻繁にそれはしたくないように、

文字クラスの主な理由です。その場合には、文字クラスの表記法は非常に参考にすることができます。

余分を破棄しますが、スペースを保ち、最大10文字の行を読み取るために、このコードを考えてみます:

#include <ctype.h>
#include <stdio.h>

int main(void)
{
    char buffer[10+1] = "";
    int rc;
    while ((rc = scanf("%10[^\n]%*[^\n]", buffer)) >= 0)
    {
            int c = getchar();
            printf("rc = %d\n", rc);
            if (rc >= 0)
                    printf("buffer = <<%s>>\n", buffer);
            buffer[0] = '\0';
    }
    printf("rc = %d\n", rc);
    return(0);
}

これは実際にバリアントをgetline()に関連した(2004年6月頃)comp.lang.c.moderated上の議論のためのコード例だった。

<時間>

少なくともいくつかの混乱が君臨します。第一の形式指定子は、%10[^\n]は、10の非改行文字まで読み取り、それらを後続ヌルと共に、バッファに割り当てられます。第二の形式指定子は、%*[^\n]が割り当て抑制文字(*)を含み、入力からゼロ又はそれ以上の残りの非改行文字を読み取ります。 scanf()機能が完了すると、入力は次の改行文字を指しています。ループを再起動すると、入力は、次の行の先頭を見ているときように、ループの本体は、読み込み、その文字を印刷します。このプロセスは、その後繰り返されます。行が10文字より短い場合、それらの文字がバッファにコピーされ、「ゼロ以上の非改行」形式がゼロ非改行を処理します。

他のヒント

%[a]は、字句解析の種類として使用することができるように、

%[^a]scanf()ような構築物は、存在します。これらは、一種の%sのような、代わりに、できるだけ多くの「糸」の文字のスパンを収集している文字クラスによって記載されているように、彼らは文字だけのスパンを集めます。そこ書き込み%[a-zA-Z0-9]は意味をなさない可能性がある場合であってもよいが、私は私がscanf()と相補的なクラスのための魅力的なユースケースを参照してくださいわからないかもしれません。

IMHO、scanf()は、単純に、この仕事のための適切なツールではありません。私はそのより強力な機能のいずれかを使用して設定したたびに、私はそれをリッピングし、別の方法で機能を実装し、最終的に終わってきました。本当の字句解析を書くことのlexを使って意味いくつかのケースでは、通常時I / Oで行を行うと、値変換を行う前にstrtok()とトークンに粗く、それを壊す十分であった。

編集の私は、ユーザーが間違った入力を提供することに主張に直面したとき、それだけでプログラムを支援するのが得意ではないので、問題についての良いフィードバックを与える通常scanf()をリッピングし、持つ終了アセンブラ印刷「エラー、終了しました。」その唯一の有用なエラーメッセージとして私のユーザーと優に超えるつもりではなかったです。 (ME、その場合には)

これは、正規表現の文字セットのようなものです。 [0-9]は数字の文字列にマッチし、[^aeiou]は小文字の母音などではないものと一致します。

などの数字を抜くなどの用途のすべての種類、識別子、空白の塊などがあります。

あなたは ISOでそれについて読むことができます/ IEC9899標準を利用可能なオンラインます。

ここで私は[に関する文書(ページ286)から引用段落があります

  

は、予想のセットから文字の空でないシーケンスにマッチします   文字ます。

     

変換指定子は、内のすべての後続の文字を含みます   書式文字列、および対応する右ブラケットを含むアップ(])。ザ・   ブラケット(スキャンリスト)の間の文字は、スキャンセットを構成します   左括弧の後の文字はで、アクセント記号(^)でない限り、   スキャンセットはで表示されないすべての文字が含まれている場合   曲折アクセントと右括弧の間にスキャンリスト。もし   変換指定は、右のブラケット[]または[^]で始まります   文字は、スキャンリストと次の次の右ブラケットであります   文字は、仕様を終了対応する右ブラケットです。   それ以外の場合は最初に、次の右括弧文字はその一つです   仕様を終了します。文字スキャンリスト内にあり、ではない - 場合   最初に、また最初の文字が^ここ二、も   最後の文字が、動作は実装定義です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top