diff --git a/Inc/CSV_Utilities.hpp b/Inc/CSV_Utilities.hpp index 15fa1b6..6bbbe3d 100644 --- a/Inc/CSV_Utilities.hpp +++ b/Inc/CSV_Utilities.hpp @@ -16,6 +16,8 @@ namespace CSV_Type CSV_ERROR_COLUMN_NOT_FOUND, // 未查找到指定列 CSV_ERROR_ILLEGAL_COLUMN_POSITION, // 非法列位置 CSV_ERROR_ILLEGAL_CELL_POSITION, // 非法单元格位置 + CSV_ERROR_FILE_CREATE_FAILED, // 文件创建失败 + CSV_ERROR_FILE_WRITE_FAILED, // 文件写入失败 } CSV_Err; } @@ -23,8 +25,9 @@ namespace CSV_Type class CSV_Table { protected: - size_t mem_use; // 存储占用 - size_t column_count; // 列计数 + size_t mem_use; // 存储占用 + size_t column_count; // 列计数 + size_t max_element_depth; // 最大元素深度 struct Column_List_Node_Struct { @@ -111,8 +114,8 @@ public: /** * @brief 在指定标题的列中指定单元格后插入 * @param target_column_title_str 目标列标题 - * @param target_cell_position 目标列位置 - * @param title_name_str 插入的列标题 + * @param target_cell_position 目标单元格位置 + * @param cell_content_str 单元格内容串 * @return CSV_Err 错误类型 */ CSV_Type::CSV_Err insert_cell_after(const char *target_column_title_str, size_t target_cell_position, const char *cell_content_str); @@ -120,11 +123,36 @@ public: /** * @brief 在指定标题的列中指定单元格后插入 * @param target_column_title_str 目标列标题 - * @param target_cell_position 目标列位置 - * @param title_name_str 插入的列标题 + * @param target_cell_position 目标单元格位置 + * @param cell_content_str 单元格内容串 * @return CSV_Err 错误类型 */ CSV_Type::CSV_Err insert_cell_after(size_t target_column_position, size_t target_cell_position, const char *cell_content_str); + + /** + * @brief 在指定标题的列中指定单元格前插入 + * @param target_column_title_str 目标列标题 + * @param target_cell_position 目标单元格位置 + * @param cell_content_str 单元格内容串 + * @return CSV_Err 错误类型 + */ + CSV_Type::CSV_Err insert_cell_before(const char *target_column_title_str, size_t target_cell_position, const char *cell_content_str); + + /** + * @brief 在指定标题的列中指定单元格前插入 + * @param target_column_title_str 目标列标题 + * @param target_cell_position 目标单元格位置 + * @param cell_content_str 单元格内容串 + * @return CSV_Err 错误类型 + */ + CSV_Type::CSV_Err insert_cell_before(size_t target_column_position, size_t target_cell_position, const char *cell_content_str); + + /** + * @brief 导出到指定文件 + * @param file_name_str 目标文件名 + * @return CSV_Err 错误类型 + */ + CSV_Type::CSV_Err export_to_file(const char *file_name_str); }; #endif \ No newline at end of file diff --git a/Src/CSV_Utilities.cpp b/Src/CSV_Utilities.cpp index dd2905f..1c54586 100644 --- a/Src/CSV_Utilities.cpp +++ b/Src/CSV_Utilities.cpp @@ -11,6 +11,7 @@ CSV_Table::CSV_Table() { this->column_count = 0; this->mem_use = 0; + this->max_element_depth = 0; this->Column_List_End = this->Column_List_Head = nullptr; } @@ -23,6 +24,7 @@ void CSV_Table::reset() { // 清理尾指针 this->Column_List_End = nullptr; + this->max_element_depth = 0; this->column_count = 0; this->mem_use = 0; @@ -304,6 +306,10 @@ CSV_Type::CSV_Err CSV_Table::append_cell(size_t target_column_position, const ch } p_target_column->element_count++; + + if (p_target_column->element_count > this->max_element_depth) + this->max_element_depth = p_target_column->element_count; + return CSV_Type::CSV_ERROR_NONE; } @@ -372,5 +378,158 @@ CSV_Type::CSV_Err CSV_Table::insert_cell_after(size_t target_column_position, si } p_target_column->element_count++; + + if (p_target_column->element_count > this->max_element_depth) + this->max_element_depth = p_target_column->element_count; + return CSV_Type::CSV_ERROR_NONE; } + +CSV_Type::CSV_Err CSV_Table::insert_cell_before(const char *target_column_title_str, size_t target_cell_position, const char *cell_content_str) +{ + size_t count = 0; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + while (p_target_column != nullptr) + { + if (!strcmp(p_target_column->column_title_str, target_column_title_str)) + return this->insert_cell_before(count, target_cell_position, cell_content_str); + + p_target_column = p_target_column->p_next_column; + count++; + } + return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND; +} + +CSV_Type::CSV_Err CSV_Table::insert_cell_before(size_t target_column_position, size_t target_cell_position, const char *cell_content_str) +{ + if ((target_column_position + 1) > this->column_count) + return CSV_Type::CSV_ERROR_ILLEGAL_COLUMN_POSITION; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + for (size_t count = 0; count < target_column_position; count++) + p_target_column = p_target_column->p_next_column; + + if (!(((target_cell_position + 1) <= p_target_column->element_count) || ((target_cell_position == 0) && (p_target_column->element_count == 0)))) + return CSV_Type::CSV_ERROR_ILLEGAL_CELL_POSITION; + + decltype(p_target_column->Cell_List_Head) p_new_cell = (decltype(p_target_column->Cell_List_Head))malloc(sizeof(*(p_target_column->Cell_List_Head))); + if (p_new_cell == nullptr) + return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; + this->mem_use += sizeof(*p_new_cell); + + if (cell_content_str != nullptr) + { + char *p_content = (char *)malloc(strlen(cell_content_str) + 1); // +1 for '\0' + if (p_content == nullptr) + { + free(p_new_cell); + return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; + } + + this->mem_use += strlen(cell_content_str) + 1; + strcpy(p_content, cell_content_str); + p_new_cell->content_str = p_content; + } + else + p_new_cell->content_str = nullptr; + + if (p_target_column->element_count == 0) + { + p_new_cell->p_next_cell = nullptr; + p_target_column->Cell_List_Head = p_target_column->Cell_List_End = p_new_cell; + } + else + { + if (target_cell_position == 0) + { + p_new_cell->p_next_cell = p_target_column->Cell_List_Head; + p_target_column->Cell_List_Head = p_new_cell; + } + else + { + + decltype(p_new_cell) p_pre_target_cell = p_target_column->Cell_List_Head; + for (size_t count = 0; count < target_cell_position - 1; count++) + p_pre_target_cell = p_pre_target_cell->p_next_cell; + + p_new_cell->p_next_cell = p_pre_target_cell->p_next_cell; + p_pre_target_cell->p_next_cell = p_new_cell; + } + } + + p_target_column->element_count++; + + if (p_target_column->element_count > this->max_element_depth) + this->max_element_depth = p_target_column->element_count; + + return CSV_Type::CSV_ERROR_NONE; +} + +CSV_Type::CSV_Err CSV_Table::export_to_file(const char *file_name_str) +{ + // 打开文件 + FILE *p_file = fopen(file_name_str, "wb"); + if (p_file == nullptr) + return CSV_Type::CSV_ERROR_FILE_CREATE_FAILED; + + // 横向元素表 + decltype(this->Column_List_Head->Cell_List_Head) *p_parallel_cell_list = nullptr; + + // 输出内容 + if (this->column_count != 0) + { + p_parallel_cell_list = (decltype(this->Column_List_Head->Cell_List_Head) *)malloc(sizeof(*this->Column_List_Head->Cell_List_Head) * this->column_count); + if (p_parallel_cell_list == nullptr) + return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; + + // 输出标题及填充横向列表 + { + size_t count = 0; + for (decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; p_target_column != nullptr; p_target_column = p_target_column->p_next_column) + { + if (fprintf(p_file, "%s,", p_target_column->column_title_str) < 0) + goto file_write_error; + p_parallel_cell_list[count] = p_target_column->Cell_List_Head; + count++; + } + fseek(p_file, -1, SEEK_CUR); + if (fprintf(p_file, "\r\n") < 0) + goto file_write_error; + } + + // 输出横向行内容 + { + for (size_t row_count = 0; row_count < this->max_element_depth; row_count++) + { + for (size_t column_count = 0; column_count < this->column_count; column_count++) + { + if (p_parallel_cell_list[column_count] != nullptr) + { + if (fprintf(p_file, strstr(p_parallel_cell_list[column_count]->content_str, ",") ? "\"%s\"," : "%s,", p_parallel_cell_list[column_count]->content_str) < 0) + goto file_write_error; + p_parallel_cell_list[column_count] = p_parallel_cell_list[column_count]->p_next_cell; + } + else + { + if (fprintf(p_file, ",") < 0) + goto file_write_error; + } + } + fseek(p_file, -1, SEEK_CUR); + if (fprintf(p_file, "\r\n") < 0) + goto file_write_error; + } + } + + free(p_parallel_cell_list); + } + + fclose(p_file); + return CSV_Type::CSV_ERROR_NONE; + +// 写入错误处理 +file_write_error: + if (p_parallel_cell_list != nullptr) + free(p_parallel_cell_list); + fclose(p_file); + return CSV_Type::CSV_ERROR_FILE_WRITE_FAILED; +} \ No newline at end of file diff --git a/Src/Command_Solve.cpp b/Src/Command_Solve.cpp index 4916d72..4a64ccd 100644 --- a/Src/Command_Solve.cpp +++ b/Src/Command_Solve.cpp @@ -23,12 +23,16 @@ void Pre_Command_Solve(void) CSV.insert_column_before("Test column", "Test insert column before Head"); CSV.insert_column_before("Test column", "Test insert column before Origin"); + CSV.insert_cell_before("Test column 2", 0, "0"); CSV.append_cell("Test column 2", "1"); + CSV.insert_cell_before("Test column 2", 0, "Insert"); CSV.insert_cell_after("Test column 3", (unsigned)0, "Insert Cell"); CSV.append_cell("Test column 3", "1"); - CSV.append_cell("Test column 3", "2"); + CSV.append_cell("Test column 3", "MyWawwww,dwadawdawd"); CSV.append_cell("Test column 3", "3"); + CSV.export_to_file("new.csv"); + // 获取命令行 int argc; LPWSTR *argv;