2016-04-08 13 views
2

ああ、プログラマの老朽化した物語。予想以上に何も期待していないコードを徐々に書いていますが、コードは予期せずすべてを正しく行います。このscanf()変換が実際に動作するのはなぜですか?

私はいくつかのCプログラミングの練習問題に取り組んでいますが、stdinをいくつかの行のコードを含むテキストファイルにリダイレクトし、それをscanf()とprintf()でコンソールに出力しました。私は、改行文字を取得するのに問題がありました(scanfは通常空白文字を食べるので)、最初からやり直すことを決めたときに複数の条件文とフラグが混乱してコードが混乱してしまいました。

scanf("%[a-zA-Z -[\n]]", c); 
printf("%s", c); 

そして、ほら(cは、テキストファイルの内容全体を保持するのに十分な大きさの文字バッファーです)

が、これは完全に働きました。

[\w\W -[\n]] 
[\w\d -[\n]] 
[. -[\n]] 
[.* -[\n]] 
[^\n] 

なく働いたそれらのどれも私のような、なぜ(外部ブラケットとの間の)文字クラスのバリエーションを作成することによって把握することを試みました。彼らはすべて一人の人物を読んだり、ランダムな人物の混乱を招いたりしてしまった。テキストファイルに改行文字が含まれているため、 '[^ \ n]'は機能しません。したがって、1行だけが出力されます。

私はまだそれを考え出したていないので

、私はそこに誰かがこれら二つの質問への答えを知っているだろう願っています:

  • をなぜ「[-ZA-Z - [\ NN] ] "期待通りに働く?
  • テキストファイルには、文字、数字、記号( ':'、 ' - '、 '>'、多分その他)が含まれています。 'a-z'が "unicode 'a'からunicode 'z' 'へのすべての文字を意味すると仮定すると、' a-zA-Z 'には数字も含まれますか?
  • 大括弧の中に入力できるものの構文は、正規表現(私はPythonに精通しています)によく似ていますが、正確ではありません。私はこの問題を解明しようとするのに使うことができるものを読みましたが、この構文が正規表現になるものを比較する情報は見つかりませんでした。だから、どうやって似ていて違うの?

私はおそらくこれを知ってはscanfのための良い使い方ではありませんが、それは練習問題から来ているので、現実の世界大会は、一時的にこの用法では無視する必要があります。

ありがとうございます!

+6

文字の分類形式は正規表現ではありません。読んでください。 [この 'scanf'(および家族)のリファレンス](http://en.cppreference.com/w/c/io/fscanf)を参照してください。 –

+0

"space"から "open bracket"までの範囲の文字列があります。 – user2357112

+0

Cにはネストされた文字クラスがありませんか? – velocirabbit

答えて

3

あなたのキャラクターセットに「 - 」があるので、数字をピックアップしています。これはスペース(32)からオープンブラケット(91)までのすべての文字を意味し、ASCII(48-57)の数字が含まれています。

あなたの他の例も同様ですが、小文字(97-122)をピックアップできる "a-zA-Z"がありません。 '\ w'のようなシーケンスは文字列自体で未知のエスケープシーケンスとして扱われるので、\wはただ一つのwになります。 .および*は文字通りに解釈されます。彼らは正規表現のような特別な意味を持っていません。

+0

Cにはネストされた文字クラスがありませんか?何らかの理由で私はそれがそうだと思った。しかしそれは間違いなくそれを説明するでしょう。 – velocirabbit

+0

私はちょうどそれをテストしました。 '%[ - 〜\ n]'は私がそれをどのようにしたいのかにも作用します。 – velocirabbit

0

(最初または最後を除く)内に-を含めると、動作は実装定義になります。

これは、コンパイラのドキュメントにその動作を記述する必要があることを意味しています。そのドキュメントを参照して、定義された動作が何であるかを調べる必要があります。

ポータブルコードを書きたい場合は、-をハイフンにマッチさせる以外の方法で使用することはできません。

関連する問題