Implement CSV export function
This commit is contained in:
parent
28728840a5
commit
87cc8637db
@ -16,6 +16,8 @@ namespace CSV_Type
|
|||||||
CSV_ERROR_COLUMN_NOT_FOUND, // 未查找到指定列
|
CSV_ERROR_COLUMN_NOT_FOUND, // 未查找到指定列
|
||||||
CSV_ERROR_ILLEGAL_COLUMN_POSITION, // 非法列位置
|
CSV_ERROR_ILLEGAL_COLUMN_POSITION, // 非法列位置
|
||||||
CSV_ERROR_ILLEGAL_CELL_POSITION, // 非法单元格位置
|
CSV_ERROR_ILLEGAL_CELL_POSITION, // 非法单元格位置
|
||||||
|
CSV_ERROR_FILE_CREATE_FAILED, // 文件创建失败
|
||||||
|
CSV_ERROR_FILE_WRITE_FAILED, // 文件写入失败
|
||||||
} CSV_Err;
|
} CSV_Err;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -23,8 +25,9 @@ namespace CSV_Type
|
|||||||
class CSV_Table
|
class CSV_Table
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
size_t mem_use; // 存储占用
|
size_t mem_use; // 存储占用
|
||||||
size_t column_count; // 列计数
|
size_t column_count; // 列计数
|
||||||
|
size_t max_element_depth; // 最大元素深度
|
||||||
|
|
||||||
struct Column_List_Node_Struct
|
struct Column_List_Node_Struct
|
||||||
{
|
{
|
||||||
@ -111,8 +114,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief 在指定标题的列中指定单元格后插入
|
* @brief 在指定标题的列中指定单元格后插入
|
||||||
* @param target_column_title_str 目标列标题
|
* @param target_column_title_str 目标列标题
|
||||||
* @param target_cell_position 目标列位置
|
* @param target_cell_position 目标单元格位置
|
||||||
* @param title_name_str 插入的列标题
|
* @param cell_content_str 单元格内容串
|
||||||
* @return CSV_Err 错误类型
|
* @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);
|
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 在指定标题的列中指定单元格后插入
|
* @brief 在指定标题的列中指定单元格后插入
|
||||||
* @param target_column_title_str 目标列标题
|
* @param target_column_title_str 目标列标题
|
||||||
* @param target_cell_position 目标列位置
|
* @param target_cell_position 目标单元格位置
|
||||||
* @param title_name_str 插入的列标题
|
* @param cell_content_str 单元格内容串
|
||||||
* @return CSV_Err 错误类型
|
* @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);
|
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
|
#endif
|
||||||
@ -11,6 +11,7 @@ CSV_Table::CSV_Table()
|
|||||||
{
|
{
|
||||||
this->column_count = 0;
|
this->column_count = 0;
|
||||||
this->mem_use = 0;
|
this->mem_use = 0;
|
||||||
|
this->max_element_depth = 0;
|
||||||
this->Column_List_End = this->Column_List_Head = nullptr;
|
this->Column_List_End = this->Column_List_Head = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ void CSV_Table::reset()
|
|||||||
{
|
{
|
||||||
// 清理尾指针
|
// 清理尾指针
|
||||||
this->Column_List_End = nullptr;
|
this->Column_List_End = nullptr;
|
||||||
|
this->max_element_depth = 0;
|
||||||
this->column_count = 0;
|
this->column_count = 0;
|
||||||
this->mem_use = 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++;
|
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;
|
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++;
|
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;
|
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;
|
||||||
|
}
|
||||||
@ -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 Head");
|
||||||
CSV.insert_column_before("Test column", "Test insert column before Origin");
|
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.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.insert_cell_after("Test column 3", (unsigned)0, "Insert Cell");
|
||||||
CSV.append_cell("Test column 3", "1");
|
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.append_cell("Test column 3", "3");
|
||||||
|
|
||||||
|
CSV.export_to_file("new.csv");
|
||||||
|
|
||||||
// 获取命令行
|
// 获取命令行
|
||||||
int argc;
|
int argc;
|
||||||
LPWSTR *argv;
|
LPWSTR *argv;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user