问题标签 [codecvt]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
138 浏览

c++ - 为什么 std::basic_fstream不行吗?

尝试编译此代码时:

编译器会警告我从调用到unsigned char的oh-not-so-healthy 转换到. 事实上,它只是一个 typedef ,人们可能会认为使用而不是允许他们在没有警告的情况下编译上面的代码,正如预期的模板类型指针一样。charwrite()std::fstreamstd::basic_fstream<char>std::basic_fstream<uint8_t>write()

这当然可行,但又出现了另一个问题。即使这段代码编译得很好:

write()即使以前的版本正在运行,它现在也会在调用 时失败(忽略编译器警告)。我花了一段时间来确定标准 C++ 库代码中异常是从哪里引发的,但我仍然不太明白这里的情况。它看起来std::basic_fstream使用了一些字符编码机制,并且由于定义了一个 forchar但没有定义 for unsigned char,因此文件流在尝试使用“错误”字符数据类型时会默默地失败......至少我是这么看的。

但这也是我不明白的。不需要任何字符编码。我什至不以文本模式打开文件,我想处理二进制数据。这就是为什么我使用类型数组而uint8_t不是 char 的原因,使用这种数据类型而不是普通的 old 感觉更自然char。但在我决定放弃uint8_t数据类型并接受使用char缓冲区或开始使用byte定义为 的自定义数据类型的数组之前char,我想问两个问题:

  1. 究竟是什么机制阻止我使用无符号字符数据类型?它真的与字符编码有关,还是有其他用途?为什么文件流适用于有符号字符数据类型,但不适用于无符号数据类型?
  2. 假设我仍然想使用std::basic_fstream<uint8_t>,无论它多么(不)合理 - 有没有办法实现这一点?
0 投票
1 回答
294 浏览

c++ - 为什么 std::codecvt 仅由文件 I/O 流使用?

我一直在实现一个编解码器来处理输出流的缩进。它可以像这样使用并且工作正常:

然而,当我发现我的std::codecvt代码和.std::ostreamstd::coutstd::ofstreamstd::ostringstreamstd::ostream

facet 构造正常,代码编译,不会抛出任何异常……只是没有std::codecvt调用 的成员函数。

对我来说,这非常令人困惑,我不得不花费大量时间弄清楚它std::codecvt不会对非文件 I/O 流做任何事情。

是否有任何理由std::codecvt没有被所有继承的类使用std::ostream

此外,有没有人知道我可以依靠哪些结构来实现压头?

编辑:这是我所指的语言的一部分:

通过 std::basic_fstream 执行的所有文件 I/O 操作都使用流中包含的语言环境的 std::codecvt<CharT, char, std::mbstate_t> 方面。

来源:https ://en.cppreference.com/w/cpp/locale/codecvt


更新1:

我做了一个小例子来说明我的问题:

我会invocation_counter在流式传输后增加std::ostringstream,但事实并非如此。


更新 2:

经过更多研究,我发现我可以使用std::wbuffer_converter. 引用https://en.cppreference.com/w/cpp/locale/wbuffer_convert

std::wbuffer_convert是类型的流缓冲区的包装器, std::basic_streambuf<char>使其外观为 std::basic_streambuf<Elem>. 所有通过执行的 I/O 都 std::wbuffer_convert经历了由方面 Codecvt 定义的字符转换。[...]

此类模板使隐式字符转换功能std::basic_filebuf可用于任何 std::basic_streambuf.

这样我可以将一个方面应用于std::ostringstream

但是,我失去了使用流操作符连接构面的能力<<

这让我更加困惑,为什么std::codecvt所有输出流都没有隐式使用。所有输出流都继承自std::basic_streambuf其适合使用的接口std::codecvt,它只是使用输入和输出字符序列,完全实现在std::basic_streambuf.

那么为什么解析的std::codecvt实现是 instd::basic_filebuf而不是std::basic_streambuf呢?毕竟std::basic_filebuf继承...std::basic_streambuf

要么我对流在 C++ 中的工作方式有一些基本的误解,要么std::codecvt在标准中集成得不好。也许这就是它被标记为已弃用的原因?

0 投票
1 回答
64 浏览

c++ - 什么时候 std::codecvt::always_noconv() 需要返回 true 吗?

标准 (C++17) 是否要求std::codecvt<char, char, std::mbstate_t>::always_noconv()返回 true

  • 对于所有语言环境,或
  • 对于实现提供的语言环境,或
  • 仅适用于 C 语言环境,或
  • 别的东西?

C++ 标准确实有话要说。来自 C++17 的第 25.4.1.4 节:

codecvt<char, char, mbstate_t>实现退化转换;它根本不转换。

断章取义,这强烈表明它适用于所有语言环境。尽管如此,我还是很高兴听到任何可以证实这一点的人的意见,或者有理由说明为什么不应该这样。