C#で文字列をUTF-8に変換するにはどうすればよいですか?


146

サードパーティのアプリから受け取った文字列があり、Windows SurfaceでC#を使用して任意の言語で正しく表示したいのですが。

エンコーディングが正しくないため、私の文字列の一部はスペイン語では次のようになります。

Acción

これは次のようになります。

アクシオン

この質問の回答によると: C#文字列エンコーディングを知る方法、受け取っているエンコーディングはすでにUTF-8で提供されているはずですが、Encoding.Default(おそらくANSI?)で読み取られます。

この文字列を実際のUTF-8に変換しようとしていますが、問題の1つは、Encodingクラスのサブセットしか表示できない(UTF8およびUnicodeプロパティのみ)ことです。これは、おそらくWindowsサーフェスAPIに制限されているためです。

私はインターネットで見つけたスニペットをいくつか試しましたが、東部の言語(つまり、韓国語)でこれまでに成功したと証明されたものはありません。一例は次のとおりです。

var utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(myString);
myString= utf8.GetString(utfBytes, 0, utfBytes.Length);     

また、文字列をバイト配列に抽出してから、UTF8.GetStringを使用してみました。

byte[] myByteArray = new byte[myString.Length];
for (int ix = 0; ix < myString.Length; ++ix)
{
    char ch = myString[ix];
    myByteArray[ix] = (byte) ch;
}

myString = Encoding.UTF8.GetString(myByteArray, 0, myString.Length);

私が試すことができる他のアイデアはありますか?


5
問題は、そもそも(ストリームまたはbyte []から)文字列を作成したコードにあります。そのコードを示してください。
SLaks、

1
@Oded:.Net文字列はメモリにUTF16として格納されEncoding.Defaultますが、システムのANSIコードページを返します。
SLaks

これは、英語では機能しない文字列の例です。日を表示する代わりに、フロントエンドアプリは次を表示しています:day’s
Gaara

回答:


251

あなたが知っているように、Encoding.Defaultあなたが単に使用できるように文字列が入ってくる:

byte[] bytes = Encoding.Default.GetBytes(myString);
myString = Encoding.UTF8.GetString(bytes);

もう一つは、あなたは覚えていることがありますが、出力にいくつかの文字列をConsole.WriteLineをを使用している場合は、また書くべきですConsole.OutputEncoding = System.Text.Encoding.UTF8;!または、すべてのutf8文字列がgbkとして出力されます...


これも機能します。実際には、私の回答よりもはるかに優れています。これも機能します。+ 1の優れた機能を提供します
MethodMan

ありがとう!問題は、説明で述べたように、サーフェスのAPIが不完全であることです(Encoding.Defaultが利用できません)。
Gaara

3
@Gaara:試してくださいEncoding.GetEncoding(...)。反対側で誤って使用された実際のエンコーディングの名前を見つける必要があります。
SLaks、

1
これが機能する理由を説明できますか?DefaultがGB2312の場合、Encoding.Default.GetBytesは文字列をバイト配列にエンコードしてGB2312エンコーダーを使用し、Encoding.UTF8.GetStringはバイト配列のデコードにUTF8デコーダーを使用します。結果は間違っているはずですが、なぜこれが機能するのでしょうか。@anothershrubery
guorongfei

1
@guorongfei前提はmyString文字組みです。このコードは、最初に誤ったデコードを元に戻し、次に正しいデコードを行います。間違ったデコードでデータが失われない限り、機能します。しかし、@ SLaksが指摘したように、間違っていた正確なエンコーディングを使用する方が良いでしょう。(コード内のより良い名前とコメントは、非常に見栄えの悪いコードが実際に正しく実行する試みであるかどうかを理解するのに役立ちます。)
Tom Blodget

17
string utf8String = "Acción";
string propEncodeString = string.Empty;

byte[] utf8_Bytes = new byte[utf8String.Length];
for (int i = 0; i < utf8String.Length; ++i)
{
   utf8_Bytes[i] = (byte)utf8String[i];
}

propEncodeString = Encoding.UTF8.GetString(utf8_Bytes, 0, utf8_Bytes.Length);

出力は次のようになります

アクシオン

day’sは日を表示します

