C++中如何解决getline读取首字符串开头出现乱码的问题?
问题描述
- 编写了从.txt文件导入字符串的函数,使用getline读取时,第一个字符串开头附带3个奇怪符号,其余字符串显示正常。
- 尝试新建文件后仍出现该问题,但用另一个.txt文件测试类似函数时无异常。
第一个字符串的输出示例:
Temperate Sundew
代码如下:
void SavagePlants::importInfo(std::fstream& importFile) { plants = new PlantCare[numPlants]; int i = 0; while (getline(importFile >> std::ws, plants[i].species, '#')) { getline(importFile, plants[i].sunlight, '#'); wrapText(plants[i].sunlight); getline(importFile, plants[i].water, '#'); wrapText(plants[i].water); getline(importFile, plants[i].temperature, '#'); wrapText(plants[i].temperature); getline(importFile, plants[i].soil, '#'); wrapText(plants[i].soil); getline(importFile, plants[i].fertilizer, '#'); wrapText(plants[i].fertilizer); getline(importFile, plants[i].dormancy, '#'); wrapText(plants[i].dormancy); ++i; } }
问题原因
这三个奇怪符号是**UTF-8字节顺序标记(BOM)**的显示结果。Windows记事本默认保存UTF-8文件时,会在文件开头添加EF BB BF三个字节的BOM来标识编码,但C++标准库的fstream默认不会识别并跳过这个标记,导致第一个getline把这三个字节当成普通字符读入,最终显示为乱码符号。
解决方法
方法1:手动跳过BOM
在读取文件内容前,先检查文件开头是否存在UTF-8 BOM,若存在则跳过这三个字节:
void SavagePlants::importInfo(std::fstream& importFile) { // 检查并跳过UTF-8 BOM char bom[3]; importFile.read(bom, 3); if (!(bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF)) { // 不是BOM,将文件指针移回开头 importFile.seekg(0); } plants = new PlantCare[numPlants]; int i = 0; while (getline(importFile >> std::ws, plants[i].species, '#')) { // 后续读取逻辑不变 getline(importFile, plants[i].sunlight, '#'); wrapText(plants[i].sunlight); getline(importFile, plants[i].water, '#'); wrapText(plants[i].water); getline(importFile, plants[i].temperature, '#'); wrapText(plants[i].temperature); getline(importFile, plants[i].soil, '#'); wrapText(plants[i].soil); getline(importFile, plants[i].fertilizer, '#'); wrapText(plants[i].fertilizer); getline(importFile, plants[i].dormancy, '#'); wrapText(plants[i].dormancy); ++i; } }
方法2:保存文件时去掉BOM
用支持无BOM UTF-8的编辑器(如Notepad++)打开文件,选择“编码”→“UTF-8无BOM”格式保存,这样文件开头就不会添加BOM标记,读取时自然不会出现乱码。
内容的提问来源于stack exchange,提问作者desdenova
相关产品推荐
相关产品推荐

