【问题标题】:MinGW + GCC on Windows and UTF-8 charactersWindows 上的 MinGW + GCC 和 UTF-8 字符
【发布时间】:2014-12-20 11:59:17
【问题描述】:

我在使用 GCC 编译器和 Windows CMD 时遇到问题,因为我无法正确看到 UTF-8 字符。我有以下代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char caractere;
  int inteiro;
  float Float;
  double Double;

  printf("Tipo de Dados\tNúmero de Bytes\tEndereço\n");
  printf("Caractere\t%d bytes \t em %d\n", sizeof(caractere), &caractere);
  printf("Inteiro\t%d bytes \t em %d\n", sizeof(inteiro), &inteiro);
  printf("Float\t%d bytes \t\t em %d\n", sizeof(Float), &Float);
  printf("Double\t%d bytes \t em %d\n", sizeof(Double), &Double);

  printf("Caractere: %d bytes \t em %p\n", sizeof(caractere), &caractere);
  printf("Inteiro: %d bytes \t em %p\n", sizeof(inteiro), &inteiro);
  printf("Float: %d bytes \t\t em %p\n", sizeof(Float), &Float);
  printf("Double: %d bytes \t em %p\n", sizeof(Double), &Double);

  return 0;
}

然后我运行以下命令:

gcc pointers01.c -o pointers

我没有收到任何编译错误。但是当我执行生成的文件 (.exe) 时,它不显示 UTF-8 字符:

Tipo de Dados   Número de Bytes    Endereço
Caractere   1 bytes      em 2686751
Inteiro 4 bytes      em 2686744
Float   4 bytes          em 2686740
Double  8 bytes      em 2686728
Caractere: 1 bytes   em 0028FF1F
Inteiro: 4 bytes     em 0028FF18
Float: 4 bytes       em 0028FF14
Double: 8 bytes      em 0028FF08

我该如何解决这个问题?谢谢。

【问题讨论】:

  • 这是windows控制台的问题。有一些解决方法,但没有“但是”,即。没有任何东西在任何情况下都能可靠地工作。
  • 您知道一些解决方法吗?即使是“但是”。
  • 在此处查看已接受的答案和前两个 cmets(答案):stackoverflow.com/questions/388490/…(嗯,它也不是很详细……也许我在某处获得了另一个链接……)
  • 谢谢。它可以工作,但似乎有很多“但是”......我希望通过 Windows 10 他们可以改善这一点。 =D
  • 那么……你想写答案吗?还是我应该给出自己的答案? O.o

标签: c windows gcc utf-8 cmd


【解决方案1】:

遗憾的是,Windows 控制台对 UTF-8 的支持非常有限且有缺陷。

可以做什么:将代码页设置为65001 并使用其中一种支持它的字体,例如。 “露西达控制台”。代码页可以通过命令chcp 或在C/C++ 中通过函数SetConsoleOutputCP 设置;字体设置为SetCurrentConsoleFontEx

但是,存在一些主要(和次要)问题。次要优先:

a) 这些函数对一个会话有效,即。如果稍后再次运行该程序,则必须重新设置它。将其设为默认在理论上是可能的,但不推荐,因为它会影响所有控制台程序并向它们引入以下问题,即使它们不使用代码页做任何事情并且不是为了缓解问题而编写的。

b) 如果程序没有打开控制台,但您从现有控制台启动它,它将影响在它之后运行的任何内容,直到此控制台关闭。所以你必须在你自己的程序退出之前把它改回默认值。

c) 一些可用于控制台输入/输出的功能在 CP65001 上无法正常工作。
(这是最严重的事情)

与 Windows 的整个 UTF16 部分不同,它部分地将 UTF8 视为任何 1 字节 字符集,并做了一些奇怪的事情,这些事情恰好符合 1 字节字符集的标准,但实现方式不同。

例如,fread 应该返回读取的字节数(如果调用大小为 1),但在 Microsoft 的实现中,它确实返回字符数(UTF16 是一个例外,但不是 UTF8)。对于任何正常的代码页,它都可以工作,因为 1char=1byte,但不是 UTF8 ...错误的返回值 => 处理了错误的数据

另一个例子,fflush 可以挂起(至少被报告给,没有检查)。等等等等
而且它不仅会影响标准的 C 函数,还会影响直接的 Winapi 调用。

d) 由于 c),所有带有 UTF-8 字符的批处理文件(正常的 ASCII 范围除外)将无法正常工作,至少在某些 Windows 版本中(没有检查每个,但很可能Win10仍然存在此错误。MS表示不打算很快修复它。)

更多关于 c 和 d 的阅读:https://social.msdn.microsoft.com/Forums/vstudio/en-US/e4b91f49-6f60-4ffe-887a-e18e39250905/possible-bugs-in-writefile-and-crt-unicode-issues?forum=vcgeneral

【讨论】:

  • 只是一件事,使用 Cygwin,当我编译一个带有重音符号的 C 程序时,一切正常。现在我需要使用 TDM-GCC 来创建 Go DLL,单词上会出现错误。这一定也是编译器或其他东西的问题,或者Cygwin它不起作用,我想。
  • 为什么不在写入控制台之前将 UTF-8 转换为 UTF-16?
【解决方案2】:

我通常使用 Sublime Text 将源文件保存为 DOS( CP437 ),它可以工作(至少对于小程序)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 2020-08-13
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多