当記事では、C#でファイル入出力を行う場合の文字コードの指定について調査した。
C#でテキストファイルを読み書きする場合のエンコーディング指定の方法や、エンコーディングの種類について良く忘れるので、備忘録としてまとめてみたのだ。
では本題に入ろう。
文字コードはエンコーディングと呼ばれる
C#でプログラムを書いていると、ファイルを読み書きする状況は良くある。
例えば、以下の二つのファイル出力関数は手軽に文字列や配列をファイルに出力できるのでワテは良く使う。
C#で文字列をファイルに出力する関数
File.WriteAllText( string path, // 書き込み先のファイル。 string contents, // ファイルに書き込む文字列。 Encoding encoding // 出力ファイルのエンコーディング。 )
WriteAllText関数の場合には、第二引数contentsで与えた文字列をファイルに出力出来る。
もし改行コードを含む文字列をファイル出力した場合には、複数行のデータをファイルに書き込む事が出来る。
エンコーディングは第三引数で与える。省略した場合にはUTF-8が使われる。
一方、次に示す関数を使えば、配列やリストに保存している複数行の文字列データをファイルに出力出来るので便利だ。
C#で文字列配列をファイルに出力する関数
File.WriteAllLines( string path, // 書き込み先のファイル。 string[] contents, // ファイルに書き込む文字列配列。 Encoding encoding // 出力ファイルのエンコーディング。 )
このWriteAllLines関数の場合には、第二引数contentsが文字列型の配列になっている。
なので、もしリストデータを出力したい場合には to.Array()メソッドで配列化してやれば良い。
どちらの関数も事前にファイルをオープンするなどの操作が必要なく、いきなり出力出来る。
書き込んだ後はクローズ処理などは何もしなくても良い。
C, C++でファイルの入出力を行う場合だと、fopen, fcloseなど何かとややこしいが、C#のファイル操作の手軽さがとても使い易い。
文字列や文字列配列をファイル出力するコンソールプログラム例
何の特徴もない普通のプログラムであるが、ファイル出力を行うプログラムの例。
文字列を出力する場合と、文字列配列を出力する場合の例を二つ書いてみた。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //現在のVisual Studio Projectのトップディレクトリを取得
            var pathNamePJ = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
 
            //出力ファイルの絶対パスを作成
            var pathFNameOut1 = Path.Combine(pathNamePJ, "CSV1.txt");
            var pathFNameOut2 = Path.Combine(pathNamePJ, "CSV2.txt");
            
            const string CRLF = "\r\n";
            
            //出力文字列
            var text
                = "00, 01, 02" + CRLF
                + "10, 11, 12" + CRLF
                + "20, 21, 22";
 
            //出力文字列配列を作成
            var lines  = text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
 
 
            //ファイルに出力
            File.WriteAllText (pathFNameOut1, text, Encoding.GetEncoding("Shift-JIS")); // 文字列
            File.WriteAllLines(pathFNameOut2, lines, Encoding.GetEncoding("Shift-JIS"));// 文字列の配列やリストなど
        }
    }
}
実行すると、二つのファイルが出来るが、CSV1.txt も CSV2.txt も共に
00, 01, 02 10, 11, 12 20, 21, 22
こんな中身になる。
この場合だとシングルバイトの半角文字しか出力していないので、エンコーディング指定を省略しても良い。その場合はUTF-8で出力される。
C#のエンコーディングの種類
さて、Windowsでプログラミングをしていると、文字コードを意識する必要がある。
WindowsはテキストファイルはシフトJISコードを想定しているので、他の文字コード
- UTF-8
- JIS
- Euc-JP
のファイルを開くと文字化けする場合があるからだ。
なので、Visual Studioでファイルの入出力を行う場合には、上記の関数の例のように、引数でエンコーディングを指定するのが安全だ。このパラメータは省略可能であるが、ワテは毎回明示的に指定する習慣を付けている。
でも、未だに、このエンコーディング指定の記述方法を覚えられない。
Encoding.GetEncoding("Shift-JIS")  // これは行ける
Encoding.GetEncoding("Shift_JIS") // じゃあこれは?
Encoding.GetEncoding("Shift JIS") // これは?
Encoding.GetEncoding("SJIS")    // これも行ける?
最近は物覚えが悪いので、これらを調査してまとめてみた。
その調査結果は以下の通り。
C#で指定出来るエンコーディングの形式(日本語関連)
//①シフトジスの場合
var e1 = Encoding.GetEncoding("Shift_JIS");             // アンダースコアか
var e2 = Encoding.GetEncoding("Shift-JIS");             // ハイホンが良いみたい。
var e3 = Encoding.GetEncoding("SHiFt-jIs");             // 大文字小文字が混じっていても良い。
var e4 = Encoding.GetEncoding("Sjis");                  // 短縮形SJISも良い。
//x var e5 = Encoding.GetEncoding("SHIFT-JIS"); // 全角は駄目。誰もそんなんせえへんわ。
//x var e6 = Encoding.GetEncoding("SHiFt - jIs");       // 途中に半角空白があるとエラー
//x var e7 = Encoding.GetEncoding("Shift JIS");         // 途中に半角空白があるとエラー
//x var e8 = Encoding.GetEncoding("ShiftJIS");          // 連結するとエラー
//x var e9 = Encoding.GetEncoding("シフト JIS");        // 日本語もエラー。まあそうだろうな。
var e11 = Encoding.GetEncoding("Shift_JIS".ToUpper());  // 大文字でも良い。
var e12 = Encoding.GetEncoding("Shift-JIS".ToUpper());  // 大文字でも良い。 
var e13 = Encoding.GetEncoding("SJIS".ToUpper());       // 大文字でも良い。 
var e21 = Encoding.GetEncoding("Shift_JIS".ToLower());  // 小文字でも良い。
var e22 = Encoding.GetEncoding("Shift-JIS".ToLower());  // 小文字でも良い。 
var e23 = Encoding.GetEncoding("SJIS".ToLower());       // 小文字でも良い。 
var e24 = Encoding.GetEncoding(932);                    // SJISのコードを数字で指定しても良い。
//②JISの場合
var e30 = Encoding.GetEncoding("iso-2022-jp");          // JISコードの場合
var e31 = Encoding.GetEncoding(50220);                  // JISコードの場合
//③EUCの場合
var e70 = Encoding.GetEncoding("euc-jp");               // EUCの場合
//x var e71 = Encoding.GetEncoding("euc_jp");           // EUCの場合
//x var e71 = Encoding.GetEncoding("eucjp");            // EUCの場合
var e72 = Encoding.GetEncoding(51932);                  // EUCの場合
//④UTF-8の場合
var e40 = Encoding.GetEncoding("UTF-8");                // UTF-8の場合
var e41 = Encoding.GetEncoding(65001);                  // UTF-8の場合
var e42 = Encoding.UTF8;                                // UTF-8の場合
//⑤UTF-16(=Unicode)
var e50 = Encoding.Unicode;                             // Unicodeとは
var e51 = Encoding.GetEncoding("utf-16");               // UTF-16の事か。
var e52 = Encoding.GetEncoding(1200);                   // 数字だと1200
//⑥UTF-16BE
var e60 = Encoding.BigEndianUnicode;                    // UnicodeのBigEndianは
var e61 = Encoding.GetEncoding("utf-16BE");             // utf-16BE
var e62 = Encoding.GetEncoding(1201);                   // 数字だと1201
まとめ
まあ、結論としては、
シフトジスを使うなら ”SJIS” で十分。
Encoding.GetEncoding("SJIS");
UTF-8は “UTF-8” でも良いが、
Encoding.GetEncoding("UTF-8");
以下のように専用の定数が用意されているのでこっちで良いな。
Encoding.UTF8
あとは、UTF-16とUnicodeが同じと言う事と、
Encoding.Unicode;                            // Unicodeとは
Encoding.GetEncoding("utf-16");          // UTF-16の事
ビッグエンディアンは以下のような形式で指定可能と言う点を覚えておけば良い。
Encoding.BigEndianUnicode;                    // UnicodeのBigEndianは
Encoding.GetEncoding("utf-16BE");             // utf-16BE
Encoding.GetEncoding(1201);
う~ん、多分また忘れるな。
C#を勉強するなら本を読まなあかん
まずはこういう本で勉強してデスクトップアプリを作ってみるのが良いだろう。
デスクトップアプリとは、
- ウンドウが開いてボタンとかチェックボックスとかいろんな部品が乗っているGUIアプリ
- ウインドウは出さずにコンソール画面(DOS窓)に文字出力だけのアプリ
- ウインドウもコンソール画面も出さずに裏でコッソリ動いているプログラム
などだ。










コメント