From e3571db92564f61ca1445036a263011c334cfed1 Mon Sep 17 00:00:00 2001 From: LuChiChick <1084116302@qq.com> Date: Wed, 17 Sep 2025 09:55:13 +0800 Subject: [PATCH] Project reconstructed && Fix speed issue caused by excessive IO frequency && New information and progress bar output --- .gitignore | 2 + .vscode/c_cpp_properties.json | 18 +++ .vscode/launch.json | 18 +++ .vscode/tasks.json | 17 +++ Inc/Config.hpp | 10 ++ Inc/Global_Variables.hpp | 13 ++ Inc/Tool_Functions.hpp | 25 ++++ Inc/Type_Descriptions.hpp | 28 ++++ Makefile | 223 +++++++++++++++++++++++++++++++ Src/Global_Variables.cpp | 8 ++ SNOOPerToCSV.cpp => Src/Main.cpp | 196 +++++++++++---------------- Src/Tool_Functions.cpp | 141 +++++++++++++++++++ 12 files changed, 579 insertions(+), 120 deletions(-) create mode 100644 .gitignore create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 Inc/Config.hpp create mode 100644 Inc/Global_Variables.hpp create mode 100644 Inc/Tool_Functions.hpp create mode 100644 Inc/Type_Descriptions.hpp create mode 100644 Makefile create mode 100644 Src/Global_Variables.cpp rename SNOOPerToCSV.cpp => Src/Main.cpp (68%) create mode 100644 Src/Tool_Functions.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb75516 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Build/ +Test/ \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..b553091 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/Inc", + "${workspaceFolder}/**" + ], + "defines": [ + "UNICODE", + "_UNICODE" + ], + "cStandard": "c17", + "cppStandard": "c++17" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ade11ff --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "[SNOOPerToCSV]构建并调试", + "type": "cppdbg", + "request": "launch", + "preLaunchTask": "project_debug_build_task", // 预构建脚本 + "program": "${workspaceFolder}\\Build\\Debug\\SNOOPerToCSV.exe", // 调试目标 + "args": [ // 附加参数 + ], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", // 工作目录 + "environment": [], + // "console": "externalTerminal", + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..8a5e69b --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + "tasks": [ + { + "label": "project_debug_build_task", //定义的Task标签 + "type": "shell", //Task执行的类型 + "options": { + "cwd": "${workspaceFolder}" // 工作目录 + }, + "command": "make", //运行的命令 + "args": [ // 附加参数 + "debug", + "-j4" + ], + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/Inc/Config.hpp b/Inc/Config.hpp new file mode 100644 index 0000000..e643d0a --- /dev/null +++ b/Inc/Config.hpp @@ -0,0 +1,10 @@ +#ifndef __CONFIG_HPP__ +#define __CONFIG_HPP__ + +// 进度条长度 +#define PROGRESS_LENGTH 29 + +// 默认数值类型 +#define DEFAULT_VALUE_TYPE "uint64_t" + +#endif \ No newline at end of file diff --git a/Inc/Global_Variables.hpp b/Inc/Global_Variables.hpp new file mode 100644 index 0000000..6d1a29f --- /dev/null +++ b/Inc/Global_Variables.hpp @@ -0,0 +1,13 @@ +#ifndef __GLOBAL_VARIABLES_HPP__ +#define __GLOBAL_VARIABLES_HPP__ + +#include "Type_Descriptions.hpp" + +// 文件列表 +extern file_node *file_list_head; +// 值列表 +extern value_node *value_list_head; +// 起始时间戳 +extern double time_begin; + +#endif \ No newline at end of file diff --git a/Inc/Tool_Functions.hpp b/Inc/Tool_Functions.hpp new file mode 100644 index 0000000..7012405 --- /dev/null +++ b/Inc/Tool_Functions.hpp @@ -0,0 +1,25 @@ +#ifndef __TOOL_FUNCTIONS_HPP__ +#define __TOOL_FUNCTIONS_HPP__ + +#include "Config.hpp" + +extern "C" +{ +#include "stdint.h" +#include "stdio.h" +#include "stdbool.h" +} + +// 行进到上一行起始位置 +size_t f_seek_pre_line_begin(FILE *file); + +// 读取文件一行 +size_t f_getline(FILE *file, char *buffer, const size_t buffer_len); + +// 进度条打印 +void progress_print(size_t completed, size_t total, bool reflush); + +// 16进制字符串转十进制数值(8字节) +uint64_t hex_to_decimal(const char *str); + +#endif \ No newline at end of file diff --git a/Inc/Type_Descriptions.hpp b/Inc/Type_Descriptions.hpp new file mode 100644 index 0000000..c2b462d --- /dev/null +++ b/Inc/Type_Descriptions.hpp @@ -0,0 +1,28 @@ +#ifndef __TYPE_DESCRIPTIONS_HPP__ +#define __TYPE_DESCRIPTIONS_HPP__ + +#include "Config.hpp" + +extern "C" +{ +#include "stdint.h" +} + +// 文件链表节点 +typedef struct file_node_struct +{ + const char *file_name_str = nullptr; + file_node_struct *p_next = nullptr; +} file_node; + +// 数据列表 +typedef struct value_node_struct +{ + char value_name_str[100] = {'\0'}; + const char *value_type_str = "uint64_t"; + uint64_t raw_value = 0x0000000000000000; + value_node_struct *p_next; +} value_node; + +// 数据类型 +#endif diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9deade0 --- /dev/null +++ b/Makefile @@ -0,0 +1,223 @@ +# 目标文件名称 +TARGET_FILE_NAME = SNOOPerToCSV + +# 编译目录 +BUILD_DIR = Build + +# Release 编译子目录 +SUB_DIR_RELEASE = Release + +# Debug 编译子目录 +SUB_DIR_DEBUG = Debug + +# Release 优化等级 +RELEASE_OPT = -Os + +# Debug 优化等级 +DEBUG_OPT = -O0 + +# GUI或CUI编译选项 [0]CUI/Console [1]GUI +GUI = 0 + +# C编译标准 +C_STD = c17 + +# C++编译标准 +CXX_STD = c++17 + +# 源文件编码定义 +INPUT_CHAR_ENCODING = UTF-8 + +# 编译产物单字节字符(char)编码定义 +OUTPUT_CHAR_ENCODING = GBK + +# 编译产物宽字符(wchar_t)编码定义 +OUTPUT_WCHAR_ENCODING = UTF-16LE + +# 编译工具前缀 +COMPLIER_PREFIX = \ + +# C编译工具 +C_COMPLIER = $(strip $(COMPLIER_PREFIX))gcc + +# C++编译工具 +C++_COMPLIER = $(strip $(COMPLIER_PREFIX))g++ + +# Windows 资源文件编译工具 +WIN_RES_COMPLIER = windres + +################################################################################## + +# 链接库 +LIB_LINK = \ + +# C定义 +C_DEFS = \ +_UNICODE \ +UNICODE \ + +# C头文件目录 +C_INCLUDES_PATHS = \ + +# C源文件目录 +C_SOURCES_PATHS = \ + +# C额外单个源文件 +C_EXTERA_SOURCES = \ + +# C++定义 +CXX_DEFS = \ +_UNICODE \ +UNICODE \ + +# C++ 头文件目录 +CXX_INCLUDES_PATHS = \ +Inc \ + +# C++源文件目录 +CXX_SOURCES_PATHS = \ +Src \ + +# C++额外单个源文件 +CXX_EXTERA_SOURCES = \ + +# Windows 资源文件脚本头文件路径 +WIN_RESOURCE_INCLUDES_PATHS = \ + +# Windows 资源文件脚本列表 +WIN_RESOURCE_SCRIPTS = \ + +################################################################################## + +# C编译选项 +CFLAGS = $(foreach text,$(C_DEFS),$(addprefix -D,$(text))) \ + $(foreach path,$(C_INCLUDES_PATHS),$(addprefix -I,$(path))) \ + -std=$(strip $(C_STD)) \ + -finput-charset=$(strip $(INPUT_CHAR_ENCODING)) \ + -fexec-charset=$(strip $(OUTPUT_CHAR_ENCODING)) \ + -fwide-exec-charset=$(strip $(OUTPUT_WCHAR_ENCODING)) \ + -static \ + -Wall \ + -MMD -MP -MF"$(@:%.o=%.d)" \ + +# C++编译选项 +CXXFLAGS = $(foreach text,$(CXX_DEFS),$(addprefix -D,$(text))) \ + $(foreach path,$(CXX_INCLUDES_PATHS),$(addprefix -I,$(path))) \ + -std=$(strip $(CXX_STD)) \ + -finput-charset=$(strip $(INPUT_CHAR_ENCODING)) \ + -fexec-charset=$(strip $(OUTPUT_CHAR_ENCODING)) \ + -fwide-exec-charset=$(strip $(OUTPUT_WCHAR_ENCODING)) \ + -static \ + -Wall \ + -MMD -MP -MF"$(@:%.o=%.d)" \ + -lstdc++ \ + +# 链接选项 +LDFLAGS = -Wl,-Map,$(basename $@).map \ + +################################################################################## + +# GUI与CUI选项附加 +ifeq ($(GUI), 1) +LDFLAGS += -mwindows +else +LDFLAGS += -mconsole +endif + +# C目标文件及索引目录关联 +OBJECTS = $(notdir $(C_EXTERA_SOURCES:.c=.o)) +OBJECTS += $(subst .c,.o,$(notdir $(foreach path,$(C_SOURCES_PATHS),$(wildcard $(path)/*.c)))) +vpath %.c $(sort $(dir $(C_EXTERA_SOURCES))) $(sort $(C_SOURCES_PATHS)) + +# C++目标文件及索引目录关联 +OBJECTS += $(notdir $(CXX_EXTERA_SOURCES:.cpp=.o)) +OBJECTS += $(subst .cpp,.o,$(notdir $(foreach path,$(CXX_SOURCES_PATHS),$(wildcard $(path)/*.cpp)))) +vpath %.cpp $(sort $(dir $(CXX_EXTERA_SOURCES))) $(sort $(CXX_SOURCES_PATHS)) + +# Windows资源文件及索引目录关联 +OBJECTS += $(notdir $(WIN_RESOURCE_SCRIPTS:.rc=.o)) +vpath %.rc $(sort $(dir $(WIN_RESOURCE_SCRIPTS))) + + +# Release 目标文件 +RELEASE_OBJECTS = $(addprefix $(BUILD_DIR)/$(SUB_DIR_RELEASE)/,$(OBJECTS)) + +# Debug 目标文件 +DEBUG_OBJECTS = $(addprefix $(BUILD_DIR)/$(SUB_DIR_DEBUG)/,$(OBJECTS)) + +################################################################################## + +# all任务 目标为 release 和 debug 产物 +all: $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).exe $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).exe + @echo ====== [All] Build Procedure Accomplished ====== + +# release任务 目标为 release 产物 +release: $(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).exe + @echo ====== [Release] Build Procedure Accomplished ====== + +# debug任务 目标为 debug 产物 +debug: $(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).exe + @echo ====== [Debug] Build Procedure Accomplished ====== + +# 清理任务 +clean: $(BUILD_DIR) + powershell rm -r $(BUILD_DIR) + +# 构建目录生成 +$(BUILD_DIR): + powershell mkdir $@ + +# Release 工作目录生成 +$(BUILD_DIR)/$(SUB_DIR_RELEASE): | $(BUILD_DIR) + powershell mkdir $@ + +# Debug 工作目录生成 +$(BUILD_DIR)/$(SUB_DIR_DEBUG): | $(BUILD_DIR) + powershell mkdir $@ + +# Release 最终可执行文件编译任务 +$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(TARGET_FILE_NAME).exe: $(RELEASE_OBJECTS) + @echo ====== [Release] All File Compiled. Now Linking... ====== + $(C++_COMPLIER) $(RELEASE_OBJECTS) -static -o $@ $(LIB_LINK) $(LDFLAGS) + @echo ====== [Release] Program Link Finished ====== + +# Debug 最终可执行文件编译任务 +$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(TARGET_FILE_NAME).exe: $(DEBUG_OBJECTS) + @echo ====== [Debug] All File Compiled. Now Linking... ====== + $(C++_COMPLIER) $(DEBUG_OBJECTS) -static -o $@ $(LIB_LINK) $(LDFLAGS) + @echo ====== [Debug] Program Link Finished ====== + +# C Release 目标文件编译 +$(BUILD_DIR)/$(SUB_DIR_RELEASE)%.o: %.c Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE) + @echo ====== [Release] C Source File "$<" Compiling... ====== + $(C_COMPLIER) -c $(CFLAGS) $(RELEASE_OPT) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(notdir $(<:.c=.lst)) $< -o $@ + +# C++ Release 目标文件编译 +$(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.cpp Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE) + @echo ====== [Release] C++ Source File "$<" Compiling... ====== + $(C++_COMPLIER) -c $(CXXFLAGS) $(RELEASE_OPT) -Wa,-a,-ad,-ahlms=$(BUILD_DIR)/$(SUB_DIR_RELEASE)/$(notdir $(<:.cpp=.lst)) $< -o $@ + +# Release 资源脚本文件编译 +$(BUILD_DIR)/$(SUB_DIR_RELEASE)/%.o: %.rc Makefile | $(BUILD_DIR)/$(SUB_DIR_RELEASE) + @echo ====== [Release] Windows Resource Script File "$<" Compiling... ====== + $(WIN_RES_COMPLIER) $(foreach path,$(WIN_RESOURCE_INCLUDES_PATHS),$(addprefix -I,$(path))) $< -o $@ + +# C Debug 目标文件编译 +$(BUILD_DIR)/$(SUB_DIR_DEBUG)%.o: %.c Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG) + @echo ====== [Debug] C Source File "$<" Compiling... ====== + $(C_COMPLIER) -c $(CFLAGS) $(DEBUG_OPT) -g -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(notdir $(<:.c=.lst)) $< -o $@ + +# C++ Debug 目标文件编译 +$(BUILD_DIR)/$(SUB_DIR_DEBUG)/%.o: %.cpp Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG) + @echo ====== [Debug] C++ Source File "$<" Compiling... ====== + $(C++_COMPLIER) -c $(CXXFLAGS) $(DEBUG_OPT) -g -Wa,-a,-ad,-ahlms=$(BUILD_DIR)/$(SUB_DIR_DEBUG)/$(notdir $(<:.cpp=.lst)) $< -o $@ + +# Debug 资源脚本文件编译 +$(BUILD_DIR)/$(SUB_DIR_DEBUG)/%.o: %.rc Makefile | $(BUILD_DIR)/$(SUB_DIR_DEBUG) + @echo ====== [Debug] Windows Resource Script File "$<" Compiling... ====== + $(WIN_RES_COMPLIER) $(foreach path,$(WIN_RESOURCE_INCLUDES_PATHS),$(addprefix -I,$(path))) $< -o $@ + + +# 依赖关系 +-include $(RELEASE_OBJECTS:.o=.d) +-include $(DEBUG_OBJECTS:.o=.d) \ No newline at end of file diff --git a/Src/Global_Variables.cpp b/Src/Global_Variables.cpp new file mode 100644 index 0000000..f972172 --- /dev/null +++ b/Src/Global_Variables.cpp @@ -0,0 +1,8 @@ +#include "Global_Variables.hpp" + +// 文件列表 +file_node *file_list_head = nullptr; +// 值列表 +value_node *value_list_head = nullptr; +// 起始时间戳 +double time_begin = 0.0; \ No newline at end of file diff --git a/SNOOPerToCSV.cpp b/Src/Main.cpp similarity index 68% rename from SNOOPerToCSV.cpp rename to Src/Main.cpp index 6a22df2..df7a031 100644 --- a/SNOOPerToCSV.cpp +++ b/Src/Main.cpp @@ -1,3 +1,6 @@ +#include "Tool_Functions.hpp" +#include "Global_Variables.hpp" + extern "C" { #include "stdio.h" @@ -7,117 +10,6 @@ extern "C" #include "ctype.h" } -// 行进到上一行起始位置 -size_t f_seek_pre_line_begin(FILE *file) -{ - int count = 0; - - // 本身就在文件起始位置 - if (ftell(file) == 0) - return 0; - // 本身在文件结尾 - if (fgetc(file) == EOF) - { - // 移动到之前 - do - { - fseek(file, -2, SEEK_CUR); - count--; - } while (ftell(file) != 0 && fgetc(file) != '\n'); - - return count; - } - - // 其它情况返 - - // 移动到上一行的结尾处 - while (ftell(file) != 0 && fgetc(file) != '\n') - { - fseek(file, -2, SEEK_CUR); - count--; - } - - fseek(file, -2, SEEK_CUR); - count--; - - // 移动到上上一行的结尾处 - while (ftell(file) != 0 && fgetc(file) != '\n') - { - fseek(file, -2, SEEK_CUR); - count--; - } - - return count; -} - -// 读取一行 -size_t f_getline(FILE *file, char *buffer, size_t buffer_len) -{ - memset(buffer, '\0', buffer_len); - int count = 0; - - while (true) - { - if (count >= buffer_len) - { - fseek(file, -count, SEEK_CUR); - memset(buffer, '\0', buffer_len); - return 0; - } - - char ch = fgetc(file); - - if (ch == EOF && count == 0) - return 0; - if (ch == '\n' || ch == EOF) - { - buffer[count] = ch; - return count + 1; - } - - buffer[count] = ch; - count++; - } -} - -// 16进制字符串转十进制数值(8字节) -uint64_t hex_to_decimal(const char *str) -{ - uint64_t value = 0; - - int len = strlen(str); - // 循环读取 - for (int count = 0; count < len; count++) - { - value *= 16; - if (str[count] >= '0' && str[count] <= '9') - value += str[count] - '0'; - else - value += toupper(str[count]) - 'A' + 10; - } - return value; -} - -// 文件链表节点 -typedef struct file_node_struct -{ - const char *file_name_str = nullptr; - file_node_struct *p_next = nullptr; -} file_node; - -// 数据列表 -typedef struct value_node_struct -{ - char value_name_str[100] = {'\0'}; - uint64_t raw_value = 0x0000000000000000; - value_node_struct *p_next; -} value_node; - -// 文件列表 -file_node *file_list_head = nullptr; -value_node *value_list_head = nullptr; -double time_begin = 0.0; - int main(int argc, char *argv[]) { // 处理指令输入 @@ -136,6 +28,11 @@ int main(int argc, char *argv[]) continue; } + // 处理格式串指令 + { + } + + // 其余输入作为文件输入 static file_node *target_node = nullptr; if (file_list_head == nullptr) { @@ -153,9 +50,11 @@ int main(int argc, char *argv[]) target_node->p_next = nullptr; } target_node->file_name_str = argv[count]; - printf("%s\n", argv[count]); + // printf("%s\n", argv[count]); } + printf("\n\n"); + // 遍历文件 file_node *target_file_node = file_list_head; while (target_file_node != nullptr) @@ -171,14 +70,28 @@ int main(int argc, char *argv[]) output_file = fopen(buffer, "wb"); } + if (input_file == nullptr || output_file == nullptr) + { + target_file_node = target_file_node->p_next; + continue; + } + + printf("Solving file: \"%s\"\n", target_file_node->file_name_str); + printf("----------------------------------------------------------------\n"); + printf("%-40s %-16s %s\n", "Value Name", "Out Type", "ID"); + printf("----------------------------------------------------------------\n"); + char segment_buffer[1000] = {'\0'}; + size_t total_line; + // 跳过非数据行 while (true) { f_getline(input_file, segment_buffer, sizeof(segment_buffer)); if (segment_buffer[0] == '-') { + sscanf(segment_buffer + 1, "%zu", &total_line); f_seek_pre_line_begin(input_file); break; } @@ -189,6 +102,7 @@ int main(int argc, char *argv[]) // 分配数值链表节点 value_list_head = (value_node *)malloc(sizeof(value_node)); value_list_head->p_next = nullptr; + value_list_head->value_type_str = DEFAULT_VALUE_TYPE; value_list_head->raw_value = 0x0000000000000000; memset(value_list_head->value_name_str, '\0', sizeof(value_list_head->value_name_str)); @@ -205,7 +119,7 @@ int main(int argc, char *argv[]) value_list_head->raw_value = hex_to_decimal(value_str); } - // 处理第一个数值循环 + // 处理第一个数值循环记录 { value_node *target_value_node = value_list_head; while (true) @@ -222,18 +136,28 @@ int main(int argc, char *argv[]) // 完成回环 if (!strcmp(value_name_str, value_list_head->value_name_str)) { - // 回转到文件的第二行 + // 回转到文件的数据行起始位置 memset(segment_buffer, '\0', sizeof(segment_buffer)); fseek(input_file, 0, SEEK_SET); - f_getline(input_file, segment_buffer, sizeof(segment_buffer)); + // 跳过非数据行 + while (true) + { + f_getline(input_file, segment_buffer, sizeof(segment_buffer)); + if (segment_buffer[0] == '-') + { + sscanf(segment_buffer + 1, "%zu", &total_line); + f_seek_pre_line_begin(input_file); + break; + } + } break; } - // 未完成回环,记录新的类型 - // 分配数值链表节点 + // 未完成回环,分配数值链表节点 target_value_node->p_next = (value_node *)malloc(sizeof(value_node)); target_value_node = target_value_node->p_next; target_value_node->p_next = nullptr; + target_value_node->value_type_str = DEFAULT_VALUE_TYPE; target_value_node->raw_value = 0x0000000000000000; memset(target_value_node->value_name_str, '\0', sizeof(target_value_node->value_name_str)); @@ -243,6 +167,18 @@ int main(int argc, char *argv[]) } } + // 展示数据类型输出 + { + value_node *target_value_node = value_list_head; + size_t value_count = 0; + + while (target_value_node != nullptr) + { + printf("%-40s %-16s [%d]\n", target_value_node->value_name_str, target_value_node->value_type_str, value_count++); + target_value_node = target_value_node->p_next; + } + } + // 输出csv抬头部分 { value_node *target_value_node = value_list_head; @@ -257,7 +193,10 @@ int main(int argc, char *argv[]) // 循环处理数据 { + printf("----------------------------------------------------------------\n"); + memset(segment_buffer, '\0', sizeof(segment_buffer)); + size_t line_count = -1; while (f_getline(input_file, segment_buffer, sizeof(segment_buffer)) != 0) { char value_name_str[100] = {'\0'}; @@ -279,7 +218,10 @@ int main(int argc, char *argv[]) timestamp += time; } - printf("timestamp: %lfs %s\n", timestamp, segment_buffer); + line_count++; + if ((line_count % 10000) == 0) + progress_print(line_count, total_line, true); + // printf("timestamp: %lfs %s\n", timestamp, segment_buffer); // 处理数值链表 value_node *target_value_node = value_list_head; @@ -290,8 +232,15 @@ int main(int argc, char *argv[]) if (!strcmp(value_name_str, target_value_node->value_name_str)) target_value_node->raw_value = hex_to_decimal(value_str); - // 输出当前值 - fprintf(output_file, ",%d", target_value_node->raw_value + 0); + // 特殊处理 + if (strstr(target_value_node->value_name_str, "wmrmeasured_speed")) + { + float *value = (float *)&(target_value_node->raw_value); + fprintf(output_file, ",%f", *value); + } + else + fprintf(output_file, ",%llu", target_value_node->raw_value); + target_value_node = target_value_node->p_next; } fprintf(output_file, "\n"); @@ -299,6 +248,13 @@ int main(int argc, char *argv[]) // 清理缓冲区 memset(segment_buffer, '\0', sizeof(segment_buffer)); } + + progress_print(line_count, total_line, true); + printf("\n\n\n"); + } + + // 清理数据列表 + { } target_file_node = target_file_node->p_next; diff --git a/Src/Tool_Functions.cpp b/Src/Tool_Functions.cpp new file mode 100644 index 0000000..50064c7 --- /dev/null +++ b/Src/Tool_Functions.cpp @@ -0,0 +1,141 @@ +#include "Tool_Functions.hpp" + +extern "C" +{ +#include "string.h" +#include "ctype.h" +} + +// 行进到上一行起始位置 +size_t f_seek_pre_line_begin(FILE *file) +{ + int count = 0; + + // 本身就在文件起始位置 + if (ftell(file) == 0) + return 0; + // 本身在文件结尾 + if (fgetc(file) == EOF) + { + // 移动到之前 + do + { + fseek(file, -2, SEEK_CUR); + count--; + } while (ftell(file) != 0 && fgetc(file) != '\n'); + + return count; + } + + // 其它情况 + + // 移动到上一行的结尾处(回到本行起始位置) + while (ftell(file) != 0 && fgetc(file) != '\n') + { + fseek(file, -2, SEEK_CUR); + count--; + } + + // 移动到上上一行的结尾处 + do + { + fseek(file, -2, SEEK_CUR); + count--; + } while (ftell(file) != 0 && fgetc(file) != '\n'); + + return count; +} + +// 读取文件一行 +size_t f_getline(FILE *file, char *buffer, const size_t buffer_len) +{ + if (buffer == nullptr || file == nullptr) + return 0; + + memset(buffer, '\0', buffer_len); + + size_t count = 0; + + // 循环读取 + while (true) + { + // 超长判定 + if (count + 1 == buffer_len) + return buffer_len; + + // 正常读取 + char ch = fgetc(file); + + // 仅文件结尾时 + if (ch == EOF && count == 0) + return 0; + + // 成功换行 + if (ch == '\n') + { + buffer[count] = '\n'; + return count + 1; + } + + // 没有换行但是遇到了文件结尾 + if (ch == EOF) + { + buffer[count] = '\n'; + return count; + } + + // 其它情况下正常复制 + buffer[count] = ch; + count++; + } +} + +// 进度条打印 +void progress_print(size_t completed, size_t total, bool reflush) +{ + + // 消除单行内容 + if (reflush) + putchar('\r'); + else + putchar('\n'); + + double p_percent = 1.0 * completed / total; + + putchar('['); + + // 输出完成部分填充 + size_t completed_count = (PROGRESS_LENGTH * p_percent) - 1; + if (p_percent - (int)(p_percent) > 0.5) + completed_count++; + + for (int count = completed_count; count > 0; count--) + putchar('='); + putchar('>'); + + // 填充未完成部分 + for (int count = PROGRESS_LENGTH - (completed_count + 1); count > 0; count--) + putchar(' '); + putchar(']'); + + // 进度数显 + printf(" %d/%d (%%%.2lf)", completed, total, p_percent * 100); +} + +// 16进制字符串转十进制数值(8字节) +uint64_t hex_to_decimal(const char *str) +{ + uint64_t value = 0; + + int len = strlen(str); + // 循环读取 + for (int count = 0; count < len; count++) + { + value *= 16; + if (str[count] >= '0' && str[count] <= '9') + value += str[count] - '0'; + else + value += toupper(str[count]) - 'A' + 10; + } + return value; +} \ No newline at end of file