当前位置: 首页 > news >正文

【蛋疼c++】千万别用std::wifstream读取Unicode UTF16文件

上当了。

最近程序要和 Jscript / activex 脚本通信。

ActiveX这玩意,导出文件,如果是UTF8导出,会出现莫名异常:写一半直接退出。或许是系统语言设置的问题。

但是切换为utf16(unicode)导出就没有问题:

OpenTextFile method (Visual Basic for Applications) | Microsoft Learn

var fso = new ActiveXObject("Scripting.FileSystemObject");
var file = fso.CreateTextFile("", true, true );

然而蛋疼还没有完。在C++程序中,UTF8文件直接用 stf::ifstream 读进来就可以。

std::ifstream file(L"");if (file.is_open()) {std::string line;while (std::getline(file, line)) {...}}file.close();

但 UTF16 却不能直接用 std::wifstream 读取。 StackOverflow 上有人说,需要告知 std::wifstream 编码格式。 c++ 标准库才会跳过bom、进行逐行解码。

有人整理如下:(18)用std::wifstream读取Unicode文本-CSDN博客

结果第二天就出现问题。一些特殊表情符号直接空白(比如:🍓)。或许是,这个办法不支持UTF16的surrogate pair,四个字节的符号。

我勒个去,编码直接变没了!

震惊!

立马鞭策chatgpt,让他写个直接读到 TCHAR* 数组里的替代办法,一点问题没有!c++还真是蛋疼啊~

TCHAR* ReadUTF16File(const TCHAR* filePath) {HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE) {// Handle file opening errorreturn NULL;}DWORD fileSize = GetFileSize(hFile, NULL);TCHAR* buffer = new TCHAR[fileSize / sizeof(TCHAR) + 1];DWORD bytesRead = 0;ReadFile(hFile, buffer, fileSize, &bytesRead, NULL);buffer[fileSize / sizeof(TCHAR)] = '\0';CloseHandle(hFile);return buffer;
}
std::vector<std::wstring> _args;
QkString ln;if(StrCmpN(_args[i].c_str(), L"-loadArgsW", 10)==0) {TCHAR* all = ReadUTF16File(_args[i].c_str()+11)+1;TCHAR* current = all;TCHAR* next = nullptr;while ((next = _tcschr(current, _T('\n'))) != nullptr) {// Process the line from current to nextln.Empty();ln.Append(current, next-current);//*next = _T('\0');//_tprintf(_T("%s\n"), current);*next = _T('\n'); // Restore the newline charactercurrent = next + 1; // Move to the character after the newlineln.Trim();_args.push_back(ln.GetData());}if (*current != _T('\0')) {//_tprintf(_T("%s\n"), current);ln = current;ln.Trim();_args.push_back(ln.GetData());}}

这说明,程序里面 TCHAR* 字符串就是UTF16编码,或者说是 IE / JScript / ActiveX 认可的 unicode 编码模式,不需要 std::wifstream 多此一举地解码,直接读取到内存即可。

http://www.lryc.cn/news/419509.html

相关文章:

  • [算法] 第二集 二叉树中的深度搜索
  • 放弃使用外键时,sequelize 应该怎么使用?
  • Microsoft GraphRAG 输出的配置信息
  • 怎么判断张量的维度(形状(shape)),即如何定义行数、列数和深度的?
  • AI入门指南(二):算法、训练、模型、大模型是什么?
  • CSS已访问链接的隐私保护
  • 代码练习12-排序链表
  • Linux 内核源码分析---套接字
  • vscode配置xdebug断点调试详细教程
  • 【人工智能】Transformers之Pipeline(八):文生图/图生图(text-to-image/image-to-image)
  • AI Agent 工程师认证-学习笔记(1)——【单Agent】ModelScope-Agent
  • 【Python机器学习】树回归——将CART算法用于回归
  • 前端(HTML + CSS)小兔鲜儿项目(仿)
  • 【Rust光年纪】构建高效终端用户界面:Rust库全面解析
  • 鼠标滑动选中表格部分数据列(vue指令)
  • “5G+Windows”推动全场景数字化升级:美格智能5G智能模组SRM930成功运行Windows 11系统
  • c语言学习,isupper()函数分析
  • Adnroid 数据存储:SharedPreferences详解【SharedPreferencesUtils,SharedPreferences的ANR】
  • Sentinel 规则持久化到 Nacos 实战
  • 服务器CPU天梯图2024年8月,含EYPC/至强及E3/E5
  • SpringBoot加载dll文件示例
  • 9.C基础_指针与数组
  • C语言——结构体与共用体
  • vs+qt项目转qt creator
  • 微信小程序 checkbox 实现双向绑定以及特殊交互处理
  • 我在高职教STM32——I2C通信之读写EEPROM(1)
  • 【ARM】应用ArmDS移植最小FreeRTOS系统
  • golang下载、上传文件MD5高效计算方法,利用io.TeeReader函数特性 实时计算文件md5签名
  • TreeMap实现根据值比较
  • 2024前端面试(内容持续更新)