具有默认utf8处理的流

时间:2013-07-22 15:06:34

标签: c++ unicode c++11 stream locale

我已经读过在某些环境std::string内部使用UTF-8。然而,在我的平台上,Windows std::string仅为ASCII。可以使用std::locale更改此行为。我的STL版本没有,或者至少我找不到用于字符串的UTF-8方面。但是,我确实有一个方面可用于fstream类。

编辑: 当我说“在内部使用UTF-8”时,我指的是像std::basic_filebuf::open()这样的方法,它们在某些环境中接受UTF-8编码的字符串。我知道这不是一个std::string问题,而是一些操作系统本地使用UTF-8。我的问题应该理解为“您的实现如何处理无效序列的代码转换?”。

这些流如何处理其他平台/实现上的无效代码序列?

在我的UTF8 facet文件中,它只返回一个错误,这反过来又会阻止更多的流被读取。我本以为将错误更改为Unicode“无效字符”0xfffd值是一个更好的选择。

我的问题不仅限于UTF-8,无效UTF-16代理人对怎么办?

我们有一个例子。假设您打开一个UTF-8编码文件,其中UTF-8wchar_t locale。您的实现如何处理无效的UTF-8序列? 或者,std::wstring并将其打印到std::cout,这次是单独的代理。

3 个答案:

答案 0 :(得分:3)

  

我已经读过,在某些环境中,std :: string内部使用的是UTF-8。

C ++程序可以选择使用std::string在任何符合标准的平台上保存UTF-8字符串。

  

然而,在我的平台上,Windows,std :: string只是ASCII。

这是不正确的。在Windows上,如果需要,可以使用std::string来保存UTF-8字符串,std::string不限于在任何符合标准的平台上保留ASCII。

  

可以使用std :: locale更改此行为。

不,std::string的行为不受语言环境库的影响。

std::string是一系列chars。在大多数平台上,包括Windows,char是8位。因此,您可以使用std::string来保存ASCII,Latin1,UTF-8或使用8位或更少代码单元的任何字符编码。 std::string::length返回如此保留的代码单元数,std::string::operator[]将返回第i个代码单元。

要保留UTF-16,您可以使用char16_tstd::u16string

如需持有UTF-32,您可以使用char32_tstd::u32string

答案 1 :(得分:1)

  

假设您打开一个UTF-8编码文件,其中包含UTF-8到wchar_t语言环境。您的实现如何处理无效的UTF-8序列?

通常没有人会在其他平台上转换为wchar_t或其他宽字符类型,但是可以用于此的所有标准方面都表示读取错误导致流停止工作,直到错误为止清零。

答案 2 :(得分:0)

std::string应编码不可知:http://en.cppreference.com/w/cpp/string/basic_string - 因此它不应验证代码点/数据 - 您应该能够在其中存储任何二进制数据。

编码确实有所作为的唯一地方是计算字符串长度并逐个字符地迭代字符串 - 并且语境环境应该对这两种情况都没有影响。

而且 - 如果可以完全避免使用std::locale可能不是一个好主意 - 它在所有平台或标准库的所有实现上都不是线程安全的,因此在使用它时必须小心。这种影响也非常有限,可能完全没有你想象的那样。