1
1

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]』とは?? その3: 応用編(最後)

Last updated at Posted at 2020-04-24

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

#本題はfscanf()で読み込む事

(; ・`д・´)はっ!…もう満足して本題を忘れかけてました。危ない危ない…。

今回この様なテキストファイル(.txt)を作ってみました

test用.txt
Kenji^Hello, world and Mami!

パラメータKenjiと値Hello, world and Mami!が記述されたファイルです。
何だかノベルゲームのスクリプトの様ですが、区切り文字が^になっていて見慣れない感じですね。

main.c
//プリプロセッサは省略
int main(void) {
	FILE *fp;
	char str[2][64] = { { '\0' } };
	fp = fopen("./test用.txt", "r");
	fscanf(fp, "%[^^]%[^\n]", str[0], str[1]); //読み込み
	fclose(fp);
	printf("%s says \"%s\"\n", str[0], str[1]); //出力
	system("pause");
}
実行結果
Kenji says "^Hello, world and Mami!"
続行するには何かキーを押してください . . .

おっ出来……ん?????
^が文章に含まれてしまいました。うーんこの…。

それもその筈。

  1. headから^の直前迄を読み込む
  2. ^から\n迄を読み込む
という風に処理された結果、当然 2 の先頭の^も格納されます。

ではどうすれば回避できるでしょうか?少し考えてみて下さい。

###区切り文字が読み込まれるバグを修正
分かりましたか? …そうですね。

例えば、標準入力からsage, true(ただし値はchar*)という様に入力する場合は

例.c
    scanf("%s, %s", str1, str2);

という風に記述すると思います。
そうです。%[^\n]についても同じ事がいえます。

'^'が読み捨てられるmain.c
	fscanf(fp, "%[^^]^%[^\n]", str[0], str[1]); //読み込み
実行結果
Kenji says "Hello, world and Mami!"
続行するには何かキーを押してください . . .

ちゃんと^が読み捨てられました。皆は分かったかな?

###僕がやりたいのはスクリプトの読み込みだから……
今度は複数行が読み込まれるようにしました。

'^'が読み捨てられるmain.c
int main(void) {
	FILE *fp;
	char str[2][64] = { { '\0' } };
	fp = fopen("./test用.txt", "r");
	while (1) {
		fscanf(fp, "%[^^]^ %[^\n]\n", str[0], str[1]); //読み込み
		if ('0' == str[0][0] &&  '0' == str[1][0]) { //終了チェック
			break;
		}
		printf("%s says \"%s\"\n", str[0], str[1]); //出力
	}
	fclose(fp);
	system("pause");
}
test用.txt
KenjiEX ^ Hello, world and Mami!
song1   ^ Shades of Light in a Transcendent Realm
song10  ^ world.execute(me);
0^0

テキストファイルには曲名を追加してみました(「~ says ...」と出力されるけど)。
え?どっかで見たことある曲名だって?偶然だよ偶然、あはは…。

実行結果
KenjiEX  says "Hello, world and Mami!"
song1    says "Shades of Light in a Transcendent Realm"
song10   says "world.execute(me);"
続行するには何かキーを押してください . . .

な ん と い う こ と で し ょ う(BGM:TAKUMI/匠 / 松谷 卓)
誰かさんがインデントした所為で、パラメータが^の直前のスペース迄読み込まれているではありませんか(バグ)。

…まあ、パラメータは普通は綴りに空白なんて入れないので、これへの対応は難しくは無いでしょう。

##結局

これでいいや…….c
    scanf("%s %[^\n]\n", str[0], str[1]);

この様に、^みたいな区切り文字は無くし、半角空白で区切る事にしました。
読み込み方法を、パラメータは其の儘に、値を改行文字迄にしたので区切り用の記号が必要無くなったのです。

#まとめ
フォーマット指定子%[...]は使い辛い!以上!


あっやめて四角括弧ちゃん!ごめんって!僕が悪かったから!うわなにをするやめrくぁwせdrftgyふじこlp








1
1
1

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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?