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

※これは<a href="https://qiita.com/Sankyuri/items/c7fb52658c45b8757b5c" target="_blank"><code><b><font color="red">これ</font></b></code></a>の続きです。先にこれを読んでおいた方が<b>絶対</b>良いです。

#何故こういう記述が可能なのか
その1で
><p>勿論ggってみました。<br>
<a href="https://www.google.co.jp/search?sxsrf=ALeKk00qddikOwol1uBHx0Sy1YjqNIC5aQ%3A1587700410997&source=hp&ei=umKiXva1OoH6-Qajxqy4Dg&q=%22%25%5B%5E%5Cn%5D%22&oq=&gs_lcp=CgZwc3ktYWIQARgJMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnUABYAGDMHWgDcAB4AIABAIgBAJIBAJgBAKoBB2d3cy13aXqwAQo&sclient=psy-ab" target="_blank">"%[^\n]" - Google 検索</a><br>
残念！この謎の記法についての情報は(10件中)2件しかありませんでした。</p>

とか何とかと書いてましたね。その時に出て来たサイトによると、

><div class="post-text" itemprop="text">
<p><code>[^\n]</code> is a kind of regular expression.</p>
<ul>
<li><code>[...]</code>: it matches a nonempty sequence of characters from the <em>scanset</em> (a set of characters given by <code>...</code>).</li>
<li><code>^</code> means that the scanset is "negated": it is given by its <em>complement</em>.</li>
<li><code>^\n</code>: the scanset is all characters except <code>\n</code>.</li>
</ul>
<p>Furthermore <code>fscanf</code> (and <code>scanf</code>) will read the longest sequence of input characters matching the format.</p>
<p>So <code>scanf("%[^\n]", s);</code> will read all characters until you reach <code>\n</code> (or <code>EOF</code>) and put them in <code>s</code>. It is a common idiom to read a whole line in C.</p>
</div>

<a href""https://stackoverflow.com/questions/39431924/what-does-n-mean-in-c" target="_blank">string - What does %[^\n] mean in C? - Stack Overflow</a>

…とあります。<b>日本語でおｋ</b>

要するに、
<code>[^\n]</code>の記法は正規表現の1つである。
<code>[...]</code>はリストみたいなもの。
この中に<code>^</code>と記述したので、これはリストの内容が<b>否定されている</b>ことを表している(補集合)。
つまり<code>^\n</code>は、<b>すべての文字のうち<code>\n</code>が除かれている</b>ことを表す。
<code>scanf("%[^\n]", s);</code>の場合は<code>\n</code>(又は<code>EOF</code>)に到達するまでの文字配列をポインタ s に格納する。
<font color="silver">
…これで合ってる？
</font>

これは逆にいうと、<b><code>[  ]</code>内に記述した文字だけを読み込ませる</b>なーんて事も出来ちゃうんですね。

``` c:排他的なmain.c
int main(void) {
	char str[64] = { '\0' };
	scanf("%[abcde]\n", str); //読み込み
	printf("%s\n", str); //出力
	system("pause");
}
```
このプログラムで<code>aaaaaaaaaffffeee</code>と入力したらどうなるでしょうか？

``` result:実行結果
aaaaaaaaaffffeee
aaaaaaaaa
続行するには何かキーを押してください . . .
```
1つ目の<code>'f'</code>の直前迄格納された様です。
つまり、<code>a</code>, <code>b</code>, <code>c</code>, <code>d</code>, <code>e</code>の5種類の文字<b>のみ</b>を読み込みの対象とし、それ以外を区切り文字としたのです。

###これは……？
``` c:最早解り辛いmain.c
int main(void) {
	char str[64] = { '\0' };
	scanf("%[^a][bc\n]\n", str[0]); //読み込み
	printf("%s\n", str); //出力
	system("pause");
}
```
このプログラムでは<code>a</code>は区切り文字、<code>b</code>,<code>c</code>,<code>\n</code>は入力できる文字になってそうですね。

``` result:実行結果bbbccc

bcc
ggrggggg
fbgfgfgfrgrgrgrgnyjnkmk
a
str = "bbbccc

bcc
ggrggggg
fbgfgfgfrgrgrgrgnyjnkmk
"
続行するには何かキーを押してください . . .
```
解り辛いですが、<b><code>a</code>の直前迄</b>になっています。
<b><code>%[^...][～]</code>の後半の<code>[～]</code>は意味を成さない</b>という事が分かりました。省略しますが、逆(<code>%[...][^～]</code>)もまた然りです。

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


(…実際は違うかも知れないけど僕の環境ではそうなったの！)

scanf系の『仕様』だと通りすがりの人に教えて貰いました。ありがとうございます
<a href="https://ja.cppreference.com/w/c/io/fscanf" target="_blank">リンク</a>も持ってきてくれました。でもいっぺん開いたページだったんですよね(自爆)

<hr>

<a href="https://qiita.com/Sankyuri/items/12b967cc6cfa7eb04fbe" target="_blank"><code><b><font color="red">これ</font></b></code></a>へ続く…
(次は実践編(といいつつ実質応用編)です。ここ迄読めばもう充分身に付いてると思うので、読みたい人だけ読みましょう。)













<br><br><br><br><br><br><br>