添加多平台支持

This commit is contained in:
CSSC-WORK\murmur 2024-11-30 11:06:18 +08:00
parent 6a935c877c
commit 42cfecb0cd
2 changed files with 121 additions and 70 deletions

27
Makefile Normal file
View File

@ -0,0 +1,27 @@
CC = gcc
CFLAGS = -O2 -Wall
# 检测操作系统类型
ifeq ($(OS),Windows_NT)
TARGET = decode.exe
RM = del /Q
else
TARGET = decode
RM = rm -f
endif
SRCS = decode.c
OBJS = $(SRCS:.c=.o)
.PHONY: all clean
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $<
clean:
$(RM) $(OBJS) $(TARGET)

164
decode.c
View File

@ -1,11 +1,23 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <windows.h>
// 定义缓冲区大小(可以根据实际需求调整)
#define BUFFER_SIZE 1024 // 每次读取1024条记录
// 操作系统相关头文件
#ifdef _WIN32
#include <windows.h>
#define PATH_SEPARATOR '\\'
#else
#include <unistd.h>
#include <locale.h>
#define PATH_SEPARATOR '/'
#endif
#define BUFFER_SIZE 1024
// 平台无关的结构体定义
#pragma pack(1)
// MPU传感器数据结构
typedef struct {
int16_t ax; // 加速度计 X轴
@ -17,7 +29,6 @@ typedef struct {
} sensor_data_t;
// 完整的数据记录结构
#pragma pack(1)
typedef struct {
uint8_t y; // 年相对值需要加上2000
uint8_t month; // 月
@ -31,8 +42,38 @@ typedef struct {
} info_t;
#pragma pack()
// 平台相关的函数封装
void platform_init(void) {
#ifdef _WIN32
// Windows: 设置控制台代码页为UTF-8
SetConsoleOutputCP(65001);
#else
// Linux: 设置locale为UTF-8
setlocale(LC_ALL, "en_US.UTF-8");
#endif
}
// 生成输出文件名
char* generate_output_filename(const char* input_file) {
size_t len = strlen(input_file);
char* output = (char*)malloc(len + 5); // +5 for ".csv\0"
if (!output) return NULL;
strcpy(output, input_file);
// 找到最后一个点的位置
char* dot = strrchr(output, '.');
if (dot != NULL) {
strcpy(dot, ".csv");
} else {
strcat(output, ".csv");
}
return output;
}
// 检测系统字节序
static uint8_t is_little_endian() {
static uint8_t is_little_endian(void) {
uint16_t test = 0x0001;
return *(uint8_t *)&test;
}
@ -46,41 +87,30 @@ static int16_t swap_int16(int16_t val) {
return (val << 8) | ((val >> 8) & 0xFF);
}
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) {
uint8_t sys_is_le = is_little_endian();
#ifdef _WIN32
fprintf(stderr, "系统类型: Windows\n");
#else
fprintf(stderr, "系统类型: Linux\n");
#endif
fprintf(stderr, "系统字节序: %s\n", sys_is_le ? "小端序" : "大端序");
FILE *file = fopen(filename, "rb");
if (!file) {
fprintf(stderr, "无法打开文件\n");
fprintf(stderr, "无法打开文件: %s\n", filename);
return;
}
// 检测系统字节序
uint8_t sys_is_le = is_little_endian();
// 显示系统字节序
fprintf(stderr, "系统字节序: %s\n",
sys_is_le ? "小端序" : "大端序");
// 获取文件大小
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
// 计算记录数量
int recordCount = fileSize / sizeof(info_t);
size_t recordCount = fileSize / sizeof(info_t);
// 打印CSV格式的表头
printf("年,月,日,时,分,秒,毫秒,深度,ax,ay,az,gx,gy,gz\n");
@ -130,41 +160,41 @@ void decode(char *filename) {
fclose(file);
fprintf(stderr, "共解析 %d 条记录\n", recordCount);
fprintf(stderr, "共解析 %zu 条记录\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;
void print_usage(const char* program_name) {
fprintf(stderr, "用法:\n");
#ifdef _WIN32
fprintf(stderr, "%s -f <文件名> [-o <输出文件名>]\n", program_name);
#else
fprintf(stderr, "./%s -f <文件名> [-o <输出文件名>]\n", program_name);
#endif
fprintf(stderr, "选项:\n");
fprintf(stderr, " -f <文件名> 指定输入文件\n");
fprintf(stderr, " -o <文件名> 指定输出文件(可选,默认输出到与输入同名的.csv文件\n");
fprintf(stderr, " -h 显示帮助信息\n");
fprintf(stderr, "\n示例:\n");
#ifdef _WIN32
fprintf(stderr, "%s -f 20241112.BIN\n", program_name);
fprintf(stderr, "%s -f 20241112.BIN -o output.csv\n", program_name);
#else
fprintf(stderr, "./%s -f 20241112.BIN\n", program_name);
fprintf(stderr, "./%s -f 20241112.BIN -o output.csv\n", program_name);
#endif
}
int main(int argc, char *argv[]) {
// 设置控制台输出代码页为 UTF-8
SetConsoleOutputCP(65001);
// 平台初始化
platform_init();
char *input_file = NULL;
char *output_file = NULL;
// 解析命令行参数
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0) {
print_usage();
print_usage(argv[0]);
return 0;
}
else if (strcmp(argv[i], "-f") == 0) {
@ -172,8 +202,8 @@ int main(int argc, char *argv[]) {
input_file = argv[i + 1];
i++;
} else {
printf("错误:-f 参数后需要指定文件名\n");
print_usage();
fprintf(stderr, "错误:-f 参数后需要指定文件名\n");
print_usage(argv[0]);
return 1;
}
}
@ -182,14 +212,14 @@ int main(int argc, char *argv[]) {
output_file = argv[i + 1];
i++;
} else {
printf("错误:-o 参数后需要指定文件名\n");
print_usage();
fprintf(stderr, "错误:-o 参数后需要指定文件名\n");
print_usage(argv[0]);
return 1;
}
}
else {
fprintf(stderr, "错误:未知参数 %s\n", argv[i]);
print_usage();
print_usage(argv[0]);
return 1;
}
}
@ -197,18 +227,10 @@ int main(int argc, char *argv[]) {
// 检查必需参数
if (input_file == NULL) {
fprintf(stderr, "错误:未指定输入文件\n");
print_usage();
print_usage(argv[0]);
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) {
@ -217,10 +239,12 @@ int main(int argc, char *argv[]) {
}
// 重定向标准输出到文件
if (freopen(output_file, "w", stdout) == NULL) {
printf("错误:无法创建输出文件 %s\n", output_file);
if (auto_output_file) free(auto_output_file);
return 1;
if (output_file != NULL) {
if (freopen(output_file, "w", stdout) == NULL) {
fprintf(stderr, "错误:无法创建输出文件 %s\n", output_file);
if (auto_output_file) free(auto_output_file);
return 1;
}
}
// 解析文件