【问题标题】:ASCii value of ü in C++C++中ü的ASCII值
【发布时间】:2013-04-08 13:04:46
【问题描述】:

根据that site ASCii 的 ü 值为 129,但是当我运行 printf("%d",'ü') 代码时,输​​出为 -4。这是什么原因?

【问题讨论】:

  • 它不是 ASCII。它是扩展的 ASCII。
  • 欢迎来到字符编码的奇妙世界。
  • 绝对不能保证您的编译器的执行字符集是 ASCII,尤其是不能保证它是特定的扩展 ASCII 集。
  • ASCII 取决于语言
  • 它不是 ASCII。 ASCII 字符不包括任何重音/等字符。

标签: c++ windows encoding ascii


【解决方案1】:

您获得 -4 的事实基本上纯属偶然,因为这取决于您的环境的语言环境设置和编译器的实现。

其他人已经指出,根据您的平台是否认为 char 是有符号的,将 char 值作为整数打印可能会为 0x80 或更高的值产生负数。


至于编码(请注意,下面的列表绝不是详尽的):

ü 没有 ASCII 值,因为 (US-) ASCII 仅定义最大为 0x7f (127) 的字符。

IBM Codepage 437850 (DOS) 在 0x81 处具有 ü,根据签名为 -127 或 129。

ISO-8859-1 through -4, -9, -10, and -13 through -16 以及 Windows 代码页 125012520xfc (-4 / 252) 处具有 ü。其他 ISO-8859 编码的字符集中没有 ü

UTF-8 - 每个人都应该使用它而不是过去的那些 8 位编码,用于 reasonsvariety - 将 ü 编码为两字节序列 0xc3 0xbc

我整理了一个并排的代码页供个人使用,如果您有兴趣,可以在my homepage 找到它。


一旦您接受了这一点,请注意该标准定义了两个character sets,一个用于表示源代码,一个用于表示可执行代码中的字符串。两者都不包含超出基本 A-Z 范围的任何字符,两者实际上可能不同(想想交叉编译器),并且都没有定义其数字表示 - 即您可能实际上正在查看 EBCDIC,其中字符甚至没有编码连续 值(即assert( 'Z' - 'A' == 26 ) 会失败)。

你觉得这很有趣吗?好吧,基本上你的机器甚至不需要提供像@ 这样的字符,因为那是ASCII,但不是基本字符集的一部分。 ;-)

一般来说,一旦您在源代码中使用非 ASCII 字符,您就会留下明确定义的行为,并且依赖于实现/环境。

【讨论】:

  • 关于在源代码中使用非 ASCII:我认为将 UTF-8 用于源文件正在慢慢变得正常或至少可以接受。在任何相对较新的编译器/语言上,它也应该是完美定义的行为。
  • @hyde:我个人觉得每个软件都应该适当地支持UTF-8,但是源代码应该是严格的ASCII-7。为简单起见,标识符和 cmets 无论如何都应该是简单的英语(这来自德语)。程序字符串应位于 external 文本文件(编码为 UTF-8)中,并由本地化框架处理。 ASCII-7 是唯一可以可靠、自动测试 的编码。这是您的环境应该在每次提交之前设置的事情。 (当您使用它时,还要检查空格与制表符缩进。)
  • 这是来自亲身经历的痛苦。我们实际上浪费了 的时间来寻找和修复由 š 的模糊性导致的错误(Windows 中的 0x9a,ISO-8859-15 中的 0xa8,UTF-8 中的 0xc5 0xa1)。太多的人,包括其他熟练的开发人员,不知道、不关心或不时忘记字符编码。文本为 UTF-8,源为 ASCII-7。恕我直言。
  • 我同意使用 UTF-8 需要更加小心,但我已经完成了在使用纯 ASCII 源时将 \xxx 代码写入字符串文字以及编写不太理想的内容cmets 由于缺乏原生字符,所以基于此我想说,iff 它有利于项目,决定使用 UTF-8 是明智的。它需要向每个开发人员简要介绍其中的含义,但糟糕的项目管理或开发人员纪律是一个不好的借口。
  • @hyde:同意 - 如果对项目有利,UTF-8 是唯一明智的选择。 (即使在 Unicode 编码中,因为它是最可移植的,也是唯一一个你不会弄错 reendianess 的编码,这是 other 主题,令人惊讶的是许多开发人员竟然对此一无所知。)跨度>
【解决方案2】:

在您的系统上 char 是有符号类型。打印前应先转换为无符号类型。

printf("%d", (unsigned char)'ü');

这是否会打印您期望的 129 是另一回事,但它至少会在您的执行字符集中打印 ü 的编码

【讨论】:

    【解决方案3】:

    %d 正在打印一个带符号的十进制数,对于一个字节,它将在 -128-127 的范围内打印)。您可能希望使用无符号 (%u) 来输出预期的 0-255。

    【讨论】:

    • 可能你真的想要printf("%d", (unsigned char)'ü')。负整数不会以直接的方式转换为无符号值。
    • Char 可以是有符号或无符号的(C 和 C++ 标准允许)。如果是 8 位,则可以是 -128 到 +127 或 0 到 255。
    • @AlexeyFrunze:...或 -127 到 +127(补码或符号/大小)。
    • 同意。由于输出为负值,我假设目标平台的字符已签名。
    • @JerryCoffin:或者它甚至可能根本不是 8 位的。 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2013-01-12
    • 1970-01-01
    相关资源
    最近更新 更多