#include #include #include #include #include // 定义缓冲区大小(可以根据实际需求调整) #define BUFFER_SIZE 1024 // 每次读取1024条记录 // MPU传感器数据结构 typedef struct { int16_t ax; // 加速度计 X轴 int16_t ay; // 加速度计 Y轴 int16_t az; // 加速度计 Z轴 int16_t gx; // 陀螺仪 X轴 int16_t gy; // 陀螺仪 Y轴 int16_t gz; // 陀螺仪 Z轴 } sensor_data_t; // 完整的数据记录结构 #pragma pack(1) typedef struct { uint8_t y; // 年(相对值,需要加上2000) uint8_t month; // 月 uint8_t d; // 日 uint8_t h; // 时 uint8_t m; // 分 uint8_t s; // 秒 uint16_t ms; // 毫秒 int16_t deepth; // 深度 sensor_data_t data; // MPU传感器数据 } info_t; #pragma pack() void print_usage() { printf("用法:\n"); printf("decode.exe -f <文件名> [-o <输出文件名>]\n"); printf("选项:\n"); printf(" -f <文件名> 指定输入文件\n"); printf(" -o <文件名> 指定输出文件(可选,默认输出到与输入同名的.csv文件)\n"); printf(" -h 显示帮助信息\n"); printf("\n示例:\n"); printf("decode.exe -f 20241112.BIN\n"); printf("decode.exe -f 20241112.BIN -o output.csv\n"); } // 原有的decode函数保持不变 void decode(char *filename) { FILE *file = fopen(filename, "rb"); if (!file) { fprintf(stderr, "无法打开文件\n"); return; } // 获取文件大小 fseek(file, 0, SEEK_END); long fileSize = ftell(file); fseek(file, 0, SEEK_SET); // 计算记录数量 int recordCount = fileSize / sizeof(info_t); // 打印CSV格式的表头 printf("年,月,日,时,分,秒,毫秒,深度,ax,ay,az,gx,gy,gz\n"); // 使用缓冲区读取以提高效率 info_t buffer[BUFFER_SIZE]; size_t records_read; while ((records_read = fread(buffer, sizeof(info_t), BUFFER_SIZE, file)) > 0) { for (size_t i = 0; i < records_read; i++) { // 直接使用小端序数据,无需转换 // 单字节数据:y, month, d, h, m, s // 双字节数据:ms, deepth, ax, ay, az, gx, gy, gz 已经是正确的小端序 printf("%04d,%02d,%02d,%02d,%02d,%02d,%03d,%04d,%d,%d,%d,%d,%d,%d\n", buffer[i].y + 2000, // 年份偏移2000 buffer[i].month, // 月 buffer[i].d, // 日 buffer[i].h, // 时 buffer[i].m, // 分 buffer[i].s, // 秒 buffer[i].ms, // 毫秒,uint16_t buffer[i].deepth, // 深度,uint16_t buffer[i].data.ax, // 加速度计x,int16_t buffer[i].data.ay, // 加速度计y,int16_t buffer[i].data.az, // 加速度计z,int16_t buffer[i].data.gx, // 陀螺仪x,int16_t buffer[i].data.gy, // 陀螺仪y,int16_t buffer[i].data.gz // 陀螺仪z,int16_t ); } } fclose(file); fprintf(stderr, "共解析 %d 条记录\n", recordCount); } // 生成输出文件名 char* generate_output_filename(const char* input_file) { size_t len = strlen(input_file); char* output = (char*)malloc(len + 5); // +5 为了容纳 .csv 和结束符 // 复制输入文件名 strcpy(output, input_file); // 找到最后一个点的位置 char* dot = strrchr(output, '.'); if (dot != NULL) { // 如果找到点,在点的位置替换后缀 strcpy(dot, ".csv"); } else { // 如果没有找到点,直接在末尾添加.csv strcat(output, ".csv"); } return output; } int main(int argc, char *argv[]) { // 设置控制台输出代码页为 UTF-8 SetConsoleOutputCP(65001); char *input_file = NULL; char *output_file = NULL; // 解析命令行参数 for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-h") == 0) { print_usage(); return 0; } else if (strcmp(argv[i], "-f") == 0) { if (i + 1 < argc) { input_file = argv[i + 1]; i++; } else { printf("错误:-f 参数后需要指定文件名\n"); print_usage(); return 1; } } else if (strcmp(argv[i], "-o") == 0) { if (i + 1 < argc) { output_file = argv[i + 1]; i++; } else { printf("错误:-o 参数后需要指定文件名\n"); print_usage(); return 1; } } else { fprintf(stderr, "错误:未知参数 %s\n", argv[i]); print_usage(); return 1; } } // 检查必需参数 if (input_file == NULL) { fprintf(stderr, "错误:未指定输入文件\n"); print_usage(); return 1; } // 检查输入文件是否存在 FILE *file = fopen(input_file, "rb"); if (!file) { printf("错误:无法打开输入文件 %s\n", input_file); return 1; } fclose(file); // 如果没有指定输出文件,生成默认的输出文件名 char *auto_output_file = NULL; if (output_file == NULL) { auto_output_file = generate_output_filename(input_file); output_file = auto_output_file; } // 重定向标准输出到文件 if (freopen(output_file, "w", stdout) == NULL) { printf("错误:无法创建输出文件 %s\n", output_file); if (auto_output_file) free(auto_output_file); return 1; } // 解析文件 decode(input_file); // 清理 if (auto_output_file) { free(auto_output_file); } return 0; }