该错误源于源文件含utf-8 bom(\357\273\277)或不可见非法字符,需用file -i确认编码、xxd查看头部字节,再通过vim :set nobomb | wq! 或sed -i '1s/^\xef\xbb\xbf//'清除bom。

gcc 报错 “error: stray ‘\357’ in program” 怎么办
这基本等于源文件里混进了 UTF-8 BOM 或其他不可见控制字符,gcc 解析时直接卡在第一个字节上。不是语法问题,是文件本身“脏”了。
- 用
file -i main.c看编码,如果输出含charset=utf-8-with-bom,就坐实了 BOM 问题 - 用
xxd main.c | head -n 3查看开头几个字节:出现ef bb bf就是 UTF-8 BOM - 用
vim main.c,输入:set nobomb | wq!强制去掉 BOM 并保存(注意加!) - 或者用命令行一键清除:
sed -i '1s/^\xEF\xBB\xBF//' main.c
源码写的是中文,但 gcc 编译报错 “invalid byte sequence”
说明 gcc 读取源文件时默认用了错误的输入编码。它不自动猜编码,必须显式告诉它。
- 确认源文件真实编码:用
iconv -f gbk -t utf-8 main.c > main_utf8.c测试能否转码成功 - 若源码是 GBK 编码(常见于 Windows 记事本),编译时加
-finput-charset=GBK - 若源码是 UTF-8(推荐),但终端或编辑器偷偷加了 BOM,仍需先清 BOM,再加
-finput-charset=UTF-8 - 不要只加
-fexec-charset:它只管字符串字面量运行时怎么解释,不解决编译阶段读源码的问题
编译通过了,但运行时 printf 输出中文是乱码
编译没问题,说明源码编码和 gcc 解读一致;乱码出在运行时环境,跟终端、locale、printf 输出流编码有关。
- 先查当前 locale:
locale | grep -E "(LANG|LC_CTYPE)",必须含UTF-8(如LANG=en_US.UTF-8) - 若不是 UTF-8,临时生效:
export LANG=en_US.UTF-8,再运行程序 - Linux 终端一般没问题;Windows CMD 默认是 GBK,
chcp 65001切到 UTF-8 后再运行 - C 标准库不保证宽字符跨平台,
printf("%s", "中文")依赖底层stdout的编码设置,别试图用wprintf混搭窄字符流
为什么 -Wall 不报编码相关警告
-Wall 和 -Wextra 都不检查源文件编码问题——这不是语言规范层面的“警告”,而是预处理前的字节流解析失败。真正有用的只有错误信息本身和 file/xxd 这类底层工具。
BOM、零字节、混合编码这些不会触发语法检查,只会让 gcc 在词法分析第一轮就退出,错误位置常显示为第一行第一个字符,容易误判成“少括号”或“符号错”。实际要盯住错误信息里的十六进制字节码(比如 \357 就是 0xef),那才是破案关键。











