demo3/decode.c
2024-11-30 10:15:30 +08:00

198 lines
6.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <windows.h>
// 定义缓冲区大小(可以根据实际需求调整)
#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, // 加速度计xint16_t
buffer[i].data.ay, // 加速度计yint16_t
buffer[i].data.az, // 加速度计zint16_t
buffer[i].data.gx, // 陀螺仪xint16_t
buffer[i].data.gy, // 陀螺仪yint16_t
buffer[i].data.gz // 陀螺仪zint16_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;
}