duckx读取.docx出现乱码的根本原因是utf-8内部存储与终端gbk解码不匹配;linux/macos终端默认utf-8通常正常,windows控制台需改用std::wcout或转本地编码输出。

DuckX 是目前 C++ 项目中解析 .docx 最轻量、最直接的选择——它不依赖 Office、不调 COM、不打包 XML 解析细节,开箱即可读取段落和文本块。
如果你正卡在“中文乱码”“找不到段落”“编译报 undefined reference”,大概率不是库不行,而是初始化或编码处理没对。
用 DuckX 读取 docx 文本时为什么全是乱码?
根本原因是:DuckX 内部以 UTF-8 存储文本,但你的终端或 IDE 默认用 GBK/GBK2312 解码显示。
- Linux/macOS 终端通常默认 UTF-8,一般不会乱码;Windows 控制台默认是 GBK,
std::cout 就会显示为方块或问号 - 解决方法不是改库,而是改输出方式:用
std::wcout+std::locale(""),或把字符串转成本地编码再输出(如 Windows 下用WideCharToMultiByte(CP_ACP, ...)) - 若只是调试查看,可临时把
r.get_text()写入 UTF-8 编码的文件,再用 VS Code 或记事本(UTF-8 模式)打开验证内容是否正确
DuckX::Document::open() 失败但没报错,怎么办?
open() 返回 void,不抛异常也不返回状态码——这是初学者最容易忽略的设计点。
- 必须在
open()后立刻检查doc.is_open(),否则后续paragraphs()可能返回空迭代器,循环直接跳过 - 路径错误(相对路径没对准)、文件被占用、权限不足、或文件实际是
.doc(非.docx)都会导致is_open() == false - 建议加一行诊断输出:
if (!doc.is_open()) { std::cerr
遍历段落时为什么 paragraphs() 没内容?
常见于文档含大量表格、文本框、页眉页脚——DuckX 当前版本(v0.5.x)的 paragraphs() 只返回主文档流中的段落,不包含表格单元格内文本或页眉内容。
- 表格里的文字需单独访问:
for (auto& table : doc.tables()) { for (auto& row : table.rows()) { for (auto& cell : row.cells()) { for (auto r : cell.paragraphs().runs()) { ... } } } } - 页眉/页脚暂不支持,强行读取会跳过;若需提取,得换
DocxFactory或手动解压.docx包查header1.xml - 空段落(仅含换行符)会被跳过,
r.get_text().empty()不一定代表没内容,可能含空格或制表符,建议用utf8::length(r.get_text())判断有效字符数
DuckX 接口简洁,但结构隐含层级;表格、样式、编码这三处,最容易在交付前一小时才发现数据不对。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











