c++ - 使用 utf-8 在 msvc 和 g++ 上的 std::fstream 不同行为
问题描述
std::string path("path.txt");
std::fstream f(path);
f.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
std::string lcpath;
f >> lcpath;
从 Windows 上读取 utf-8 文本path.txt
失败,Windows 上的 MSVC 编译器lcpath
无法将路径理解为 utf-8。
以下代码在使用 g++ 编译时在 linux 上正常工作。
std::string path("path.txt");
std::fstream ff;
ff.open(path.c_str());
std::string lcpath;
ff>>lcpath;
在 windows(MSVC) 上是否fstream
默认只假设 ascii?
在第一个片段中,如果我更改string
withwstring
和fstream
with wfstream
,lcpath
也会在 windows 上获得正确的值。
lcpath
编辑:如果我使用转换读取MultiByteToWideChar()
,我得到正确的表示。但是为什么我不能std::string
在 Windows 上直接读取一个 UTF-8 字符串呢?
解决方案
灌输打开的文件可能很麻烦:
http://www.cplusplus.com/reference/fstream/filebuf/imbue/
如果 loc 与文件流缓冲区当前使用的语言环境不同,则内部位置指针指向文件的开头,或者其编码与状态无关。否则,它会导致未定义的行为。
这里的问题是,当打开一个文件并且文件中有一个 BOM 标记时,这通常会由当前安装的本地文件从文件中读取。因此,position pointer
不再是文件的开头,我们有未定义的行为。
为了确保您的本地设置正确,您必须在打开文件之前执行此操作。
std::fstream f;
f.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
std::string path("path.txt");
f.open(path);
std::string lcpath;
f >> lcpath;
推荐阅读
- react-native - 防止 iOS 在 React Native TextInput 中将双连字符变成“破折号”
- javascript - 如何获得正确分页的下一个结果
- arrays - UIImage 没有出现在 UIScrollView 中
- java - 有没有办法将不断变化的数组反复传递给 Java Canvas 并让它更新屏幕?
- javascript - 如何改进我的代码,为什么它不运行?
- c++ - 按升序排列值的算法
- c++ - c ++迭代基类和派生类
- gcc - 有没有办法指向正确的 gcc 版本?
- node.js - Mongo/Express:如果没有通过查询参数,如何返回集合中的所有文档?
- c++ - 尝试打开 TCP 套接字时出错 - C++