※これはこれの続きです。先にこれを読んでおいた方が絶対良いです。
何故こういう記述が可能なのか
その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系の『仕様』だと通りすがりの人に教えて貰いました。ありがとうございます
リンクも持ってきてくれました。でもいっぺん開いたページだったんですよね(自爆)
これへ続く…
(次は実践編(といいつつ実質応用編)です。ここ迄読めばもう充分身に付いてると思うので、読みたい人だけ読みましょう。)