我正在为一个使用文件作为参数的应用程序编写一个小包装器。
包装器需要是Unicode,所以我使用wchar_t作为我拥有的字符和字符串。 现在我发现自己遇到了问题,我需要在wchar_t和wchar_t字符串数组中包含程序的参数。
可能吗? 我将main
function定义为
int main(int argc, char *argv[])
我应该将wchar_t用于argv
吗?
非常感谢,我似乎没有找到有关如何在C中正确使用Unicode的有用信息。
一般来说,没有。 它取决于O / S,但C标准说’main()’的参数必须是’main(int argc,char ** argv)’或等价,所以除非char和wchar_t是相同的基本类型,你不能这样做。
话虽如此,你可以在程序中获得UTF-8参数字符串,将它们转换为UTF-16或UTF-32,然后继续生活。
在Mac(10.5.8,Leopard)上,我得到了:
Osiris JL: echo "ï€" | odx 0x0000: C3 AF E2 82 AC 0A ...... 0x0006: Osiris JL:
这都是UTF-8编码的。 (odx是一个hex转储程序)。
另请参阅: 为什么在与UNIX / Linux环境交互时使用UTF-8编码
便携式代码不支持它。 Windows(例如)支持使用wmain
而不是main
,在这种情况下,argv作为宽字符传递。
在Windows上,您可以使用GetCommandLineW()
和CommandLineToArgvW()
生成argv样式的wchar_t[]
数组,即使该应用程序未针对Unicode进行编译也是如此。
无论如何,在Windows上,您可以拥有一个用于UNICODE构建的wmain()
。 虽然不便携。 如果GCC或Unix / Linux平台提供类似的东西,我不知道。
假设您的Linux环境使用UTF-8编码,那么以下代码将准备您的程序,以便在C ++中轻松进行Unicode处理:
int main(int argc, char * argv[]) { std::setlocale(LC_CTYPE, ""); // ... }
接下来,wchar_t类型在Linux中是32位,这意味着它可以保存单独的Unicode代码点,并且您可以安全地使用wstring类型进行C ++中的经典字符串处理(逐个字符)。 使用上面的setlocale调用,插入wcout将自动将输出转换为UTF-8,从wcin中提取将自动将UTF-8输入转换为UTF-32(1个字符= 1个代码点)。 唯一的问题是argv [i]字符串仍然是UTF-8编码的。
您可以使用以下函数将UTF-8解码为UTF-32。 如果输入字符串已损坏,它将返回正确转换的字符,直到UTF-8规则被破坏的位置。 如果您需要更多错误报告,可以改进它。 但对于argv数据,可以安全地假设它是正确的UTF-8:
#define ARR_LEN(x) (sizeof(x)/sizeof(x[0])) wstring Convert(const char * s) { typedef unsigned char byte; struct Level { byte Head, Data, Null; Level(byte h, byte d) { Head = h; // the head shifted to the right Data = d; // number of data bits Null = h << d; // encoded byte with zero data bits } bool encoded(byte b) { return b>>Data == Head; } }; // struct Level Level lev[] = { Level(2, 6), Level(6, 5), Level(14, 4), Level(30, 3), Level(62, 2), Level(126, 1) }; wchar_t wc = 0; const char * p = s; wstring result; while (*p != 0) { byte b = *p++; if (b>>7 == 0) { // deal with ASCII wc = b; result.push_back(wc); continue; } // ASCII bool found = false; for (int i = 1; i < ARR_LEN(lev); ++i) { if (lev[i].encoded(b)) { wc = b ^ lev[i].Null; // remove the head wc <<= lev[0].Data * i; for (int j = i; j > 0; --j) { // trailing bytes if (*p == 0) return result; // unexpected b = *p++; if (!lev[0].encoded(b)) // encoding corrupted return result; wchar_t tmp = b ^ lev[0].Null; wc |= tmp << lev[0].Data*(j-1); } // trailing bytes result.push_back(wc); found = true; break; } // lev[i] } // for lev if (!found) return result; // encoding incorrect } // while return result; } // wstring Convert
在Windows上,您可以使用tchar.h和_tmain,如果在编译时定义了_UNICODE符号,则将其转换为wmain,否则为main。 如果定义了unicode,TCHAR * argv []将同样扩展为WCHAR * argv [],否则将扩展为char * argv []。
如果您希望主要方法跨平台工作,则可以将自己的宏定义为相同的效果。
TCHAR.h包含许多用于在wchar和char之间进行转换的便捷宏。
需要了解更多c/c++开发分享是否可以使用Unicode“argv”?,也可以关注C/ C++技术分享栏目---计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享是否可以使用Unicode“argv”?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979343.html