DecodeFromUtf8();を呼び出します。

private static void DecodeFromUtf8()
{
    string utf8_String = "day’s";
    byte[] bytes = Encoding.Default.GetBytes(utf8_String);
    utf8_String = Encoding.UTF8.GetString(bytes);
}

1
ありがとう!スペイン語でも機能しますが、問題は東部言語(韓国語)では機能しないことです。インターネットで8ビットからUTF-8への変換アルゴリズムを探していますが、まだうまくいきません。
Gaara

これは、英語では機能しない文字列の例です。日を表示する代わりに、フロントエンドアプリは次を表示しています:day’s
Gaara

わかりました、それを
いじっ

私がテストしたところ、1日が返されました。テストした静的メソッドを貼り付けます。実際には、@ anothershruberyが提供したものと同じです
MethodMan

DecodeFromUtf8(string utf8string);を渡すことで、そのメソッドを変更できます。
MethodMan

12

コードはUTF8エンコードされたバイトのシーケンスを読み取り、8ビットエンコーディングを使用してそれらをデコードします。

バイトをUTF8としてデコードするには、そのコードを修正する必要があります。

あるいは(理想的ではありませんが)、不正な文字列を元のバイト配列に変換し(誤ったエンコードを使用してエンコードする)、バイトをUTF8として再デコードすることもできます。


ありがとう!問題は、サードパーティアプリがC ++であり、コードがC#であるため、デコードはこれら2つの間の「ブリッジ」で行われると思います。
Gaara


5

mysqlデータベースに文字列を保存する場合は、次のようにします:->

phpmyadmin [またはその他のコントロールパネル]のデータベースフィールド構造は、utf8-gerneral-ciに設定する必要があります。

2)文字列を変更する必要があります[Ex。textbox1.text]をバイトに変換するため

2-1)byte [] st2を定義します。

2-2)文字列[textbox1.text]をユニコード[mmultibyte string]に変換します。

byte[] st2 = System.Text.Encoding.UTF8.GetBytes(textBox1.Text);

3)クエリの前にこのSQLコマンドを実行します。

string mysql_query2 = "SET NAMES 'utf8'";
cmd.CommandText = mysql_query2;
cmd.ExecuteNonQuery();

3-2)次に、この値を、たとえば名前フィールドに挿入します。

cmd.CommandText = "INSERT INTO customer (`name`) values (@name)";

4)多くのソリューションがそれに注意を払っていなかった主な仕事は以下の行です:以下のようにコマンドパラメーターに追加する代わりにaddwithvalueを使用する必要があります:

cmd.Parameters.AddWithValue("@name",ut);

++++++++++++++++++++++++++++++++++は、データベースサーバーで実際のデータを????ではなく楽しむ


3

以下のコードスニペットを使用してcsvファイルからバイトを取得します

protected byte[] GetCSVFileContent(string fileName)
    {
        StringBuilder sb = new StringBuilder();
        using (StreamReader sr = new StreamReader(fileName, Encoding.Default, true))
        {
            String line;
            // Read and display lines from the file until the end of 
            // the file is reached.
            while ((line = sr.ReadLine()) != null)
            {
                sb.AppendLine(line);
            }
        }
        string allines = sb.ToString();


        UTF8Encoding utf8 = new UTF8Encoding();


        var preamble = utf8.GetPreamble();

        var data = utf8.GetBytes(allines);


        return data;
    }

以下を呼び出して、添付ファイルとして保存してください

           Encoding csvEncoding = Encoding.UTF8;
                   //byte[] csvFile = GetCSVFileContent(FileUpload1.PostedFile.FileName);
          byte[] csvFile = GetCSVFileContent("Your_CSV_File_NAme");


        string attachment = String.Format("attachment; filename={0}.csv", "uomEncoded");

        Response.Clear();
        Response.ClearHeaders();
        Response.ClearContent();
        Response.ContentType = "text/csv";
        Response.ContentEncoding = csvEncoding;
        Response.AppendHeader("Content-Disposition", attachment);
        //Response.BinaryWrite(csvEncoding.GetPreamble());
        Response.BinaryWrite(csvFile);
        Response.Flush();
        Response.End();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.