C++读取UTF-8编码的ipk.dat文件输出乱码如何解决
问题原因
你看到的┬á乱码是字符编码不匹配导致的:
- 你的
ipk.dat是UTF-8编码,姓名中间的空格实际是UTF-8的非中断空格(Unicode编码U+00A0,对应UTF-8字节序列0xC2 0xA0) - Windows系统控制台默认使用GBK/CP936编码输出,会把这两个字节按本地编码分别解析为
┬和á,就出现了你看到的乱码。
修复方案
你可以根据自己的需求选择以下任意一种方案:
方案1:修改控制台编码为UTF-8(Windows平台首选)
只需要在代码最开头添加控制台编码配置即可,无需修改文件内容:
- 引入Windows头文件
- main函数入口处设置控制台输入输出编码为UTF-8
完整修改后代码:
#include <iostream> #include <fstream> #include <sstream> #include <windows.h> using namespace std; int main() { // 设置控制台编码为UTF-8,匹配文件编码 SetConsoleOutputCP(CP_UTF8); SetConsoleCP(CP_UTF8); ifstream inGPA; string studentGPA; string studentName; inGPA.open("ipk.dat"); if (inGPA.is_open()) { string line; while (getline(inGPA, line)) { stringstream ss(line); getline(ss, studentName, ';'); getline(ss, studentGPA); if (stod(studentGPA) >= 3.0) { cout << studentName << " \t" << studentGPA << endl; } } inGPA.close(); } return 0; }
方案2:读取时替换特殊空格(跨平台通用)
如果你需要代码在Linux、Mac等平台也能正常运行,不需要依赖系统API,可以在读取姓名后将特殊空格替换为普通空格:
#include <iostream> #include <fstream> #include <sstream> using namespace std; int main() { ifstream inGPA; string studentGPA; string studentName; inGPA.open("ipk.dat"); if (inGPA.is_open()) { string line; while (getline(inGPA, line)) { stringstream ss(line); getline(ss, studentName, ';'); getline(ss, studentGPA); // 替换UTF-8非中断空格为普通空格 size_t pos = 0; while ((pos = studentName.find("\xC2\xA0", pos)) != string::npos) { studentName.replace(pos, 2, " "); pos += 1; } if (stod(studentGPA) >= 3.0) { cout << studentName << " \t" << studentGPA << endl; } } inGPA.close(); } return 0; }
内容的提问来源于stack exchange,提问作者Dede Kurniawan
相关产品推荐
相关产品推荐

