C #에서 문자열을 UTF-8로 변환하는 방법은 무엇입니까?


146

타사 앱에서받은 문자열이 있으며 Windows Surface에서 C #을 사용하여 모든 언어로 올바르게 표시하고 싶습니다.

잘못된 인코딩으로 인해 내 문자열 부분은 스페인어로 다음과 같습니다.

아키 엔

반면 다음과 같이 보일 것입니다 :

아치 온

이 질문에 대한 답변에 따르면 : C #에서 문자열 인코딩을 아는 방법은 수신중인 인코딩이 이미 UTF-8로 제공되어야하지만 Encoding.Default (아마도 ANSI?)에서 읽습니다.

이 문자열을 실제 UTF-8로 변환하려고하지만 문제 중 하나는 Encoding 클래스의 하위 집합 (UTF8 및 유니 코드 속성 만)을 볼 수 있다는 것입니다. 아마도 Windows Surface 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
문제는 문자열을 생성 한 코드 (스트림 또는 바이트 [])에서 처음 발생합니다. 그 코드를 보여주세요.
SLaks

1
@Oded : .Net 문자열은 메모리에 UTF16으로 저장되지만 Encoding.Default시스템의 ANSI 코드 페이지를 반환합니다.
SLaks

여기에 영어 작동하지 않습니다 문자열의 예입니다 : 대신 하루를 표시하는 내 프런트 엔드 응용 프로그램이 표시됩니다 : 다야 € ™ s의
가아라

답변:


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 전제는 mojibake 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

여기에 영어 작동하지 않습니다 문자열의 예입니다 : 대신 하루를 표시하는 내 프런트 엔드 응용 프로그램이 표시됩니다 : 다야 € ™ s의
가아라

알았어 내가 그걸 엉망으로 만들 수 있는지 보자
MethodMan

나는 테스트했고 그것은 하루를 반환합니다. 나는 테스트 한 정적 메소드를 붙여 넣을 것입니다. 실제로 @anothershrubery가 제공 한 것과 동일합니다
MethodMan

DecodeFromUtf8 (string utf8string);을 전달하여 해당 메소드를 변경할 수 있습니다.
MethodMan

12

코드가 UTF8로 인코딩 된 바이트 시퀀스를 읽고 8 비트 인코딩을 사용하여 디코딩합니다.

바이트를 UTF8로 디코딩하려면 해당 코드를 수정해야합니다.

또는 ( 이상적이지 않은 ) 잘못된 문자열을 잘못된 인코딩을 사용하여 인코딩하여 원래 바이트 배열로 다시 변환 한 다음 바이트를 UTF8로 다시 디코딩 할 수 있습니다.


감사! 문제는 타사 응용 프로그램이 C ++이고 코드가 C #이므로 디코딩이 두 브리지 사이의 "브리지"에서 발생한다고 생각합니다.
Gaara


5

mysql 데이터베이스에 문자열을 저장하려면 다음을 수행하십시오.

데이터베이스 필드 구조 i phpmyadmin [또는 다른 제어판]은 utf8-gerneral-ci로 설정해야합니다

2) 문자열을 변경해야합니다 [예 : textbox1.text]를 바이트로 변환

2-1) 바이트 정의 [] 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) 이제이 값을 예를 들어 name 필드에 삽입해야합니다.

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

4) 많은 솔루션이주의를 기울이지 않은 주요 작업은 다음과 같습니다. 아래와 같이 명령 매개 변수에 add 대신 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.