C++使用wstring读取UTF-8文件无法按行拆分及过滤无效行问题
C++ wstring读取UTF-8文件按行处理解决方案
核心问题原因
你当前代码无法正常按行读取的核心问题是wifstream没有应用你配置的UTF-8编码转换locale:你设置了全局locale,但打开文件流后流默认使用系统locale,导致UTF-8字节转wchar_t逻辑异常,读取的内容本身是乱码,后续getline自然无法正确分割行。
此外你原有按空格切分的逻辑会把连续空格、行首尾空格切出无效空字符串,也没有做行合法性校验,不符合你跳过无效行的需求。
修复后完整代码
#include <sstream> #include <fstream> #include <codecvt> #include <deque> #include <iostream> #include <fcntl.h> #include <io.h> #include <algorithm> // 辅助函数:按空白符切分宽字符串,自动过滤空字符串 std::deque<std::wstring> split_wstring(const std::wstring& str) { std::deque<std::wstring> res; std::wstringstream ss(str); std::wstring temp; // 用>>运算符自动跳过任意空白符,避免手动按空格切分产生空元素 while (ss >> temp) { res.push_back(temp); } return res; } int main() { _setmode(_fileno(stdout), _O_U8TEXT); // 配置UTF-8转换locale std::locale utf8_locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>); std::locale::global(utf8_locale); std::deque<std::wstring> valid_lines; std::deque<std::wstring> all_valid_words; std::wifstream wif(L"C:/Users/Administrator/source/repos/ConsoleApplication1/x64/Debug/data.txt"); // 关键:给文件流应用UTF-8 locale,保证编码转换正确 wif.imbue(utf8_locale); if (wif.is_open()) { std::wstring line; // 直接逐行读取,不需要先读全量内容再二次转换 while (std::getline(wif, line)) { auto words = split_wstring(line); // 合法性校验:前4项存在即切分后非空元素≥4,不符合的行直接跳过 if (words.size() >= 4) { valid_lines.push_back(line); for (const auto& w : words) { all_valid_words.push_back(w); } } } wif.close(); } else { std::wcout << L"Не удалось открыть файл!"; return 1; } // 测试输出,可根据需求调整 if (!all_valid_words.empty()) { std::wcout << all_valid_words[6]; } return 0; }
关键逻辑说明
- 取消冗余的全量文件内容读取转字符串流的操作,直接对文件流逐行读取,大文件场景下内存开销更低、性能更优
- 用
>>运算符切分单词,自动跳过空格、制表符等任意空白字符,不会产生空字符串元素,比手动按L' '切分更稳定 - 合法性校验直接判断切分后的非空元素数量是否≥4,刚好满足你只关心前4项(日期、来源、去向、金额)是否存在的需求,自动跳过
asd、- - - - -这类无效行
内容的提问来源于stack exchange,提问作者Lith
相关产品推荐
相关产品推荐

