C++ 文件打开接口是否应为C++;库是否在Windows上使用UTF-8?
我正在开发一个库(pugixml),其中包括使用窄字符C字符串为XML文档提供文件加载/保存API:C++ 文件打开接口是否应为C++;库是否在Windows上使用UTF-8?,c++,windows,unicode,encoding,utf-8,C++,Windows,Unicode,Encoding,Utf 8,我正在开发一个库(pugixml),其中包括使用窄字符C字符串为XML文档提供文件加载/保存API: bool load_file(const char* path); bool save_file(const char* path); 目前,路径被逐字传递到fopen,这意味着在Linux/OSX上,您可以传递UTF-8字符串以打开文件(或任何其他有效路径的字节序列),但在Windows上,您必须使用Windows ANSI编码-UTF-8不起作用 文档数据(默认情况下)使用UTF-8表示,
bool load_file(const char* path);
bool save_file(const char* path);
目前,路径被逐字传递到fopen
,这意味着在Linux/OSX上,您可以传递UTF-8字符串以打开文件(或任何其他有效路径的字节序列),但在Windows上,您必须使用Windows ANSI编码-UTF-8不起作用
文档数据(默认情况下)使用UTF-8表示,因此如果您有一个带有文件路径的XML文档,您将无法将从文档检索到的路径按原样传递到load_file
函数,或者更确切地说,这在Windows上不起作用。该库提供了使用wchar\t
的替代函数:
bool load_file(const wchar_t* path);
但是使用它们需要额外的努力来将UTF8编码为wchar\t
另一种不同的方法(SQlite和GDAL使用-不确定是否有其他C/C++库这样做)涉及在Windows上将路径视为UTF-8(这将通过将其转换为UTF-16并使用wchar\u t
感知函数(如\wfopen
打开文件)来实现)
我可以看到不同的利弊,我不确定哪种权衡是最好的
一方面,在所有平台上使用一致的编码肯定是好的。这意味着您可以使用从XML文档提取的文件路径打开其他XML文档。此外,如果使用库的应用程序采用UTF-8,则在通过库打开XML文件时不必进行额外的转换
另一方面,这意味着文件加载的行为不再与标准函数的行为相同,因此通过库访问文件并不等同于通过标准fopen
/std::fstream
访问文件。看起来,虽然有些库采用UTF-8路径,但这在很大程度上是一个不受欢迎的选择(这是真的吗?),因此对于使用许多第三方库的应用程序,这可能会增加混乱,而不是帮助开发人员
例如,将argv[1]
传递到load_file
当前适用于在Windows上使用系统区域设置编码编码的路径(例如,如果您有俄语区域设置,您可以加载任何具有类似俄语名称的文件,但无法加载具有日语字符的文件)。切换到UTF-8意味着只有ASCII路径才能工作,除非您以其他特定于Windows的方式检索命令行参数
当然,对于图书馆的一些用户来说,这将是一个突破性的变化
我是否遗漏了任何重要的要点?是否还有其他图书馆采用同样的方法?什么是更好的C++ +一致不一致的文件访问,或争取统一的跨平台行为?< /P>
请注意,问题是关于打开文件的默认方式-当然,没有什么可以阻止我添加另一对带有_utf8后缀的函数或以其他方式指示路径编码。越来越多的人认为,您应该只在跨平台代码中使用UTF-8,并在适当的情况下在Windows中自动执行转换。详细介绍了选择UTF-8编码的原因 最近的一个例子是,
libtorrent
不推荐所有处理wchar\u t
文件名的例程,而是要求库用户在传入文件名之前使用其wchar\u t-to-utf8转换函数
就我个人而言,我必须避免使用
wchar\u t
/wstring
函数的最大原因就是避免重复我的API。减少API中的函数数量,以减少外部维护、文档编制和代码路径复制成本是很有价值的。细节可以在内部解决。Windows ANSI/Unicode拆分所造成的重复API的混乱可能足以在您自己的API中避免这种情况。三件事:(1)为什么不在内部转换为UTF-16,然后在Windows上使用\wfopen
/std::ifstream(wchar\u t*)
?生成的文件对象与非wchar函数打开的文件对象相同。(2) 你读过了吗?你同意吗?(3) 看。1)第二种方法就是这样工作的2)我读过了。我同意UTF-8在跨平台应用程序中通常是优越的,但库可能是不同的-世界是否也这么认为?:)另一个在Windows上使用UTF-8(并且没有宽字符)的库:gtkmm。尽管它也犯下了其他罪行,但应该注意的是,正是出于这些原因,微软正在大力推行文件系统TS。他们甚至实现了对Boost.FileSystem v2的支持,这样他们就可以在VS2013中获得一些东西。现在FST已经完成,它们是主要编译器/标准库供应商中的第一个实现。他们希望看到这个问题像其他人一样结束。第二,这确实是使事情变得更简单的最佳方法。是的,更具体地说,在Windows上,将文件名转换为宽字符,并使用宽API。有很多库只需将const char*
传递给fopen(…)
,这将有效地使打开具有任意文件名(即当前代码页之外的字符)的文件变得不可能。