山口屋~活動日誌~

私生活で主な出来事をピックアップ

C# 1文字 読み込み ファイル 入力 サロゲート String 出力 文字化け

2023-11-21 12:44:17 | ソフトウェア開発
C言語のfgetcと同じように1文字ずつC#で読み込みたいときは、StreamReader.Readメソッドを使えばよく、戻り値がint型であることも同じである。ただし、改行コードも1文字ずつとなりCRLFが2文字となるため、処理に注意が必要である。

C#内部の文字コードはUTF-16だが、Windowsで扱うテキストファイルはShift-JISであったりUTF-8であったり(Windows10 May 2019 Update で、メモ帳の文字コード既定値がShift-JISからUTF-8に変わった)と、細かい処理をする際は注意が必要。Encoding.Defaultのコードページを調べてみると932(Shift-JIS)だったり、コマンドプロンプトの文字コードをchcpコマンドで調べてみると932(Shift-JIS)だったり、複雑だ。

C#内部の文字コードはUTF-16ということで、サロゲートの処理について気になったので、いろいろ調べてみた。

String型の内部はCharオブジェクトで構成され、各Charオブジェクトには各UTF-16の2Byteを格納している。
日経クロステック(xTECH):C#プログラムでサロゲート・ペアの動作を検証する(前編)

UTF-8では3Byte以上の文字もあるが、UTF-16で2Byteで表現できるものはCharオブジェクトからはみ出ることなく格納される。UTF-8やUTF-16では、Basic Multilingual Plane:基本多言語面を面00として表し、これ以外の面01-面10(16進数)をサロゲートとして表す。UTF-8では、面00は3Byteで表現可能で、面01-面10が4Byteとなる。

.NET Tips (VB.NET,C#...):文字列から1文字取得する、文字列内の文字を列挙する
.NET Tips (VB.NET,C#...):サロゲートペアや結合文字が含まれているか調べる

Char.IsSurrogateメソッドは引数がCharオブジェクトで、StreamReader.Readメソッドの戻り値のInt32オブジェクトとは異なる。StringBuilder.Appendメソッドは引数がInt32オブジェクトのものもあり、StreamReader.Readメソッドの戻り値のInt32オブジェクトがそのまま使えそう。よって、StreamReader.Readメソッドの戻り値をStringBuilder.Appendメソッドで連結した後、末尾のCharオブジェクトをChar.IsSurrogateメソッドで調べれば良い?

なお、サロゲートは、Windows のコマンドプロンプトが出力をサポートしておらず、そもそもコンソールバッファのひとマスが16bitしか確保してないらしい。
標準愚痴出力:Windows のコンソールと、Unicode のサロゲートペアとゼロ幅文字



最新の画像もっと見る

コメントを投稿