【问题标题】:How to Pass Unicode Arguments to G++?如何将 Unicode 参数传递给 G++?
【发布时间】:2021-05-21 12:47:09
【问题描述】:

我正在尝试使用 G++ 编译一个简单的 C++ 程序。我正在运行 Windows 10 并且我已经安装了 MinGW。因此,我尝试通过在命令提示符中键入 g++ "C:\Users\Vesk\Desktop\Информатика\Hello World.cpp" -o "C:\Users\Vesk\Desktop\Информатика\Hello World.exe" 来使用 G++ 编译此文件 C:\Users\Vesk\Desktop\Информатика\Hello World.cpp。 G++ 虽然没有编译文件并给了我这个错误信息:

g++: error: C:\Users\Vesk\Desktop\???????????\Hello World.cpp: Invalid argument
g++: fatal error: no input files
compilation terminated.

'Информатика' 只是一个西里尔字母,所以我很困惑问题是什么。但后来我只是将“Информатика”文件夹重命名为“Informatics”。我尝试使用g++ "C:\Users\Vesk\Desktop\Informatics\Hello World.cpp" -o "C:\Users\Vesk\Desktop\Informatics\Hello World.exe" 再次编译该文件。你瞧,它奏效了。 G ++编译了该文件,可执行文件在文件夹中并且正在运行。但是,如果文件的路径包含西里尔文(或其他 Unicode)字符,是否有任何方法可以实际编译文件?如果有,怎么做?

【问题讨论】:

  • 在命令提示符窗口chcp 中运行时您会看到什么,以显示 Windows 命令处理器默认使用的code page,根据为您的帐户配置的国家/地区和下一个dir "%UserProfile%\Desktop" /AD /B ?我想chcp 输出855872866 并且 g++ 期望使用 UTF-8 编码的西里尔字母,如 Linux 或代码页 Windows-1251
  • 在命令提示符窗口中使用 chcp 65001 设置 UTF-8 用于字符编码然后运行 ​​g++ 会发生什么?
  • @Mofi 当我运行 chcp 时,它说我的活动代码页是 437。我真的不知道那是什么,但我的 Windows 设置为英语。我尝试运行chcp 65001,然后再次尝试在旧文件夹上运行 g++,但它给了我同样的错误。
  • 好吧,北美 OEM code page 437 绝对不是您在文件/文件夹名称中使用西里尔字母时应该使用的代码页,因为此代码页(表格)不支持这些字符完全没有。您可以像我一样使用英语 Windows,但您应该为您的国家/地区配置正确的地区/国家。参见例如How to change country or region home location in Windows 10
  • 在正确配置国家后重新启动 Windows。然后打开命令提示符窗口并再次运行chcp。现在应该输出我在第一条评论中已经写过的 OEM 代码页之一。它也可以在命令提示符窗口中使用 chcp 855chcp 866 将代码页从 437 更改为支持西里尔字母的代码页,然后使用 MinGW g++。但更好的是正确配置国家或继续使用美国,不要在文件/文件夹名称中使用西里尔字母。

标签: cmd unicode character-encoding g++ mingw


【解决方案1】:

Windows 使用 UTF-16 作为 Unicode 文件名。据我所知,它不支持 UTF-8 作为语言环境,尽管这非常有用。

我在一个非常旧的 MinGW G++ 4.6.3 上进行了尝试,它确实不支持文件路径中的 Unicode 字符当前区域设置之外。不知道最近的 MinGW GCC。第一个可能的解决方案是使用俄语语言环境。

要让 Windows 应用程序正确支持 Unicode 文件名,它需要将路径处理为 wchar_t 宽字符。例如,int main(int argc, const char* argv[]) 经典签名必须替换为 int wmain(int argc, const wchar_t* argv[])。对于像 GCC 这样的便携式软件,这是一个可能不值得的复杂问题。很少有人会将字符放在当前语言环境之外的源文件路径中。

我在 Cygwin 上尝试了 G++ 10.2.0,它可以工作。这是因为所有 Cygwin 软件都与 cygwin1.dll 链接,除其他服务外,它还会自动将所有 UTF-8 路径转换为 ​​UTF-16。

【讨论】:

  • 我认为in Windows 10 可以为控制台程序设置UTF-8。
  • 感谢您的回答。我在我的 Windows 上将所有内容都设置为英语,我更喜欢这种方式。我想我可能不得不避免在我的文件夹和文件名中使用西里尔字母,因为似乎没有一个简单的解决方案。
【解决方案2】:

您应该首先使用GetCommandLineW 函数(https://docs.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-getcommandlinew)获取带有UTF16 编码的命令行,然后使用CommandLineToArgWhttps://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw)分隔标记。

如果您想要 UTF8 编码的字符串,您需要对其进行转换,可以在 here 找到一个简单、开源且有用的工具,用于在 C++20 中转换具有不同编码的字符串。

【讨论】:

  • 通常在 Windows 上,如果您需要管理任何非 ASCII 输入/输出,您应该始终使用 W 结尾版本的 I/O 函数,因为这些命令的正常版本很大程度上取决于当前提示代码页(Windows 使用的单字节 ASCII 扩展编码,如 Latin1)在一台计算机与另一台计算机之间存在很大差异。
  • GCC 是一个跨平台的应用程序,支持很多不同的平台。你不能指望它使用平台特定的代码到这样的程度。
  • GCC 在 Windows 上不存在,有 Cygwin 和 MinGW ;) 并且它们对 cin、cout 和 cerr 的行为与非 ASCII 字符非常不同:Cygwin 将全部转换为 UTF8 而 MinGW 使用默认代码页(例如 1251)
  • 如果你想通过 UTF8/UTF16 转换增加额外的开销并且只使用 utf8 字符串,那么你应该使用 Cygwin 而不是 MinGW(但问题是关于 MinGW)。否则,您可以使用链接库编写编码感知程序。
  • 我自己从源代码为 Windows 构建了 GCC,我可以向你保证它确实存在于 Windows 中。 MinGW 是它所构建的系统库(很像其他平台上的 newlib)。这个问题的主题是为什么GCC本身不支持Unicode字符,而不是如何编写一个支持的程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多