※これはこれ
の続きです。先にこれを読んでおいた方が絶対良いです。
#何故こういう記述が可能なのか
その1で
勿論ggってみました。
"%[^\n]" - Google 検索
残念!この謎の記法についての情報は(10件中)2件しかありませんでした。
とか何とかと書いてましたね。その時に出て来たサイトによると、
[^\n]
is a kind of regular expression.
[...]
: it matches a nonempty sequence of characters from the scanset (a set of characters given by...
).^
means that the scanset is "negated": it is given by its complement.^\n
: the scanset is all characters except\n
.Furthermore
fscanf
(andscanf
) will read the longest sequence of input characters matching the format.So
scanf("%[^\n]", s);
will read all characters until you reach\n
(orEOF
) and put them ins
. It is a common idiom to read a whole line in C.string - What does %[^\n] mean in C? - Stack Overflow
…とあります。日本語でおk
要するに、
[^\n]
の記法は正規表現の1つである。
[...]
はリストみたいなもの。
この中に^
と記述したので、これはリストの内容が否定されていることを表している(補集合)。
つまり^\n
は、すべての文字のうち\n
が除かれていることを表す。
scanf("%[^\n]", s);
の場合は\n
(又はEOF
)に到達するまでの文字配列をポインタ s に格納する。
…これで合ってる?これは逆にいうと、
[ ]
内に記述した文字だけを読み込ませるなーんて事も出来ちゃうんですね。排他的なmain.cint main(void) { char str[64] = { '\0' }; scanf("%[abcde]\n", str); //読み込み printf("%s\n", str); //出力 system("pause"); }
このプログラムで
aaaaaaaaaffffeee
と入力したらどうなるでしょうか?実行結果aaaaaaaaaffffeee aaaaaaaaa 続行するには何かキーを押してください . . .
1つ目の
'f'
の直前迄格納された様です。
つまり、a
,b
,c
,d
,e
の5種類の文字のみを読み込みの対象とし、それ以外を区切り文字としたのです。###これは……?
最早解り辛いmain.cint main(void) { char str[64] = { '\0' }; scanf("%[^a][bc\n]\n", str[0]); //読み込み printf("%s\n", str); //出力 system("pause"); }
このプログラムでは
a
は区切り文字、b
,c
,\n
は入力できる文字になってそうですね。実行結果bbbcccbcc ggrggggg fbgfgfgfrgrgrgrgnyjnkmk a str = "bbbccc bcc ggrggggg fbgfgfgfrgrgrgrgnyjnkmk " 続行するには何かキーを押してください . . .
解り辛いですが、
a
の直前迄になっています。
%[^...][~]
の後半の[~]
は意味を成さないという事が分かりました。省略しますが、逆(%[...][^~]
)もまた然りです。###これビット演算子じゃね?
って思ったそこのあなた!そう見えますが違います。他のビット演算子|
,&
,~
で試してみて下さい。
例えば%[~\n]
と記述した場合、~
,\n
を読み込みの対象として扱う様になります。残り2つも同様です。
先頭が^
の時だけ特別扱いです。先頭以外に^
を記述した場合はちゃんと読み込みの対象になります。
(…実際は違うかも知れないけど僕の環境ではそうなったの!)
scanf系の『仕様』だと通りすがりの人に教えて貰いました。ありがとうございます
リンクも持ってきてくれました。でもいっぺん開いたページだったんですよね(自爆)
これ
へ続く…
(次は実践編(といいつつ実質応用編)です。ここ迄読めばもう充分身に付いてると思うので、読みたい人だけ読みましょう。)