結果が異なる §
サンプルソースをVisual Studioでデバッグ実行するとコンソールには"A?B"と出力されますが、Visual Studioの出力ウィンドウにはABと出て来て一致しません。
疑問は2つです。
- コンソールでなぜ2文字目は?に化けるのか?
- 出力ウィンドウでなぜ2文字目は消えてしまうのか?
- そもそも2文字目の'\u200B'は何を書いているのか
問いの答え §
第1の問いの答は【デフォルトのコンソールはシフトJIS(CP932)で動いているため、シフトJISにない文字は全て?になるから】です。
第2の問いの答は、2文字目がzero width spaceという幅がゼロの空白文字だからです。この文字には幅がありませんので、書き込まれていても存在しないように見えます。
第3の問いの答は、【C#に存在するUnicodeの文字コードを直接表記する書式でzero width spaceのコードU+200Bを直接書いた】です。\uに続いて文字コードの16進値を書きます。
罠の数々 §
- ソースを入力する手段で、扱えない文字、見えない文字は16進数の番号指定で書き込んでしまう。この方法を使えば、かな漢字変換機能を持っていない英語環境で日本語文字も簡単にソースに埋め込める。(ただし文字の番号を調べる手間はかかる)
- Unicodeで面倒くさいのはサロゲートペアだけだと思うと痛い目を見る。zero width spaceが挿入されているせいで、見た目と実際の文字列の長さが違うケースもあり得る (他にもあるぞ)
- zero width spaceは、文字としては隣接しているが単語の区切りになる箇所を示す等の目的で使われるが、希に表現のトリックにも使用される。注意しよう
参考リンク §
文字列 (C# プログラミング ガイド)
上記ページの【文字列のエスケープ シーケンス】に\uを始めとする\を前置する表記の一覧がある。他にとんな表記があるか確認しておこう。特に、4桁を超える番号を持つ表記を記述する方法は顔文字を埋め込む際には使用される可能性がある。要チェックだ。
リポジトリ §
https://github.com/autumn009/cshowto
ZWSP §
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
char[] ar = { 'A', '\u200B', 'B' };
string s = new string(ar);
Console.WriteLine(s);
Debug.WriteLine(s);
}
}
実行結果 (コンソール)
A?B
実行結果 (Visual Studioの出力ウィンドウ)
AB