在Windows上编译时如何处理UTF-8编码的源代码?

在Windows上编译时如何处理UTF-8编码的源代码?,windows,encoding,Windows,Encoding,我目前正在编写一个小型C程序,使用MinGW的gcc在Windows上编译它。我还在GitHub上托管它(并使用GitHub桌面for Windows)。然而,GitHub似乎在文件中强制使用UTF-8编码,Windows终端在处理UTF-8时遇到问题 经过一番搜索,我找到了一些解决方案,但它们需要手动的、最终用户风格的解决方案,这是我想要避免的(我不打算发布它或任何东西,但我想知道如果我是的话我会怎么做) 目前有效的方法是将编码更改为ANSI,并在编译之前手动修复所有内容,但我宁愿避免每次想在

我目前正在编写一个小型C程序,使用MinGW的gcc在Windows上编译它。我还在GitHub上托管它(并使用GitHub桌面for Windows)。然而,GitHub似乎在文件中强制使用UTF-8编码,Windows终端在处理UTF-8时遇到问题

经过一番搜索,我找到了一些解决方案,但它们需要手动的、最终用户风格的解决方案,这是我想要避免的(我不打算发布它或任何东西,但我想知道如果我是的话我会怎么做)

目前有效的方法是将编码更改为ANSI,并在编译之前手动修复所有内容,但我宁愿避免每次想在Windows上工作时都这样做

所以问题是:在Windows上编译时如何处理UTF-8编码的源代码


以下是一些示例输出:

[]

  • 左:UTF-8编码的源代码(显示错误)
  • 右:以ANSI编码的源代码(显示在右侧)

编译过程完全相同,唯一不同的是实际的源代码编码。

问题是由于Windows终端无法正常显示UTF-8编码字符

要解决此问题,您需要告诉终端使用UTF-8代码页。更改代码页后,您不需要调用setlocale(),因为这可能会把事情搞得一团糟

要告诉Windows应该使用哪个代码页来显示输出,您可以使用传递UTF-8代码(65001)作为参数的函数(有关更多信息,请查看MSDN中的“”

下面是一个测试程序:

#include <stdio.h>
#include <locale.h>
#include <windows.h>

int main(void)
{
    UINT CODEPAGE_UTF8 = 65001;
    UINT CODEPAGE_ORIGINAL = GetConsoleOutputCP();

    printf("DEFAULT CODEPAGE, DEFAULT LOCALE: ¶\n");
    setlocale(LC_ALL, "");
    printf("DEFAULT CODEPAGE, SYSTEM LOCALE: ¶\n");

    SetConsoleOutputCP(CODEPAGE_UTF8);

    setlocale(LC_ALL, "C");
    printf("UTF-8 CODEPAGE, DEFAULT LOCALE: ¶\n");

    setlocale(LC_ALL, "");
    printf("UTF-8 CODEPAGE, SYSTEM LOCALE: ¶\n");

    SetConsoleOutputCP(CODEPAGE_ORIGINAL);
    return 0;
}
#包括
#包括
#包括
内部主(空)
{
UINT代码页_UTF8=65001;
UINT CODEPAGE_ORIGINAL=GetConsoleOutputCP();
printf(“默认代码页,默认区域设置:”“\n”);
setlocale(LC_ALL,“”);
printf(“默认代码页,系统区域设置:”“\n”);
设置控制台输出CP(代码页\ UTF8);
setlocale(LC_ALL,“C”);
printf(“UTF-8代码页,默认区域设置:”“\n”);
setlocale(LC_ALL,“”);
printf(“UTF-8代码页,系统区域设置:”“\n”);
SetConsoleOutputCP(原始代码页);
返回0;
}
下面是程序输出,分别使用ANSI编码的源代码、不带BOM(字节顺序标记)的UTF-8和带BOM的UTF-8进行编译:

[]


警告:互联网上的一些信息说,这只适用于某些字体,尤其是Lucida Console。此外,这仅适用于Windows 2000 Professional及更高版本。不过,我认为您现在不需要触摸比这更古老的东西。

这个问题是由于Windows终端无法正常显示UTF-8编码字符造成的

要解决此问题,您需要告诉终端使用UTF-8代码页。更改代码页后,您不需要调用setlocale(),因为这可能会把事情搞得一团糟

要告诉Windows应该使用哪个代码页来显示输出,您可以使用传递UTF-8代码(65001)作为参数的函数(有关更多信息,请查看MSDN中的“”

下面是一个测试程序:

#include <stdio.h>
#include <locale.h>
#include <windows.h>

int main(void)
{
    UINT CODEPAGE_UTF8 = 65001;
    UINT CODEPAGE_ORIGINAL = GetConsoleOutputCP();

    printf("DEFAULT CODEPAGE, DEFAULT LOCALE: ¶\n");
    setlocale(LC_ALL, "");
    printf("DEFAULT CODEPAGE, SYSTEM LOCALE: ¶\n");

    SetConsoleOutputCP(CODEPAGE_UTF8);

    setlocale(LC_ALL, "C");
    printf("UTF-8 CODEPAGE, DEFAULT LOCALE: ¶\n");

    setlocale(LC_ALL, "");
    printf("UTF-8 CODEPAGE, SYSTEM LOCALE: ¶\n");

    SetConsoleOutputCP(CODEPAGE_ORIGINAL);
    return 0;
}
#包括
#包括
#包括
内部主(空)
{
UINT代码页_UTF8=65001;
UINT CODEPAGE_ORIGINAL=GetConsoleOutputCP();
printf(“默认代码页,默认区域设置:”“\n”);
setlocale(LC_ALL,“”);
printf(“默认代码页,系统区域设置:”“\n”);
设置控制台输出CP(代码页\ UTF8);
setlocale(LC_ALL,“C”);
printf(“UTF-8代码页,默认区域设置:”“\n”);
setlocale(LC_ALL,“”);
printf(“UTF-8代码页,系统区域设置:”“\n”);
SetConsoleOutputCP(原始代码页);
返回0;
}
下面是程序输出,分别使用ANSI编码的源代码、不带BOM(字节顺序标记)的UTF-8和带BOM的UTF-8进行编译:

[]


警告:互联网上的一些信息说,这只适用于某些字体,尤其是Lucida Console。此外,这仅适用于Windows 2000 Professional及更高版本。不过,我认为你现在不需要碰比这更古老的东西。

我希望我没有遗漏任何相关信息,但如果我遗漏了,请询问!gcc不会自动处理吗?gcc处理得很好,但问题似乎是由Windows终端引起的。显然,它只适用于Lucida控制台字体,但我不想为了让程序运行而更改终端字体。@HansPassant我不打开任何文件!我的源代码是用UTF-8编码的,在Windows上编译的文件编码不正确。将源代码转换为ANSI时,一切正常不过,了解fopen()处理编码非常有趣。谢谢所以gcc在UTF-8中编译的很好,但是exe没有运行?到底出了什么问题?我希望我没有遗漏任何相关信息,但如果我遗漏了,请询问!gcc不会自动处理吗?gcc处理得很好,但问题似乎是由Windows终端引起的。显然,它只适用于Lucida控制台字体,但我不想为了让程序运行而更改终端字体。@HansPassant我不打开任何文件!我的源代码是用UTF-8编码的,在Windows上编译的文件编码不正确。将源代码转换为ANSI时,一切正常不过,了解fopen()处理编码非常有趣。谢谢所以gcc在UTF-8中编译的很好,但是exe没有运行?到底出了什么问题?非常感谢
SetConsoleOutputCP(65001)
saved my day!非常感谢你
SetConsoleOutputCP(65001)
saved my day!