【问题标题】:C++ and file paths with national symbols (encoded with utf8, maybe)C++ 和带有国家符号的文件路径(可能用 utf8 编码)
【发布时间】:2018-09-30 18:43:21
【问题描述】:

我有一些跨平台代码,它应该使用一些配置文件。一切正常,除非配置文件名路径包含非 ANSI 字符。

对于打开/读取文件,我使用的是std::ifstream。 在windows平台(MSVC)上,解决方案是使用std::ifstream的重载版本,它可以接受路径名wchar_t*,所以路径名编码为utf16,路径中的国家符号没有问题。

但是对于 NIX* 系统有什么解决方案? 据我所知,所有此类文件名都使用 UTF-8 编码,并且可以使用 char* 作为指向字符串的指针。 例如:

std::string path_name = ...; //assigning path name
std::ifstream fin(path_name.c_str());

但是 c_str() 返回指向文件名字符串的常量指针,然后是 null 终止符呢?因为 UTF-8 字节序列可以包含零作为代码点的一部分,所以这样的字符串可以被截断。

所以请指点我,我错了,或者如果我没问题,请建议一些便携式解决方案))

谢谢。

【问题讨论】:

  • ifstream 有一个以 std::string 作为参数的构造函数 - 无需使用 c_str()。
  • UTF-8 不包含零作为代码点的一部分。 UTF-8 文本像 ASCII 文本一样以零结尾。
  • 您能否澄清一下“一切正常,除非配置文件名路径包含非 ANSI 字符”的意思?是什么让您认为问题出在文件名字符串上?
  • @ÖöTiib UTF-8 应该使用最多四个字节,每个符号。多字节序列的每个字节都包含最高有效位为 1。所以,是的,你绝对正确 - 这样的 utf-8 原始字符串上没有零字节。这就是我错了。谢谢你。如何将您的评论标记为答案?
  • @user1503944 UTF-8 supposed to use up to four bytes, per symbol. 不是符号。您可能正在考虑代码点。一个符号可以包含一个或多个代码点(每个代码点最多包含四个 UTF-8 代码单元)。

标签: c++ unicode utf-8 filenames


【解决方案1】:

UTF-8 不包含零作为代码单元的一部分。多字节序列中的字节必须设置最高有效位。因此 UTF-8 文本可以像 ASCII 文本一样以零结尾。

因此您可以使用path_name.c_str() 作为UTF-8 编码的文件名。

【讨论】:

  • UTF-8 字符串中的字节称为代码单元代码点是 UTF 编码为 代码单元的 Unicode 值。在任何情况下,UTF-8 中都有一个零字节 - NUL 字符,Unicode 代码点 U+0000,在 UTF-8 中编码为字节 0x00,因此可以用作空终止符一个以 null 结尾的字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
  • 2012-05-18
相关资源
最近更新 更多