C#UTF8输出保持编码字符完整

时间:2010-05-29 23:47:45

标签: c# utf-8

我有一个非常简单的问题,我似乎无法理解。

我有一个正确编码的UTF8-String我用Json.NET解析成一个JObject,摆弄一些值并将其写入命令行,保持编码的字符不变。

除了保持编码字符的完整部分外,一切都很有效。

代码:

var json = "{roster: [[\"Tulg\u00f4r\", 990, 1055]]}";
var j = JObject.Parse(json);
for (int i = 0; i < j["roster"].Count(); i++)
{
    j["roster"][i][1] = ((int)j["roster"][i][1]) * 3;
    j["roster"][i][2] = ((int)j["roster"][i][2]) * 3;
}
Console.WriteLine(JsonConvert.SerializeObject(j, Formatting.None));

实际输出:

{"roster":[["Tulgôr",2970,3165]]}

期望的输出:

{"roster":[["Tulg\u00f4r",2970,3165]]}

似乎我在谷歌的措辞不合适,因为没有任何有用的东西出现。我确信这是非常简单的事情,之后我会觉得很愚蠢。 :)

2 个答案:

答案 0 :(得分:4)

从JsonConvert.SerializeObject获取输出并通过一个帮助器方法运行它,该方法将所有非ASCII字符转换为它们的转义(“\ uHHHH”)等效字符。下面给出了一个示例实现。

// Replaces non-ASCII with escape sequences;
// i.e., converts "Tulgôr" to "Tulg\u00f4r".
private static string EscapeUnicode(string input)
{
    StringBuilder sb = new StringBuilder(input.Length);
    foreach (char ch in input)
    {
        if (ch <= 0x7f)
            sb.Append(ch);
        else
            sb.AppendFormat(CultureInfo.InvariantCulture, "\\u{0:x4}", (int) ch);
    }
    return sb.ToString();
}

您可以按如下方式调用它:

Console.WriteLine(EscapeUnicode(JsonConvert.SerializeObject(j, Formatting.None)));

(请注意,我不会特别处理非BMP字符,因为我不知道你的第三方应用程序在代表U时是否需要“\ U00010000”或“\ uD800 \ uDC00”(或其他!)万。)

答案 1 :(得分:1)

我不确定我在这里看到问题。实际输出包含unicode字符,在使用\ u语法指定后正确解释。它包含正确的字符,因此包含正确的“字节”。当然它将是一个.Net字符串,而不是UTF-8。