2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C#】文字コードShift-JISのCSVの中身を判定する方法

Posted at

文字コードSfift-JISのCSVを読み込むときに①Shift-JISに含まれていない文字、②Null、③空文字「""」といった値をキャッチする方法を記載します。

指定されたエンコーディングの例外エラーEncoderFallbackExceptionとは?

EncoderFallbackException は、文字列をバイト配列に変換する際に、指定されたエンコーディング(例: Shift-JIS)で変換できない文字が含まれていた場合に発生する例外です。

例えば、Shift-JIS エンコーディングを使って文字列をエンコードしようとしたとき、その文字列の中に Shift-JISでは表現できない文字(例えば、UTF-8でしか表現できない文字)を含んでいた場合、エンコーディングができないため、EncoderFallbackException がスローされます。

✅ 具体例

  1. Shift-JISで扱えない文字

Shift-JISは日本語の文字セットですが、全てのUnicode文字をサポートしているわけではありません。
例えば、Shift-JISでは 絵文字や一部の漢字(例えば、Unicodeの一部の新しい漢字など)はエンコードできません。

例:

文字列 "こんにちは😊" は、Shift-JISでは 😊 をエンコードできません。

sample.cs
string value = "こんにちは😊"; // "😊" は Shift-JIS ではエンコードできない
byte[] bytes = Encoding.GetEncoding(932).GetBytes(value); // ここでエラーが発生

✅ どうして EncoderFallbackException が発生するのか?

エンコーディングは、文字をバイトに変換するプロセスです。例えば、UTF-8 Shift-JIS などのエンコーディングは、各文字に対応するバイト列(コードポイント)を持っています。

もし文字列の中に、エンコーディングがサポートしていない文字が含まれている場合、エンコーディング処理は失敗し、その結果として EncoderFallbackException がスローされます。

前置きが長くなりましたが、コードはこちらになります。

sample.cs
using System;
using System.IO;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        // ★ Shift-JISなどのコードページ対応を有効化
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        string filePath = "C:\\Users\\XXXX\\source\\repos\\ConsoleApp\\ConsoleApp\\sample.csv";

        if (!File.Exists(filePath))
        {
            Console.WriteLine($"エラー: ファイル '{filePath}' が見つかりません。");
            Console.WriteLine("プロジェクトのルートに sample.csv を作成してください。");
            return;
        }

        try
        {
            Encoding shiftJIS = Encoding.GetEncoding(932, new EncoderExceptionFallback(), new DecoderExceptionFallback());

            foreach (string line in File.ReadLines(filePath))
            {
                string[] fields = line.Split(',');

                if (fields.Length < 2)
                {
                    Console.WriteLine("無効な行フォーマットです。スキップします。");
                    continue;
                }

                string value = fields[1].Trim('\"');

                Console.WriteLine($"--- ID: {fields[0]} ---");
                Console.WriteLine($"文字列: '{value}'");

                try
                {
                    //NULLもしくは空文字列の場合
                    if (string.IsNullOrEmpty(value) || value == "null") 
                    {
                        Console.WriteLine("→ Shift-JIS変換: 失敗しました。文字列がNullもしくは空です。");
                        continue;
                    }

                    byte[] bytes = shiftJIS.GetBytes(value);
                    Console.WriteLine("→ Shift-JIS変換: 成功しました。");
                }
                catch (EncoderFallbackException ex)
                {
                    Console.WriteLine($"→ Shift-JIS変換: 失敗しました(変換できない文字が含まれています)。{ex.Message}");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"エラーが発生しました: {ex.Message}");
        }
    }
}


トラブルシューティング

「Encoding shiftJIS = Encoding.GetEncoding(932, new EncoderExceptionFallback(), new DecoderExceptionFallback());」の箇所でエラー「No data is available for encoding 932. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.」になった。

発生している下記のエラー⇩

No data is available for encoding 932. 
For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.

🔍 原因

.NET Core / .NET 5 以降の環境では、Shift-JIS などの一部の日本語コードページ(932など)がデフォルトでは利用できないようになっています。

.NET Core, .NET 5+, .NET 6, .NET 7, .NET 8 などはセキュリティ・パフォーマンス向上のため、多くの非UTFエンコーディングを無効化しています。

コードページ 932(Shift_JIS)を使用するには、エンコーディングプロバイダを登録する必要があります。

✅ 解決策:エンコーディングプロバイダを登録する

sample.cs
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

修正版のコード⇩

sample.cs
using System;
using System.IO;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        // ★ Shift-JISなどのコードページ対応を有効化
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

        // Shift-JIS エンコーディングを作成
        Encoding shiftJIS = Encoding.GetEncoding(932, new EncoderExceptionFallback(), new DecoderExceptionFallback());

        string filePath = "C:\\Users\\sample.csv";

        if (!File.Exists(filePath))
        {
            Console.WriteLine($"エラー: ファイル '{filePath}' が見つかりません。");
            Console.WriteLine("プロジェクトのルートに sample.csv を作成してください。");
            return;
        }

        try
        {
            foreach (string line in File.ReadLines(filePath))
            {
                string[] fields = line.Split(',');

                if (fields.Length < 2)
                {
                    Console.WriteLine("無効な行フォーマットです。スキップします。");
                    continue;
                }

                string value = fields[1].Trim('\"');

                Console.WriteLine($"--- ID: {fields[0]} ---");
                Console.WriteLine($"文字列: '{value}'");

                if (string.IsNullOrEmpty(value))
                {
                    Console.WriteLine("→ 判定結果: 文字列は null または空です。");
                }
                else
                {
                    Console.WriteLine("→ 判定結果: 文字列は有効です。");
                }

                try
                {
                    byte[] bytes = shiftJIS.GetBytes(value);
                    Console.WriteLine("→ Shift-JIS変換: 成功しました。");
                }
                catch (EncoderFallbackException)
                {
                    Console.WriteLine("→ Shift-JIS変換: 失敗しました(変換できない文字が含まれています)。");
                }

                Console.WriteLine();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"エラーが発生しました: {ex.Message}");
        }
    }
}

2
0
0

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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?