0

アプリの一部で RTF ドキュメントを解析していますが、うまく翻訳されていない特殊文字に遭遇しました。Word で表示すると、文字は省略記号 (...) であり、RTF では ('85) としてエンコードされます。

私たちの VB コードでは、16 進数 (85) を int(133) に変換し、Chr(133) を実行して (...) を返しました。

C# のコードは次のとおりです。問題は、127 を超える値では機能しないことです。何かアイデアはありますか?

呼び出しコード:

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

ヘルパー メソッド:

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;
}
4

7 に答える 7

2

これは、文字エンコーディングの問題のように見えます。Unicode には、上位 ASCII の 128 ~ 255 の範囲の数字を持つ文字は含まれないため、文字 133 を変換しようとすると失敗します。

最初に適切なデコードを使用して文字に変換する必要があります。Convert.toChar は UTF-16 を使用しているようです。

時々、文字を上位 ASCII から適切な Unicode 文字に変換する手動のビット操作ハックがありますが、省略記号は広く使用されている拡張 ASCII コードページのほとんどにないため、ここでは機能しそうにありません。

本当にやりたいことは、適切なエンコーディングでEncoding.GetString(Byte[])メソッドを使用することです。値をバイト配列に入れ、次に GetString を入力して、文字の C# ネイティブ文字列を取得します。

RTF ウィキペディア ページで、RTF 文字エンコーディングの詳細を確認できます。

参考: 横の省略記号は文字 U+2026 (pdf)です。

于 2008-09-19T22:03:41.490 に答える
1

あなたの元のコードは、私にとっては問題なく動作します。00 から FF までの任意の 16 進数を適切な文字に変換できます。vs2008を使用。

于 2008-09-19T22:00:17.397 に答える
0

RTFファイルが「windows-1252」拡張ASCIIラテンエンコーディングを使用して実際に保存されている場合、RTFファイル(UTF-8)を読み取るときに、デフォルトの文字エンコーディングを使用している可能性があります。

C#文字列は、16ユニコードビット幅の文字形式を使用します。windows-1252文字の0x85を同等のUnicodeに変換するには、コードポイント(文字番号)が大きく異なるため、複雑なマッピングが必要になります。幸いなことに、Windowsはあなたのために仕事をすることができます。

ストリームを開くときにソースエンコーディングを明示的に指定することにより、テキストを読み取るときに文字が変換される方法を変更できます。

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.
}
于 2008-09-19T21:57:10.787 に答える
0

私の推測では、.NET の Char は UTF-16 でエンコードされているため、実際には 2 バイト (16 ビット) です。たぶん、値の最初のバイトだけをキャッチ/書き込みしていますか?

基本的に、後で char 値を使用して、16 ではなく 8 ビットであると想定して切り捨てていることはありますか?

于 2008-09-19T21:46:38.100 に答える
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
}
于 2008-09-19T21:34:34.773 に答える
0

クリスのウェブサイトから(ごくわずかに)変更したこの関数を使用してください。

    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;
    }

「現在の Char」条件を変更して、削除する必要がある文字を削除できます (ここに表示されているように、0x00 文字、(char)127、または 0x57 文字は取得されません)。

ASCII/Hex テーブル: http://www.cs.mun.ca/~michael/c/ascii-table.html

Chris のサイト: http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/

-トム

于 2009-01-17T00:10:33.117 に答える
0

これはあなたのために働くはずの大まかなコードです:

// 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);
于 2008-09-20T06:09:23.397 に答える