Qt项目中遇到UTF-8BOM问题

首先UTF-8和UTF-8BOM在开始的前3个字节是不一样的,UTF-8 BOM是Windows用来识别UTF-8的一种方式
但是如果项目中文件是UTF-8 BOM编码,那大概会编译不通过,然后编译输出中会出现一堆乱码的东西
而出现的原因大多数是用多个编译器打开同一个项目
比如我用Qt打开编辑后保存,然后用Trae或者Cursor的agent模式进行修bug,那这样就会造成多次添加UTF-8 BOM
1. 那出现了UTF-8 BOM后如何改为UTF-8
我们用powershell输入一下命令,直接剔除BOM

点击查看代码
# 扫描项目下所有源文件,字节级剥离开头的所有 BOM (EF BB BF)
$srcDir = "你的项目目录"
$files = Get-ChildItem -Path $srcDir -Recurse -Include "*.cpp","*.h","*.txt","*.qss","*.qrc","*.ui" |
    Where-Object { $_.FullName -notmatch "\\build\\" -and $_.FullName -notmatch "\\\.cache\\" }

foreach ($f in $files) {
    $bytes = [IO.File]::ReadAllBytes($f.FullName)
    $start = 0
    # 逐字节检查开头是否为 EF BB BF,是就跳过 3 字节,循环直到没有 BOM
    while ($start + 2 -lt $bytes.Length -and
           $bytes[$start]     -eq 0xEF -and
           $bytes[$start + 1] -eq 0xBB -and
           $bytes[$start + 2] -eq 0xBF) {
        $start += 3
    }
    if ($start -gt 0) {
        $newBytes = New-Object byte[] ($bytes.Length - $start)
        [Array]::Copy($bytes, $start, $newBytes, 0, $newBytes.Length)
        [IO.File]::WriteAllBytes($f.FullName, $newBytes)
        Write-Host "Fixed ($start BOM bytes): $($f.FullName.Replace($srcDir,''))" -ForegroundColor Green
    }
}
Write-Host "`n=== BOM cleanup done ===" -ForegroundColor Cyan

然后验证是否处理干净:

点击查看代码
# 验证:打印每个源文件前 3 字节的十六进制值 (应显示 23 69 66 或 23 69 6E,不是 EF BB BF)
$srcDir = "d:\Qt\project\Agricultural"
$files = Get-ChildItem -Path $srcDir -Recurse -Include "*.cpp","*.h" |
    Where-Object { $_.FullName -notmatch "\\build\\" -and $_.FullName -notmatch "\\\.cache\\" }
foreach ($f in $files) {
    $bytes = [IO.File]::ReadAllBytes($f.FullName)
    $head = ($bytes[0..2] | ForEach-Object { $_.ToString("X2") }) -join " "
    $status = if ($bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) { "STILL HAS BOM!" } else { "OK" }
    Write-Host "[$status] $($f.Name): $head"
}

最后把build的目录删掉,重新CMake就好了

2. 我们如何在之后做项目中避免这个问题
1、首先我们可以在Qt的设置中设置UTF-8,不带BOM

屏幕截图 2026-08-13 161050
2、我们在项目的根目录下创建一个.editorconfig文件
这个文件标明编译器的规范为UTF-8,防止编辑器修改为UTF-8 BOM,防止编译不通过
文件内容是这样的:

点击查看代码
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{cpp,h,hpp,c,cc,cxx,txt,qss,qrc,cmake}]
charset = utf-8
end_of_line = lf
indent_size = 4

[*.{ui,pro,pri,xml}]
charset = utf-8
indent_size = 2

[*.json]
indent_size = 2
3、我们可以再项目根目录下创建一个.gitattributes文件 保证传入远程仓库时的代码是UTF-8类型 文件内容是这样的:
点击查看代码
# 所有文本文件统一用 UTF-8
* text=auto

# C++ 源文件:强制 UTF-8,换行符统一为 LF
*.cpp    text eol=lf working-tree-encoding=UTF-8
*.h      text eol=lf working-tree-encoding=UTF-8
*.hpp    text eol=lf working-tree-encoding=UTF-8
*.c      text eol=lf working-tree-encoding=UTF-8
*.cc     text eol=lf working-tree-encoding=UTF-8
*.cxx    text eol=lf working-tree-encoding=UTF-8

# Qt 相关文件
*.ui     text eol=lf working-tree-encoding=UTF-8
*.qss    text eol=lf working-tree-encoding=UTF-8
*.qrc    text eol=lf working-tree-encoding=UTF-8
*.pro    text eol=lf working-tree-encoding=UTF-8
*.pri    text eol=lf working-tree-encoding=UTF-8

# 其他文本
*.txt    text eol=lf working-tree-encoding=UTF-8
*.cmake  text eol=lf working-tree-encoding=UTF-8
CMakeLists.txt text eol=lf working-tree-encoding=UTF-8

# 二进制文件不做转换
*.png    binary
*.jpg    binary
*.gif    binary
*.ico    binary
*.exe    binary
*.dll    binary
*.lib    binary
*.pdf    binary
*.zip    binary

posted on 2026-08-13 16:37  dd_l  阅读(2)  评论(0)    收藏  举报