【问题标题】:Why is this appearing in my c# strings: £为什么这会出现在我的 c# 字符串中:
【发布时间】:2009-03-30 10:07:23
【问题描述】:

我在 c# 中有一个字符串,初始化如下:

string strVal = "£2000";

但是,每当我写出这个字符串时,都会写下以下内容:

2000 英镑

它不会用美元来做这件事。

我用来写出值的示例代码:

System.IO.File.AppendAllText(HttpContext.Current.Server.MapPath("/logging.txt"), strVal);

我猜这与本地化有关,但如果 c# 字符串只是 unicode,这肯定可以工作吗?

澄清:更多信息,Jon Skeet 的回答是正确的,但是当我对字符串进行 URLEncode 时,我也遇到了问题。有没有办法防止这种情况发生?

所以 URL 编码的字符串如下所示:

“%c2%a32000”

%c2 = Â %a3 = 英镑

如果我编码为 ASCII,£ 输出为 ?

还有什么想法吗?

【问题讨论】:

    标签: c# .net asp.net localization string


    【解决方案1】:

    AppendAllText 正在用 UTF-8 写出文本。

    你用什么看它?可能是它不理解 UTF-8,或者没有先尝试 UTF-8。告诉您的编辑器/查看器这是一个 UTF-8 文件,一切都应该很好。或者,使用 AppendAllText 的重载,它允许您指定编码并使用对您最方便的编码。

    编辑:针对您编辑的问题,使用 ASCII 编码时失败的原因是 £ 不在 ASCII 字符集中(即 Unicode 0-127)。

    从外观上看,URL 编码也使用 UTF-8。同样,如果您想使用不同的编码,请将其指定为接受编码的 HttpUtility.UrlEncode 重载。

    【讨论】:

      【解决方案2】:

      在 HTML 页面和 HTTP 标头中使用的 URL 的默认字符集称为 ISO-8859-1 或 ISO Latin-1。

      它与 UTF-8 不同,也与 ASCII 不同,但它确实适合每个字符一个字节。 0 到 127 的范围很像 ASCII,0 到 255 的整个范围与 Unicode 的 0000-00FF 范围相同。

      因此,您可以通过将每个字符转换为一个字节来从 C# 字符串生成它,或者您可以使用 Encoding.GetEncoding("iso-8859-1") 获取一个对象来为您进行转换。

      (在此字符集中,英磅符号为 163。)

      背景

      The RFC says 未编码的文本必须限制在传统的 7 位 US ASCII 范围内,并且必须对其他任何内容(加上特殊的 URL 分隔符)进行编码。但它留下了一个问题,即 8 位范围的上半部分使用什么字符集,使其依赖于 URL 出现的上下文。

      该上下文是由另外两个标准 HTTP 和 HTML 定义的,它们确实指定了默认字符集,并且它们共同对实现者产生了一种实际上不可抗拒的力量,即假设地址栏包含引用 ISO- 的百分比编码。 8859-1。

      ISO-8859-1 is the character set of text-based content sent via HTTP 除非另有说明。因此,当 URL 字符串出现在 HTTP GET 标头中时,它应该在 ISO-8859-1 中。

      另一个因素是 HTML 也使用 ISO-8859-1 作为其默认值,并且 URL 通常源自 HTML 页面中的链接。因此,当您在记事本中制作一个简单的最小 HTML 页面时,您在该文件中键入的 URL 采用 ISO-8859-1 格式。

      它有时被描述为标准中的“漏洞”,但实际上并非如此;只是 HTML/HTTP 填补了 RFC 为 URL 留下的空白。

      因此,例如,this page 上的建议:

      字符的 URL 编码包括 一个“%”符号,后跟 两位十六进制表示 ISO-Latin 的(不区分大小写) 字符的代码点。

      (ISO-Latin 是 IS-8859-1 的另一个名称)。

      理论就讲这么多。将此粘贴到记事本中,将其保存为 .html 文件,然后在几个浏览器中打开它。点击链接,Google 应该会搜索英镑。

      <HTML>
        <BODY>
          <A href="http://www.google.com/search?q=%a3">Test</A>
        </BODY>
      </HTML>
      

      它适用于 IE、Firefox、Apple Safari、Google Chrome - 我目前没有其他可用的。

      【讨论】:

      • 这完美地解决了我的问题。只需将 iso-8859-1 编码放在我的 UrlEncode 上即可。
      • 您有关于 URL 的默认字符编码信息的来源吗?我认为这是那些令人讨厌的未指明的事情之一。我没有争议,但我想看看它在哪里被指定为默认值。顺便说一句,您还可以使用 Encoding.GetEncoding(28591) 来获取 ISO-8859-1。
      • 我很感兴趣为什么 URLEncode 不会自动进行这种转换。由于 C# 中的字符串是 UTF-8,因此让 URLEncode 方法接受这样的字符串并正确编码将是相当直观的。除非我手动指定正确的编码,否则不会摔倒?
      • @tsaunders:不,字符串不是 UTF-8。它们是 UTF-16。 UrlEncode 默认使用 UTF-8。正如我所说,我认为 URL 规范没有指定用于 UrlEncoded 字符的编码,这很痛苦。
      • @Jon Skeet - 添加了一些背景;它不在 URL 规范中,但在 HTML 和 HTTP 规范中。
      【解决方案3】:

      请注意,%a3 不能以 ASCII(7 位,Basic Latin)编码。

      Pound Sign (down the page)Latin-1 编码的一部分。

      【讨论】:

        【解决方案4】:

        我注意到只有在使用长字符串(超过 4000 个)字符时才会发生这种情况。我的解决方案是在接收到数据库中的参数后,我只需将 Â 符号替换为空。 请注意,实际上可能需要 Â,如果是这种情况,则此解决方案不合适。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多