C言語のスキャンセット(scanset)とは?scanfの%[ ]指定子の使い方を解説
C言語には「スキャンセット(scanset)」と呼ばれる機能があります。これは scanf ファミリーの関数がサポートする変換指定子の一つで、%[ ] の形式で表されます。スキャンセットの中には、1つの文字、または複数の文字の集合(大文字・小文字は区別される)を指定できます。スキャンセットが処理されるとき、scanf() はスキャンセット内に記述された文字だけを読み込み、それ以外の文字に到達した時点で読み込みを終了します。
基本的な使用例:大文字のみを読み込む
次の例では、%[A-Z] を使って大文字アルファベットのみを入力として受け付けます。
#include<stdio.h>
int main() {
char str[50];
printf("Enter something: ");
scanf("%[A-Z]s", str);
printf("Given String: %s", str);
}実行結果
Enter something: HElloWorld Given String: HE
この例では、小文字の文字はすべて無視されます。「W」も読み込まれていませんが、これはその直前に小文字があるためです。つまり、スキャンセットは最初にマッチしない文字が出現した時点で読み込みを停止するという仕組みになっています。
キャレット(^)を使った否定のスキャンセット
スキャンセットの先頭に「^(キャレット)」を置くと、意味が反転します。この場合、指定した文字が最初に出現するまでの間だけ文字を読み込み、その文字に到達した時点で読み込みを停止します。
以下の例では、「r」という文字が現れるまでの文字列を読み込みます。
#include<stdio.h>
int main() {
char str[50];
printf("Enter something: ");
scanf("%[^r]s", str);
printf("Given String: %s", str);
}実行結果
Enter something: HelloWorld Given String: HelloWo
ここでは、scanf() が「r」を受け取った時点でそれ以降の文字を無視していることがわかります。
空白を含む文字列を読み込むテクニック
この否定スキャンセットの性質を利用すると、「scanf() が空白(スペース)を含む文字列を読み込めない」というよく知られた問題を解決できます。%[^\n] と指定すれば、改行文字が現れるまでのすべての文字を読み込むことができるため、スペースを含んだ文章全体を一度に入力できるのです。
#include<stdio.h>
int main() {
char str[50];
printf("Enter something: ");
scanf("%[^\n]s", str);
printf("Given String: %s", str);
}実行結果
Enter something: Hello World. This line has some spaces. Given String: Hello World. This line has some spaces.
まとめ
- スキャンセット
%[ ]は、scanf 系関数で読み込む文字の集合を指定できる変換指定子である - 大文字・小文字は区別され、指定外の文字に到達すると読み込みが停止する
- 先頭に
^を付けることで「指定した文字以外」を読み込む動作になる %[^\n]を使えば、スペースを含む1行全体を scanf() で読み込める
-
C言語のscanf()関数とfscanf()関数の違いと使い方を解説
scanf()関数とはscanf()は、C言語において標準入力(stdin)から書式付きデータを読み込むための標準ライブラリ関数です。読み取りに成功した項目の数を返し、入力に失敗した場合やファイルの終端に達した場合には負の値(EOF)を返します。C言語におけるscanf()の構文は以下のとおりです。int scanf(const char *characters_set)以下は、C言語でのscanf()の使用例です。例#include <stdio.h> int main () { char s[20]; &n
-
Pythonでscanf()メソッドをシミュレートする方法をわかりやすく解説
Python公式ドキュメントの記述についてPythonには、C言語でおなじみのscanf()に直接相当する関数が現在用意されていません。そのため、入力文字列の解析を行いたい場合は、代わりに正規表現(reモジュール)を使うのが標準的なアプローチです。正規表現はscanf()のフォーマット文字列よりもはるかに柔軟で強力である反面、記述がやや冗長になるという特徴があります。しかし、一度パターンの書き方に慣れてしまえば、より複雑な解析にも対応できるようになります。以下の表は、scanf()のフォーマット指定子と、それにほぼ相当する正規表現の対応関係をまとめたものです。scanf()フォーマット指定子と