2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C/C++のフォーマット指定子『%[^\n]』とは?? その2: 仕様編

Last updated at Posted at 2020-04-24

※これはこれの続きです。先にこれを読んでおいた方が絶対良いです。

#何故こういう記述が可能なのか
その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 (and scanf) will read the longest sequence of input characters matching the format.

So scanf("%[^\n]", s); will read all characters until you reach \n (or EOF) and put them in s. 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.c
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種類の文字のみを読み込みの対象とし、それ以外を区切り文字としたのです。

###これは……?

最早解り辛いmain.c
int main(void) {
	char str[64] = { '\0' };
	scanf("%[^a][bc\n]\n", str[0]); //読み込み
	printf("%s\n", str); //出力
	system("pause");
}

このプログラムではaは区切り文字、b,c,\nは入力できる文字になってそうですね。

実行結果bbbccc

bcc
ggrggggg
fbgfgfgfrgrgrgrgnyjnkmk
a
str = "bbbccc

bcc
ggrggggg
fbgfgfgfrgrgrgrgnyjnkmk
"
続行するには何かキーを押してください . . .

解り辛いですが、aの直前迄になっています。
%[^...][~]の後半の[~]は意味を成さないという事が分かりました。省略しますが、逆(%[...][^~])もまた然りです。

###これビット演算子じゃね?
って思ったそこのあなた!そう見えますが違います。他のビット演算子|, &, ~で試してみて下さい。
例えば%[~\n]と記述した場合、~, \nを読み込みの対象として扱う様になります。残り2つも同様です。
先頭が^の時だけ特別扱いです。先頭以外に^を記述した場合はちゃんと読み込みの対象になります。

(…実際は違うかも知れないけど僕の環境ではそうなったの!)
scanf系の『仕様』だと通りすがりの人に教えて貰いました。ありがとうございます
リンクも持ってきてくれました。でもいっぺん開いたページだったんですよね(自爆)


これへ続く…
(次は実践編(といいつつ実質応用編)です。ここ迄読めばもう充分身に付いてると思うので、読みたい人だけ読みましょう。)








2
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?