2008-09-19 7 views
0

Une partie de notre application analyse les documents RTF et nous avons trouvé un caractère spécial qui ne se traduit pas correctement. Quand il est vu dans Word, le personnage est un elipsis (...), et il est encodé dans le RTF en tant que ('85).Comment puis-je obtenir un type de chaîne d'une valeur hexadécimale qui représente un caractère de valeur ASCII supérieur

Dans notre code vb nous avons converti l'hexagone (85) int (133), puis a fait Chr (133) pour revenir (...)

Voici le code en C# - problème est cela ne travailler pour des valeurs supérieures à 127. Des idées?

Indicatif téléphonique:

// S is Hex number!!! 
return Convert.ToChar(HexStringToInt(s)).ToString(); 

Méthode d'assistance:

private static int HexStringToInt(string hexString) 
{ 
    int i; 

    try 
    { 
     i = Int32.Parse(hexString, NumberStyles.HexNumber); 
    } 
    catch (Exception ex) 
    { 
     throw new ApplicationException("Error trying to convert hex value: " + hexString, ex); 
    } 

    return i; 
} 

Répondre

0
private static int HexStringToInt(string hexString) 
{ 
    try 
    { 
     return Convert.ToChar(hexString); 
    } 
    catch (FormatException ex) 
    { 
     throw new ArgumentException("Is not a valid hex character.", "hexString", ex); 
    } 
    // Convert.ToChar() will throw an ArgumentException also 
    // if hexString is bad 
} 
0

Je dirais qu'un char dans .NET est en fait deux octets (16 bits), car ils sont UTF -16 codé. Peut-être que vous n'attrapez/n'écrivez que le premier octet de la valeur?

Fondamentalement, faites-vous quelque chose avec la valeur de char après cela qui suppose que c'est 8 bits au lieu de 16, et le tronque donc?

0

Vous utilisez probablement le codage de caractères par défaut lors de la lecture dans le fichier RTF, qui est UTF-8, lorsque le fichier RTF est réellement stocké en utilisant le codage latin ASCII étendu "windows-1252".

Les chaînes C# utilisent un format de caractères 16 bits unicode. La traduction du caractère 0x85 de Windows-1252 en son équivalent unicode implique un mappage compliqué, puisque les points de code (numéros de caractères) sont très différents. Heureusement, Windows peut faire le travail pour vous.

Vous pouvez modifier la manière dont les caractères sont convertis lors de la lecture dans le texte en spécifiant explicitement le codage source lors de l'ouverture du flux.

using System.IO; 
using System.Text.Encoding; 

using (TextReader tr = new StreamReader(path_to_RTF_file, Encoding.GetEncoding(1252))) 
{ 
    // Read from the file as usual. 
} 
+0

Bonne réponse, vous auriez réussi à répondre pendant que je composais la mienne. Une mise en garde, les fichiers RTF ne sont pas toujours windows 1252, ils prennent en charge un assortiment de codages, alors assurez-vous que c'est le bon codage avant de l'utiliser. – davenpcj

1

Le code original fonctionne parfaitement bien pour moi. Il est capable de convertir n'importe quel hex de 00 à FF en caractère approprié. En utilisant vs2008.

2

Cela ressemble à un problème de codage de caractères pour moi. Unicode n'inclut aucun caractère avec des nombres dans la plage supérieure ASCII 128-255, donc essayer de convertir le caractère 133 échouera.

Besoin de le convertir d'abord en un caractère en utilisant le décodage approprié, Convert.toChar semble utiliser UTF-16. Parfois, il y a un hack de manipulation manuelle pour convertir le caractère du ASCII supérieur au char Unicode approprié, mais puisque l'ellipse n'était pas dans la plupart des pages de code ASCII étendues largement utilisées, cela ne marchera probablement pas ici.

Ce que vous voulez vraiment faire est d'utiliser la méthode Encoding.GetString(Byte[]), avec le codage approprié. Mettez votre valeur dans un tableau d'octets, puis GetString pour obtenir la chaîne native C# pour le caractère.

Vous pouvez en savoir plus sur les codages de caractères RTF sur le RTF Wikipedia page. FYI: L'ellipse horizontale est character U+2026 (pdf).

0

est ici un code approximatif qui devrait fonctionner pour vous:

// Convert hex number, which represents an RTF code-page escaped character, 
// to the desired character (uses '85' from your example as a literal): 
var number = int.Parse("85", System.Globalization.NumberStyles.HexNumber); 
Debug.Assert(number <= byte.MaxValue); 

byte[] bytes = new byte[1] { (byte)number }; 
char[] chars = Encoding.GetEncoding(1252).GetString(bytes).ToCharArray(); 
// or, use: 
// char[] chars = Encoding.Default.GetString(bytes).ToCharArray(); 

string result = new string(chars); 
+0

Peut ignorer ce ToCharArray() de fin, la conversion de la chaîne retournée à un tableau de caractères, puis retour à une chaîne n'est probablement pas utile. C'est un moyen d'obtenir la valeur de char spécifique, l'exemple de code original voulait qu'une chaîne Char not soit retournée. – davenpcj

0

Il suffit d'utiliser cette fonction que je Modifiés (très légèrement) sur le site Web de Chris:

private static string charScrubber(string content) 
    { 
     StringBuilder sbTemp = new StringBuilder(content.Length); 
     foreach (char currentChar in content) 
     { 
      if ((currentChar != 127 && currentChar > 1)) 
      { 
       sbTemp.Append(currentChar); 
      } 
     } 

     content = sbTemp.ToString(); 
     return content; 
    } 

Vous pouvez modifier le « Char en cours "condition pour enlever n'importe quel caractère est nécessaire pour être éliminé (comme apparaissant ici, vous n'obtiendrez aucun caractère 0x00, ou le caractère (char) 127, ou 0x57).

ASCII/Hex Table ici: http://www.cs.mun.ca/~michael/c/ascii-table.html

site Chris: http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/

-Tom