Windows 上的 MinGW + GCC 和 UTF-8 字符

问题描述 投票:0回答:3

我在使用 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

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

c windows gcc utf-8 cmd
3个回答
8
投票

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

可以做什么:将代码页设置为

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

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

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

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

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

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

举个例子,fread应该返回读取的字节数(如果使用大小1调用),但在微软的实现中,它确实返回字符数(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-问题?论坛=vcgeneral


0
投票

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


0
投票

包括无 seu código C.

#include <winnls.h>
int SetConsoleOutputCP(int CP);
int main ()
{
    SetConsoleOutputCP(65001);
    ...
}

Windows 终端上的“SetConsoleOutputCP”功能可用于确定字符编码,或使用 utf-8 值“65001”。

Agora é so usar a criatividade para Implementar e vida que segue! :)

O melhor é que dessa forma você não precisa configurar or compilador。使用或编译com suas configurações padrão e pode levar para compilar onde quiser sem medo.

Além disso, como a indicação para que o Terminal trabalhe com utf-8 faz paré compilada junto o programa, semper que rodar o programa, eleautomaticamente "forçará" o Terminal a trabalhar em utf-8 (só não funciona em windows) NT 前部)。

Se você ainda quer mais portabilidade pode incluir a função e a biblioteca nos“includes”e funções condicionais,fazendo compilar esse detalhe do utf-8 para o windows apenas quando oprograma for rodar no windows.

© www.soinside.com 2019 - 2024. All rights reserved.