【发布时间】:2011-03-09 03:58:54
【问题描述】:
GCC 是否支持 Microsoft 等效的 wmain()?我正在编写 C 程序,需要始终使用 Unicode。如果不是,char可以转成wchar_t吗?
【问题讨论】:
标签: c unicode command-line
GCC 是否支持 Microsoft 等效的 wmain()?我正在编写 C 程序,需要始终使用 Unicode。如果不是,char可以转成wchar_t吗?
【问题讨论】:
标签: c unicode command-line
对于 Unicode,您不需要 wchar_t。您可以将char 用于Unicode 的utf-8 编码。另外,wchar_t 可以是不同的大小。在 Windows 上是 16 位,但在许多 Linux/Unix 平台上是 32 位。
有关 GCC 的更多信息,请参阅我通过 Google 搜索找到的这篇文章:
http://article.gmane.org/gmane.comp.gnu.mingw.user/22962
(据此,您对 GCC 是否支持wmain 的问题的答案是“否”。)
【讨论】:
C 的许多标准字符串函数都与编码无关。您可以使用 char* 存储 UTF-8 编码的字符串并安全地使用它们:
strcpy strncpy strcat strncat strcmp strncmp strdup strchr
strrchr strcspn strspn strpbrk strstr strtok
其他一些函数不会为您提供 Unicode 字符串的正确结果。例如,strlen 总是计算字节数,而不是字符数。可以使用mbstowcs(NULL,s,0) 以可移植的方式在 C 中计算字符数。它将返回s 中成功转换为wchar_t 的字符数。这适用于 UTF-8,就像任何其他受支持的编码一样,只要选择了适当的语言环境。
如果您想对 Unicode 字符串进行高级操作,例如复杂的代码页转换、正则表达式、单词边界上的文本换行等,我建议您使用像 ICU 这样的好的库。
【讨论】:
如果您想处理没有wmain 的Unicode 命令行参数,您可以使用无参数标准main 函数和Windows API 函数GetCommandLineW、CommandLineToArgvW 和LocalFree。 CommandLineToArgvW 使用与 Microsoft 运行时库相同的 same rules for command line parsing。
【讨论】:
如果您确实想使用宽字符串,mbstowcs 会将多字节字符串转换为wchar_t 字符串。它假定多字节字符串所在的编码取决于当前语言环境的 LC_CTYPE 类别。必须用setlocale 设置它;否则您将默认获得“C”语言环境。
问题仍然是argv 中使用了什么字符编码。这可能是 UTF-8,也可能是像 Latin-1 这样的单字节编码之一。这取决于您的终端设置。尝试使用 xterm,当我在命令行上传递“é”时,argv 得到了不同的值,这取决于 xterm 继承的 LANG 的值:对于 LANG=en_US.UTF-8,它给出了“c3 a9”;对于 LANG=en_US,它给出了“e9”(我认为这是 Latin-1。)
您可以先使用setlocale(LC_CTYPE, "") 或setlocale(LC_ALL, "") 从环境中获取语言环境,以使用正确的多字节格式(从环境变量中设置)。但是,如果在终端模拟器启动后更改 LANG,您将遇到问题。
glibc 为字符集转换提供了其他几个可能更合适的函数 - 请参阅 glibc 手册的“字符集处理”部分了解更多信息。我的经验是,将 argv 中的字符串转换为给定的编码非常棘手,可能必须分两个阶段完成:一次将其转换为 wchar_t 格式,其次将其从 wchar_t 转换为所需的编码(例如 UTF-8)。
【讨论】:
é 的编码是E9,而UTF-8 中的编码是C3 A9。它们完全不同。完全不兼容。干杯。