Windows下GnuPlot报“Bad data on line 1”问题(PowerShell编码原因)
背景
Windows 10系统中,编译后的C代码生成的数据文件无法被GnuPlot读取。
补充说明:实际问题根源是Windows PowerShell环境强制的字符编码规则。
问题详情
用于测试的简化数据文件data1内容如下:
0.0000e+00 0.0000e+00 5.0000e-01 2.5000e-01
该文件由以下C代码编译生成:
#include <stdio.h> void main() { double x=0.0 , y=0.0; printf("%.4e %.4e\n",x,y); x=0.5; y=x*x; printf("%.4e %.4e\n",x,y); }
代码在Visual Studio Code 1.84.2中,使用MSYS2版本12.2.0的gcc编译为可执行文件SPAM,随后在Windows PowerShell中执行命令 ./SPAM > data1 生成数据文件。
补充说明:问题核心是Windows PowerShell通过重定向符号>将程序输出编码为UTF-16 LE BOM格式,而GnuPlot无法识别这种编码。
使用GnuPlot 5.4(patchlevel 8)执行plot 'data1'时,触发报错:
gnuplot> plot 'data1' ^ Bad data on line 1 of file data1
已尝试的解决方法
- 使用
plot '-'直接输入数据,GnuPlot可以正常运行 - 用Notepad++查看数据文件,未发现隐藏或特殊字符
- 将数据文件内容复制粘贴到新文件可解决问题,但数据文件体积庞大,无法批量操作
问题解答
0. 数据文件中存在什么GnuPlot不兼容的隐藏内容?
数据文件开头带有UTF-16 LE的BOM(字节顺序标记),同时整个文件采用UTF-16编码存储字符。GnuPlot默认以ASCII/UTF-8编码读取文本文件,UTF-16的双字节存储格式会让GnuPlot把原本的数字解析成乱码,导致识别失败。
1. 是否可通过修改GnuPlot的设置/参数解决该问题?
GnuPlot 5.4版本本身对UTF-16编码的支持有限,没有直接的配置参数可以切换编码读取模式,因此无法单纯通过修改GnuPlot设置解决,需要从数据文件的编码入手调整。
2. 我的VSC和gcc安装/编译配置是否存在问题,导致生成异常文件?
你的VSC和gcc编译配置没有问题——C程序本身输出的是ASCII编码的文本,问题出在PowerShell的重定向操作上:PowerShell默认会把程序的标准输出重定向为UTF-16 LE编码的文件,和编译环节无关。
批量解决方法
- 修改PowerShell重定向编码
在执行重定向命令前,先设置PowerShell的输出编码为UTF-8(无BOM):$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() ./SPAM > data1 - 使用CMD执行重定向
CMD的重定向默认采用ASCII编码,不会强制转换为UTF-16,直接在CMD中运行:SPAM.exe > data1 - 在C程序中直接写入文件
跳过命令行重定向,在代码中直接打开文件并写入数据,避免编码被篡改:#include <stdio.h> int main() { FILE *fp = fopen("data1", "w"); if (fp == NULL) return 1; double x=0.0 , y=0.0; fprintf(fp, "%.4e %.4e\n",x,y); x=0.5; y=x*x; fprintf(fp, "%.4e %.4e\n",x,y); fclose(fp); return 0; }
内容的提问来源于stack exchange,提问作者Rrr

