107 votes

C# Convertir une chaîne de caractères de UTF-8 en ISO-8859-1 (Latin1) H

J'ai fait des recherches sur ce sujet et j'ai regardé toutes les réponses, mais je ne comprends toujours pas.

En fait, j'ai besoin de convertir une chaîne UTF-8 en ISO-8859-1 et je le fais en utilisant le code suivant :

Encoding iso = Encoding.GetEncoding("ISO-8859-1");
Encoding utf8 = Encoding.UTF8;
string msg = iso.GetString(utf8.GetBytes(Message));

Ma chaîne source est

Message = "ÄäÖöÕõÜü"

Mais malheureusement, ma chaîne de résultats devient

msg = "Ã?äÃ?öÃ?õÃ?ü

Qu'est-ce que je fais de mal ici ?

5 votes

Toutes les chaînes de caractères dans .NET sont stockées en interne en utilisant des caractères unicode. Il n'existe aucune notion de chaîne de caractères "Windows-1252", "iso-8859-1", "utf-8", etc. Essayez-vous de supprimer tous les caractères de votre chaîne qui n'ont pas de représentation dans la page de code Windows-1252 ?

1 votes

@IanBoyd En fait, un Chaîne de caractères est une séquence comptée d'unités de code UTF-16. (Malheureusement, le terme " Unicode " a été mal utilisé en Encoding.Unicode et dans l'API Win32. Unicode est un jeu de caractères, pas un encodage. UTF-16 est l'un des nombreux codages pour Unicode).

1 votes

Vous faites une action incorrecte : vous créez un tableau d'octets en encodage utf8, mais vous les lisez avec un décodeur iso. Si vous voulez faire une chaîne avec des symboles encodés, il suffit d'appeler string msg = iso.GetString(iso.GetBytes(Message)) ;

183voto

Nathan Baulch Points 7994

Utilisez Encodage.convertir pour ajuster le tableau d'octets avant de tenter de le décoder dans votre encodage de destination.

Encoding iso = Encoding.GetEncoding("ISO-8859-1");
Encoding utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(Message);
byte[] isoBytes = Encoding.Convert(utf8, iso, utfBytes);
string msg = iso.GetString(isoBytes);

7 votes

La doublure est Encoding.GetEncoding("ISO-8859-1").GetString(Encoding.Conver‌​t(Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1"), Encoding.UTF8.GetBytes(myString)))

1 votes

Si vous créez la chaîne vous-même dans C#/.Net, alors ce code n'est pas correct à 100%, vous devez encoder à partir de UTF-16 (qui est la variable "Unicode"). Parce que c'est la valeur par défaut. Donc UTF8 dans le code ci-dessus doit être changé en Unicode.

0 votes

Je recommande d'utiliser ceci : Encoding iso = Encoding.GetEncoding("ISO-8859-9") ; Parce que l'encodage turc couvre presque tous les alphabets étendus à partir du latin.

27voto

Je pense que votre problème est que vous supposez que les octets qui représentent la chaîne utf8 donneront la même chaîne lorsqu'ils seront interprétés comme autre chose (iso-8859-1). Et ce n'est tout simplement pas le cas. Je vous recommande de lire cet excellent article par Joel Spolsky.

1 votes

Excellent article en effet et avec le sens de l'humour ! J'étais confronté à un problème d'encodage aujourd'hui au travail et cet article m'a aidé.

16voto

Manu Points 10901

Essayez ça :

Encoding iso = Encoding.GetEncoding("ISO-8859-1");
Encoding utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(Message);
byte[] isoBytes = Encoding.Convert(utf8,iso,utfBytes);
string msg = iso.GetString(isoBytes);

0 votes

Pourquoi j'obtiens le même message utf-8 ? à la place du message j'ai passé la chaîne message=<name>sdjfhsjdf</name>.alors la même sortie est obtenue dans msg varieable.comment obtenir des données latines ?

0 votes

Cela fonctionne pour moi. N'oubliez pas d'inclure l'espace de nom System.Text.

2 votes

Encoding.Convert lève une exception de repli lors de la conversion si la chaîne de caractères ne contient pas de caractères iso.

8voto

Lasse V. Karlsen Points 148037

Vous devez réparer la source de la chaîne en premier lieu.

Une chaîne de caractères dans .NET n'est en fait qu'un tableau de points de code unicode de 16 bits, des caractères, de sorte qu'une chaîne de caractères n'est pas dans un codage particulier.

C'est lorsque vous prenez cette chaîne et la convertissez en un ensemble d'octets que le codage entre en jeu.

Dans tous les cas, la façon dont vous avez procédé, en encodant une chaîne de caractères dans un tableau d'octets avec un jeu de caractères, puis en la décodant avec un autre, ne fonctionnera pas, comme vous le voyez.

Pouvez-vous nous en dire plus sur l'origine de cette chaîne originale, et pourquoi vous pensez qu'elle a été mal codée ?

0 votes

Cela vient directement de App.config et je pensais que c'était UTF8 par défaut. Merci !

0 votes

L'encodage de ce fichier peut avoir un impact sur la façon dont il est interprété, c'est pourquoi je le vérifierais.

2 votes

Corrigez-moi si je me trompe, mais si je comprends bien, bien que techniquement elle "ne soit pas dans un encodage particulier", une chaîne .NET est un tableau d'octets qui correspond précisément à un fichier UTF-16, octet par octet (à l'exception du BOM). Elle utilise même les substituts de la même manière (ce qui semble être une astuce d'encodage). Bien sûr, vous souhaitez généralement stocker les fichiers en UTF-8 mais traiter les données en mémoire en 16 bits. (Ou 32 bits, pour éviter la complexité des paires de substituts, bien que je ne sois pas sûr que ce soit vraiment faisable).

7voto

Sander A Points 1

Le code semble un peu étrange. Pour obtenir une chaîne de caractères à partir d'un flux d'octets Utf8, tout ce que vous devez faire est :

string str = Encoding.UTF8.GetString(utf8ByteArray);

Si vous avez besoin de sauvegarder un flux d'octets iso-8859-1 quelque part, utilisez simplement : une ligne de code supplémentaire pour le précédent :

byte[] iso88591data = Encoding.GetEncoding("ISO-8859-1").GetBytes(str);

1 votes

C'est clairement la réponse la plus directe. Le problème dans le code est en fait que l'auteur semble supposer qu'une chaîne en C# peut déjà être stockée "en utilisant" un certain encodage, ce qui n'est tout simplement pas vrai ; ils sont toujours UTF16 en interne.

1 votes

Entièrement d'accord. Lorsque vous avez déjà l'UTF-16, il est assez difficile de le transformer en un encodage correct, car lorsque vous convertissez un tableau d'octets en chaîne de caractères avec un encodage incorrect, il y a déjà une perte d'informations.

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