※これはこれ
の続きです。先にこれを読んでおいた方が絶対良いです。
何故こういう記述が可能なのか
その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 に格納する。
…これで合ってる?
これは逆にいうと、[ ]
内に記述した文字だけを読み込ませるなーんて事も出来ちゃうんですね。
int 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種類の文字のみを読み込みの対象とし、それ以外を区切り文字としたのです。
これは……?
int main(void) {
char str[64] = { '\0' };
scanf("%[^a][bc\n]\n", str[0]); //読み込み
printf("%s\n", str); //出力
system("pause");
}
このプログラムではa
は区切り文字、b
,c
,\n
は入力できる文字になってそうですね。
bcc
ggrggggg
fbgfgfgfrgrgrgrgnyjnkmk
a
str = "bbbccc
bcc
ggrggggg
fbgfgfgfrgrgrgrgnyjnkmk
"
続行するには何かキーを押してください . . .
解り辛いですが、a
の直前迄になっています。
%[^...][~]
の後半の[~]
は意味を成さないという事が分かりました。省略しますが、逆(%[...][^~]
)もまた然りです。
これビット演算子じゃね?
って思ったそこのあなた!そう見えますが違います。他のビット演算子|
, &
, ~
で試してみて下さい。
例えば%[~\n]
と記述した場合、~
, \n
を読み込みの対象として扱う様になります。残り2つも同様です。
先頭が^
の時だけ特別扱いです。先頭以外に^
を記述した場合はちゃんと読み込みの対象になります。
(…実際は違うかも知れないけど僕の環境ではそうなったの!)
scanf系の『仕様』だと通りすがりの人に教えて貰いました。ありがとうございます
リンクも持ってきてくれました。でもいっぺん開いたページだったんですよね(自爆)
これ
へ続く…
(次は実践編(といいつつ実質応用編)です。ここ迄読めばもう充分身に付いてると思うので、読みたい人だけ読みましょう。)