You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将字符串中非英文字符转小写且避免出现�乱码?

解决UTF-8字符串转小写的乱码问题

问题根源

原代码的核心问题有两个:

  • ::tolower 是针对单字节ASCII字符设计的,而UTF-8编码的非英文字符(比如法语的î)是多字节结构,直接按单个字节处理会破坏编码,导致乱码。
  • 未处理UTF-8文件开头的BOM(0xEF 0xBB 0xBF),可能影响字符串的正确读取。

解决方案

要正确处理UTF-8字符串的小写转换,需要先将UTF-8编码转换为宽字符(wchar_t),使用支持多语言的小写转换函数,之后再转回UTF-8。同时要跳过文件开头的BOM。

修改后的代码示例

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <locale>
#include <codecvt>

int main() {
    std::wifstream old_file;
    std::wofstream new_file;
    std::wstring wstr;

    // 设置UTF-8编码读取,自动跳过BOM
    old_file.imbue(std::locale(old_file.getloc(), new std::codecvt_utf8<wchar_t, 0x10ffff, std::consume_header>));
    old_file.open("first.txt");

    // 设置UTF-8编码写入
    new_file.imbue(std::locale(new_file.getloc(), new std::codecvt_utf8<wchar_t>));
    new_file.open("second.txt");

    if (old_file.is_open() && new_file.is_open()) {
        std::getline(old_file, wstr);
        // 结合系统locale处理多语言字符的小写转换
        std::transform(wstr.begin(), wstr.end(), wstr.begin(), [](wchar_t c) {
            return std::towlower(c, std::locale(""));
        });
        new_file << wstr;
    }

    old_file.close();
    new_file.close();
    return 0;
}

代码说明

  1. 编码处理:使用std::codecvt_utf8<wchar_t>实现UTF-8与宽字符的双向转换,std::consume_header参数会自动识别并跳过UTF-8文件的BOM头。
  2. 小写转换:std::towlower结合系统默认locale(std::locale("")),能正确处理多语言宽字符的小写转换,不会破坏非ASCII字符的编码结构。
  3. 宽字符流:改用wifstream和wofstream处理宽字符流,确保多字节字符被完整读取和写入。

注意事项

  • 确保编译器支持C11及以上标准(codecvt组件在C11引入,C++17后需包含专门的<codecvt>头文件)。
  • Windows平台下可能需要手动设置文件或控制台的编码为UTF-8,避免后续显示或写入出现异常。

内容的提问来源于stack exchange,提问作者Mefisto1029

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:50:43