首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++读写UTF-32文件

C++读写UTF-32文件
EN

Stack Overflow用户
提问于 2018-05-02 17:04:45
回答 2查看 2.9K关注 0票数 0

我想用VisualStudio2017、C++和WindowsAPI (以前称为Win32)为自己编写一个语言学习应用程序。操作系统是最新的Windows 10内部构建和向后兼容性是一个非问题.由于我假设英语是用户的母语,而我目前感兴趣的语言是另一种欧洲语言,ASCII可能就足够了。但我想要未来的证明它(更多的外部语言),我也想尝试我的手UTF-32。我以前使用过UTF-8和UTF-16,虽然我对后者有更多的经验.

多亏了std::basic_string,很容易找到如何获得UTF-32字符串:

代码语言:javascript
复制
typedef std::basic_string<char32_t> stringUTF32

由于我正在为所有的图形用户界面工作人员使用WinAPI,我需要在UTF-32和UTF-16之间进行一些转换。

现在到我的问题:由于UTF-32没有被广泛使用,因为它的低效率,几乎没有任何关于它的材料在网上。为了避免不必要的转换,我想将我的词汇表和其他数据保存为UTF-32 (对于所有UTF-8倡导者/传道者来说,可以选择UTF-16)。问题是,我找不到如何在UTF-32中编写和打开文件.

那么,我的问题是:如何在UTF-32中编写/打开文件?我更希望不需要第三方库,除非它们是Windows的一部分,或者通常是随操作系统一起提供的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-02 18:36:40

如果您有一个char32_t序列,您可以使用一个std::basic_ofstream<char32_t> (我将称之为u32_ofstream,但不存在这个类型)将其写入文件。它的工作原理与std::ofstream完全一样,只不过它编写的是char32_ts而不是chars,但也有其局限性。

大多数具有operator<<重载的标准库类型都是在字符类型上模板化的。因此,他们将与u32_ofstream合作得很好。您将遇到的问题是用户类型。这些几乎总是假设您正在编写char,因此被定义为ostream &operator<<(ostream &os, ...);。这样的流输出不能在没有转换层的情况下与u32_ofstream一起工作。

但你要面对的大问题是endian问题。u32_ofstream将编写char32_t作为平台的本机终端。如果您的应用程序通过u32_ifstream读取它们,那很好。但是,如果其他应用程序读取它们,或者您的应用程序需要阅读由其他人用UTF-32编写的东西,这就成了一个问题。

典型的解决方案是使用“字节顺序标记”作为文件的第一个字符。Unicode甚至为这一点预留了一个特定的代码点:\U0000FEFF

BOM的工作方式是这样的。在编写文件时,您可以在任何其他代码点之前写入BOM。

当读取未知编码的文件时,您可以正常读取第一个代码点。如果它在本机编码中与BOM相等,那么您可以正常读取文件的其余部分。如果没有,那么您需要读取文件和endian-转换它,然后才能处理它。这个过程看起来会是这样的:

代码语言:javascript
复制
constexpr char32_t native_bom = U'\U0000FEFF';

u32_ifstream is(...);
char32_t bom;
is >> bom;
if(native_bom == bom)
{
  process_stream(is);
}
else
{
  basic_stringstream<char32_t> char_stream
  //Load the rest of `is` and endian-convert it into `char_stream`.
  process_stream(char_stream);
}
票数 1
EN

Stack Overflow用户

发布于 2018-05-03 05:08:04

我目前对另一种欧洲语言感兴趣,所以ASCII可能就足够了。

不是的。即使是用简单的英语。你知道微软Word是如何创建“卷引号”的吗?这些是非ASCII字符。所有这些字母都带有重音和空话。法语或英语是非ASCII字符.

我想要将来的证明

UTF-8、UTF-16和UTF-32都可以对每个Unicode代码点进行编码.它们都是防患于未然的。与其他两个相比,UTF-32没有优势。

另外,对于将来的校对:我很确定一些脚本使用字符(技术术语是“字素群集”),它由多个代码点组成。粗略的搜索发现了和Devanagari角色一起玩

UTF-32的一个缺点是对其他工具的支持。记事本不会打开你的文件。无法比较。Visual代码…不是的。会的,但是它不会让您创建这样的文件。

Win32 API:它有一个函数MultiByteToWideChar,它可以将UTF-8转换为UTF-16 (您需要传递给所有Win32调用),但是它不接受UTF-32。

所以我对这个问题的诚实的回答是,不要。否则,遵循妮可的答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50140003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档