目录
问题的由来
编码导致的问题
解决办法
VSCode进行转换
记事本进行转换
直接指定输出的文本编码
总结
问题的由来
在我的嵌入式系统的课程中有一个裸机开发的实验,其中需要把图片等文件转换为C语言数组保存在程序中。课程中,我推荐了CodePlea的hexembed工具来进行转换,它将转换结果输出到标准输出设备,使用重定向可以保存为文件。这个方法用了几年也没啥问题,不过今年由于使用Windows 11的同学增多,一些同学反应生成的文件在我们裸机开发的环境无法编译,会报告错误。今天来分析一下原因,并给出几个解决的办法。
编码导致的问题
我们使用如下的命令进行重定向保存文本。
.\hexembed.exe .\hexembed.c > hex.h
这个方法在先前的Windows版本中都没有问题。不过在Windows 11中默认使用PowerShell作为终端,而其默认的文本输出编码格式为UTF-16LE。
如果用VS Code或者记事本打开文件,都可以在右下角看到文件的编码格式。
UTF - 16 是一种 Unicode 编码方式,它使用 16 位(2 个字节)或 32 位(4 个字节)来表示一个字符。UTF - 16 LE 是 UTF - 16 的小端字节序(Little - Endian)版本,即低位字节存储在低地址,高位字节存储在高地址。对于英文文本,UTF - 8 每个字符占用 1 个字节,而 UTF - 16 LE 每个字符至少占用 2 个字节,所以 UTF - 8 更节省空间。对于中文等非 ASCII 字符,UTF - 8 通常使用 3 个字节,UTF - 16 LE 使用 2 个字节,在这种情况下 UTF - 16 LE 更节省空间。我们可以用VS Code的Hex插件打开所转换得到的文件,就可以清楚地看到它的编码特点了。
一般的文本编辑器都可以正确处理UTF -16 LE的文本,所以我们感觉不到这种编码差别,但是裸机开发使用的GCC编译器不支持这种格式的文本,就会出现编译错误。
解决办法
下面就介绍几种解决这个问题的方法。
VSCode进行转换
在VS Code中可以点击右下角的UTF-16 LE,然后在弹出的选项中选择“Save with Encoding”,选择Western作为保存的编码格式,然后按CTRL+S保存文件即可。
记事本进行转换
可以使用记事本打开文件,然后在“另存为”的对话框中指定编码方式为ANSI。
直接指定输出的文本编码
也可以在PowerShell进行重定向时指定编码格式,不过此时不能使用“>”符号了,需要改用“|”符号,如:
.\hexembed.exe .\hexembed.c | Out-File hex.h -encoding ASCII
这样生成的文件直接就是ANSI格式的了。
总结
由于大多数编译器都是基于ANSI的,所以在文件的编码格式对于编程就需要格外小心。