【问题标题】:How do I get a string type of a hex value that represents an upper ascii value character如何获取表示上 ascii 值字符的十六进制值的字符串类型
【发布时间】:2008-09-19 21:32:27
【问题描述】:

我们的应用程序的一部分解析了 RTF 文档,我们遇到了一个翻译不好的特殊字符。在 Word 中查看时,该字符是省略号 (...),它在 RTF 中编码为 ('85)。

在我们的 vb 代码中,我们将十六进制 (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;
}

【问题讨论】:

    标签: c# rtf


    【解决方案1】:

    这对我来说似乎是一个字符编码问题。 Unicode 不包含任何数字在 ASCII 128-255 范围内的字符,因此尝试转换字符 133 将失败。

    需要首先使用正确的解码将其转换为字符,Convert.toChar 似乎使用的是 UTF-16。

    有时会有一个手动位操作技巧将字符从大写 ASCII 转换为适当的 unicode 字符,但由于省略号不在大多数广泛使用的扩展 ASCII 代码页中,这不太可能在这里工作。

    您真正想做的是使用Encoding.GetString(Byte[]) 方法,并使用正确的编码。将您的值放入一个字节数组,然后 GetString 以获取该字符的 C# 本机字符串。

    您可以在RTF Wikipedia page 上了解有关 RTF 字符编码的更多信息。

    仅供参考:水平省略号是character U+2026 (pdf)

    【讨论】:

      【解决方案2】:

      您的原始代码非常适合我。它能够将任何从 00 到 FF 的十六进制转换为适当的字符。使用 vs2008。

      【讨论】:

        【解决方案3】:
        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
        }
        

        【讨论】:

          【解决方案4】:

          我的猜测是 .NET 中的 Char 实际上是两个字节(16 位),因为它们是 UTF-16 编码的。也许您只是在捕获/写入值的第一个字节?

          基本上,您之后是否对 char 值做一些假设它是 8 位而不是 16 位的事情,因此要截断它?

          【讨论】:

            【解决方案5】:

            您可能在读取 RTF 文件时使用默认字符编码,即 UTF-8,而实际存储 RTF 文件时使用的是“windows-1252”扩展 ASCII 拉丁编码。

            C# 字符串使用 16 位 unicode 位宽的字符格式。将 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.
            }
            

            【讨论】:

            • 很好的答案,当我在创作我的作品时,你已经设法回答了。需要注意的是,RTF 文件并不总是 windows 1252,它们支持各种编码,所以在使用之前确保它是正确的编码。
            【解决方案6】:

            这里有一些粗略的代码应该适合你:

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

            【讨论】:

            • 可以跳过尾随的 ToCharArray(),将返回的字符串转换为 char 数组,然后再转换回字符串可能没有用。这是一种获取特定 char 值的方法,原始代码示例希望返回一个 Char 而不是字符串。
            【解决方案7】:

            只需使用我从 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;
                }
            

            您可以修改“当前字符”条件以删除任何需要消除的字符(如此处所示,您不会得到任何 0x00 字符、(char)127 或 0x57 字符)。

            此处为 ASCII/十六进制表:http://www.cs.mun.ca/~michael/c/ascii-table.html

            克里斯的网站:http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/

            -汤姆

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-03-11
              • 2016-06-11
              • 1970-01-01
              • 1970-01-01
              • 2019-07-27
              • 1970-01-01
              • 2018-08-12
              相关资源
              最近更新 更多