为了创建一个在Windows和Linux之间可移植的源代码级别的C程序并很好地处理国际化,有恕我直言三种主要编码要考虑:
> C源代码的编码.
>外部数据的编码.
>字符串和文字的编码.
对于C源代码,没有任何替代UTF-8与BOM,至少如果标准输入和宽字符串文字应该在Windows平台上工作.没有BOM的UTF-8会导致Microsoft的Visual C编译器对源代码采用Windows ANSI编码,这对于通过std :: cout输出的UTF-8来说很有用,但这种程度有限(Windows控制台窗口有很多错误) ).但是,然后通过std :: cin输入不起作用.
而对于外部数据,UTF-8似乎是事实上的标准.
但是,内部文字和字符串呢?在这里,我的印象是编码为UTF-8的窄字符串是Linux中的常见惯例.但最近有两个不同的人声称,其中一个声称Linux中国际应用程序内部字符串的通用约定是UTF-32,另一个声称在这个领域Unix和Linux之间存在一些未指明的区别.
作为一个在业余爱好基础上摆弄一点的人,有一个微型图书馆旨在抽象出这个领域的Windows / Linux差异,我……必须要具体地问一下
>在程序中表示字符串的常见Linux约定是什么?
我很确定这个问题有一个真正的答案,这是一个非常普遍的惯例.
示例显示例如如何Linux – 传统上反转字符串(直接用UTF-8进行复杂,但可能是由Linux中事实上标准的函数完成的?),也很好,即作为一个问题,什么是这个C程序的Linux传统版本(给出的代码适用于Latin-1作为C窄文本执行字符集):
#include
#include
#include
using namespace std;
#define STATIC_ASSERT( cond ) static_assert( cond, #cond )
int main()
{
string line;
if( getline( cin, line ) )
{
static char const aSingleChar[] = "æ";
STATIC_ASSERT( sizeof( aSingleChar ) - 1 == 1 );
reverse( line.begin(), line.end() );
cout << line << endl;
}
}
解决方法:
对于外部表示,UTF-8绝对是标准.一些8位编码仍然很强大(主要在欧洲),一些16位编码仍然很强大(主要在东亚),但它们显然是传统编码,因为它们的速度很慢. UTF-8不仅是unix的标准配置,也是网络上的标准配置.
对于内部表示,没有这样的压倒性标准.如果你环顾四周,你会发现一些UTF-8,一些UCS-2,一些UTF-16和一些UCS-4.
> UTF-8的优点是它匹配公共表示,并且它是ASCII的超集.特别是,它是唯一的编码,其中空字符对应于空字节,如果您有C API(包括unix系统调用和标准库函数),这很重要.
> UCS-2是历史遗存.它很有吸引力,因为它被认为是一个固定宽度的编码,但它不能代表所有的Unicode,这是一个塞子.
> UTF-16的主要声名是Java和Windows API.如果您正在为unix编程,Unix API(喜欢UTF-8)比Windows API更相关.只有与像UTF-16这样的API交互的程序才倾向于使用UTF-16.
> UCS-4很有吸引力,因为它看起来像一个固定宽度的编码.事情是,它不是,真的.由于组合字符,因此不存在固定宽度的Unicode编码.
>还有wchar_t.问题是,在某些平台上是2个字节,在其他平台上是4个字节,并且它所代表的字符集没有特定.由于Unicode是事实上的标准字符集,较新的应用程序倾向于避免使用wchar_t.
在unix世界中,胜过它们的论点通常是与unix API兼容,指向UTF-8.然而,这并不普遍,所以对于你的图书馆是否需要支持其他编码没有肯定或没有答案.
在这方面,unix变体之间没有区别. Mac OS X prefers decomposed characters以便具有标准化表示,因此您可能也希望这样做:它将在OSX上保存一些工作,并且在其他unices上无关紧要.
请注意,UTF-8中没有BOM.字节顺序标记仅对超字节大小的编码有意义. UTF-8编码文件以字符U FEFF开头的要求特定于少数Microsoft应用程序.
标签:c,string,character-encoding,conventions
来源: https://codeday.me/bug/20190810/1636182.html