190 votes

Comment puis-je transformer une chaîne de caractères en UTF-8 en C# ?

J'ai une chaîne de caractères que je reçois d'une application tierce et je voudrais l'afficher correctement dans n'importe quelle langue en utilisant C# sur ma Surface Windows.

En raison d'un encodage incorrect, un morceau de ma chaîne ressemble à ceci en espagnol :

Acción

alors qu'il devrait ressembler à ceci :

Acción

Selon la réponse à cette question : Comment connaître l'encodage des chaînes de caractères en C# le codage que je reçois devrait déjà être en UTF-8, mais il est lu sur Encoding.Default (probablement ANSI ?).

J'essaie de transformer cette chaîne en UTF-8 réel, mais l'un des problèmes est que je ne peux voir qu'un sous-ensemble de la classe Encoding (uniquement les propriétés UTF8 et Unicode), probablement parce que je suis limité à l'API de surface de Windows.

J'ai essayé quelques extraits que j'ai trouvés sur Internet, mais aucun d'entre eux ne s'est avéré efficace jusqu'à présent pour les langues orientales (c'est-à-dire le coréen). Voici un exemple :

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

J'ai également essayé d'extraire la chaîne dans un tableau d'octets, puis d'utiliser 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);

Avez-vous d'autres idées que je pourrais essayer ?

5 votes

Votre problème vient du code qui a créé la chaîne (à partir d'un flux ou d'un byte[]) en premier lieu. Veuillez montrer ce code.

1 votes

@Oded : Les chaînes de caractères .Net sont stockées en mémoire en UTF16, mais Encoding.Default renvoie la page de code ANSI du système.

0 votes

Voici un exemple de chaîne qui ne fonctionne pas en anglais : au lieu d'afficher day's , mon application frontale affiche : day’s.

321voto

anothershrubery Points 6104

Comme vous le savez, la ficelle arrive en tant que Encoding.Default vous pourriez simplement utiliser :

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

Une autre chose dont vous devez vous souvenir : si vous utilisez Console.WriteLine pour afficher des chaînes de caractères, vous devez aussi écrire Console.OutputEncoding = System.Text.Encoding.UTF8; ! !! Ou toutes les chaînes utf8 seront affichées en gbk...

0 votes

Cela fonctionne aussi, c'est en fait beaucoup plus beau que ma réponse qui fonctionne aussi, je vous donne un +1, beau travail.

0 votes

Merci ! Le problème est que, comme je l'ai mentionné dans la description, l'API pour la surface est incomplète (pas de Encoding.Default disponible pour moi).

4 votes

@Gaara : Essayez Encoding.GetEncoding(...) vous devrez trouver le nom de l'encodage réel qui a été incorrectement utilisé à l'autre bout.

24voto

DJ KRAZE Points 8546
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);

La sortie devrait ressembler à

Acción

affichages du jour du jour

appelez DecodeFromUtf8() ;

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

1 votes

Merci ! Cela fonctionne en espagnol, le problème est que la même chose ne fonctionnerait pas pour les langues orientales (par exemple le coréen). J'essaye de chercher un algorithme de conversion 8-bit vers UTF-8 sur internet, mais toujours pas de chance.

0 votes

Voici un exemple de chaîne qui ne fonctionne pas en anglais : au lieu d'afficher day's , mon application frontale affiche : day’s.

0 votes

Ok, laissez-moi m'amuser avec et voir ce que je peux trouver.

13voto

SLaks Points 391154

Votre code lit une séquence d'octets codés UTF8 et les décode en utilisant un codage 8 bits.

Vous devez corriger ce code pour décoder les octets en UTF8.

Alternativement ( pas idéal ), vous pouvez reconvertir la mauvaise chaîne en tableau d'octets d'origine - en l'encodant à l'aide de l'encodage incorrect - puis redécoder les octets en UTF8.

0 votes

Merci ! Le problème est que l'application tierce est en C++, alors que mon code est en C#, donc je suppose que le décodage se fait dans le "pont" entre les deux.

5voto

Si vous voulez enregistrer une chaîne de caractères dans la base de données mysql, faites ceci:->

La structure des champs de votre base de données dans phpmyadmin [ ou tout autre panneau de contrôle] doit être configurée en utf8-gerneral-ci.

2) vous devez changer votre chaîne [Ex. textbox1.text] en octet, ainsi

2-1) définir byte[] st2 ;

2-2) convertissez votre chaîne [textbox1.text] en unicode [ mmultibyte string] par :

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

3) exécutez cette commande sql avant toute requête :

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

3-2) Vous devez maintenant insérer cette valeur dans le champ du nom, par exemple, par :

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

4) la principale raison pour laquelle de nombreuses solutions n'ont pas été prises en compte est la ligne ci-dessous : vous devez utiliser addwithvalue au lieu de add en paramètre de commande comme ci-dessous :

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

++++++++++++++++++++++++++++++++++ profiter de données réelles dans votre serveur de base de données au lieu de ? ???

3voto

lizyjeywin Points 11

Utilisez l'extrait de code ci-dessous pour obtenir les octets du fichier 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;
    }

Appelez le formulaire ci-dessous et enregistrez-le en pièce jointe

           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();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X